{"id":13783768,"url":"https://github.com/fisxoj/json-schema","last_synced_at":"2026-01-30T23:17:48.419Z","repository":{"id":46984613,"uuid":"258844416","full_name":"fisxoj/json-schema","owner":"fisxoj","description":"JSON Schema validation","archived":false,"fork":false,"pushed_at":"2024-06-28T22:31:38.000Z","size":102,"stargazers_count":17,"open_issues_count":4,"forks_count":4,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-11T19:39:37.800Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Common Lisp","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-2.1","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fisxoj.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-04-25T18:20:50.000Z","updated_at":"2024-04-09T20:47:47.000Z","dependencies_parsed_at":"2024-11-17T20:35:42.141Z","dependency_job_id":"5f43fca4-2be0-44ad-b02a-10de79a4fac6","html_url":"https://github.com/fisxoj/json-schema","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/fisxoj/json-schema","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fisxoj%2Fjson-schema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fisxoj%2Fjson-schema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fisxoj%2Fjson-schema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fisxoj%2Fjson-schema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fisxoj","download_url":"https://codeload.github.com/fisxoj/json-schema/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fisxoj%2Fjson-schema/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28922650,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T22:32:35.345Z","status":"ssl_error","status_checked_at":"2026-01-30T22:32:31.927Z","response_time":66,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T19:00:30.371Z","updated_at":"2026-01-30T23:17:48.405Z","avatar_url":"https://github.com/fisxoj.png","language":"Common Lisp","readme":".. image:: https://travis-ci.org/fisxoj/json-schema.svg?branch=master\n   :target: https://travis-ci.org/fisxoj/json-schema\n   :alt: Travis CI status badge\n.. image:: https://coveralls.io/repos/github/fisxoj/json-schema/badge.svg?branch=master\n   :target: https://coveralls.io/github/fisxoj/json-schema?branch=master\n   :alt: Coveralls status badge\n.. image:: https://img.shields.io/badge/Contributor%20Covenant-v1.4%20adopted-ff69b4.svg\n   :alt: Contributor Covenant\n   :target: CODE_OF_CONDUCT.md\n\n\n:Source: `https://github.com/fisxoj/json-schema \u003chttps://github.com/fisxoj/json-schema\u003e`_\n:Docs:  `https://fisxoj.github.io/json-schema/ \u003chttps://fisxoj.github.io/json-schema/\u003e`_\n\njson-schema is a validator for drafts 4, 6, 7, and 2019-09 of the `JSON Schema \u003chttps://json-schema.org/\u003e`_ standard.  It is (mostly) compliant with the `common test suite \u003chttps://github.com/json-schema-org/JSON-Schema-Test-Suite\u003e`_.  The exceptions are\n\n**Draft 2019-09:**\n\n- ``unevaluatedItems`` and ``unevaluatedProperties`` are unimplemented\n\n**Drafts 4, 6, 7:**\n\n- ``$ref`` does not override any sibling keywords\n\n-------\nExample\n-------\n\nThe main entry point to the library is :function:`json-schema:validate`, which takes a schema to validate against, the data to validate against it and a draft version to use for interpreting the schema.  The default version is currently draft7.\n\n**Validating a simple type**\n\nPassing\n::\n\n   (json-schema:validate 3 :schema (json-schema.parse:parse \"{\\\"type\\\":\\\"integer\\\"}\"))\n   ;; =\u003e T\n   ;;    NIL\n\nFailing (note the error messages in the second argument)\n::\n\n   (json-schema:validate 13 :schema (json-schema.parse:parse \"{\\\"type\\\":\\\"integer\\\",\\\"maximum\\\":10}\"))\n   ;; =\u003e NIL\n   ;;    (\"13 must be less than or equal to 10\")\n\n\n**Validating an object**\n::\n\n   (setf schema (json-schema.parse:parse\n              \"{\\\"properties\\\":{\\\"foo\\\\nbar\\\":{\\\"type\\\":\\\"number\\\"},\\\"foo\\\\\\\"bar\\\":{\\\"type\\\":\\\"number\\\"},\\\"foo\\\\\\\\bar\\\":{\\\"type\\\":\\\"number\\\"},\\\"foo\\\\rbar\\\":{\\\"type\\\":\\\"number\\\"},\\\"foo\\\\tbar\\\":{\\\"type\\\":\\\"number\\\"},\\\"foo\\\\fbar\\\":{\\\"type\\\":\\\"number\\\"}}}\"))\n\nPassing\n::\n\n   (json-schema:validate\n     (json-schema.parse:parse\n       \"{\\\"foo\\\\nbar\\\":1,\\\"foo\\\\\\\"bar\\\":1,\\\"foo\\\\\\\\bar\\\":1,\\\"foo\\\\rbar\\\":1,\\\"foo\\\\tbar\\\":1,\\\"foo\\\\fbar\\\":1}\") :schema schema)\n   ;; =\u003e T\n   ;;    NIL\n\nFailing\n::\n\n   (json-schema:validate\n     (json-schema.parse:parse\n       \"{\\\"foo\\\\nbar\\\":\\\"1\\\",\\\"foo\\\\\\\"bar\\\":\\\"1\\\",\\\"foo\\\\\\\\bar\\\":\\\"1\\\",\\\"foo\\\\rbar\\\":\\\"1\\\",\\\"foo\\\\tbar\\\":\\\"1\\\",\\\"foo\\\\fbar\\\":\\\"1\\\"}\") :schema schema)\n   ;; =\u003e NIL\n   ;; (\"got errors validating properties\n   ;;\n   ;; Additionally:\n   ;; - Value 1 is not of type \\\"number\\\".\n   ;; - Value 1 is not of type \\\"number\\\".\n   ;; - Value 1 is not of type \\\"number\\\".\n   ;; - Value 1 is not of type \\\"number\\\".\n   ;; - Value 1 is not of type \\\"number\\\".\n   ;; - Value 1 is not of type \\\"number\\\".\n   ;; \")\n\n**Validating a document with a referenced schema**\n\nIf your data contains a top-level ``$schema`` key, you don't need to pass a schema along.  It will be fetched and validated against automatically.  This works with, for example, the `draft2019-09 meta-schema \u003chttps://json-schema.org/draft/2019-09/schema\u003e`_.\n\n-----------\nUsage Notes\n-----------\n\n~~~~~~~~\nContexts\n~~~~~~~~\n\nA context is a reusable set of state that contains all of the fetched network resources (if your schema references external resources) and resolved ids.  By storing that all, you can reuse the validation context multiple times without fetching/resolving everything again.\n::\n   (ql:quickload '(trivial-benchmark json-schema))\n\n   (defvar *schema* (json-schema.parse:parse #P\"~/Downloads/schema\"))\n\n   ;; schema is the json-schema meta schema document from:\n   ;; https://json-schema.org/specification-links.html#draft-2019-09-formerly-known-as-draft-8\n\n   (defvar *context*\n     (json-schema:make-context\n      *schema*\n      :draft2019-09))\n\n   ;;; Cached\n\n   (let ((data (json-schema.parse:parse \"{\\\"type\\\": \\\"string\\\"}\")))\n     (trivial-benchmark:with-timing (1000)\n       (json-schema:validate data\n                             :context *context*)))\n\n   ;; -                SAMPLES  TOTAL      MINIMUM  MAXIMUM   MEDIAN    AVERAGE    DEVIATION\n   ;; REAL-TIME        1000     0.826      0        0.022     0.001     0.000826   0.000797\n   ;; RUN-TIME         1000     0.826      0        0.022     0.001     0.000826   0.0008\n   ;; USER-RUN-TIME    1000     0.781011   0        0.020644  0.000745  0.000781   0.000665\n   ;; SYSTEM-RUN-TIME  1000     0.049933   0        0.000986  0         0.00005    0.000184\n   ;; PAGE-FAULTS      1000     0          0        0         0         0          0.0\n   ;; GC-RUN-TIME      1000     0.02       0        0.02      0         0.00002    0.000632\n   ;; BYTES-CONSED     1000     213753664  195344   228976    228032    213753.66  16221.591\n   ;; EVAL-CALLS       1000     0          0        0         0         0          0.0\n\n\n   ;;; Uncached\n\n   (let ((data (json-schema.parse:parse \"{\\\"type\\\": \\\"string\\\"}\")))\n     (trivial-benchmark:with-timing (1000)\n       (json-schema:validate data\n                             :schema *schema*\n                             :schema-version :draft2019-09)))\n\n   ;; -                SAMPLES  TOTAL      MINIMUM   MAXIMUM   MEDIAN    AVERAGE   DEVIATION\n   ;; REAL-TIME        1000     203.185    0.148     1.471     0.185     0.203185  0.112807\n   ;; RUN-TIME         1000     9.25       0.006     0.04      0.009     0.00925   0.002294\n   ;; USER-RUN-TIME    1000     8.145081   0.003368  0.039067  0.008105  0.008145  0.002317\n   ;; SYSTEM-RUN-TIME  1000     1.107377   0         0.004927  0.000994  0.001107  0.000967\n   ;; PAGE-FAULTS      1000     0          0         0         0         0         0.0\n   ;; GC-RUN-TIME      1000     0.08       0         0.03      0         0.00008   0.001464\n   ;; BYTES-CONSED     1000     719780512  707728    751424    718160    719780.5  11026.181\n   ;; EVAL-CALLS       1000     0          0         0         0         0         0.0\n\n\nSo, for this trivial example, the cached version is around a 245x speedup!  Note, though, that json-schema evaluates these things lazily, so not every reference is necessarily resolved when the context is created.  They are mutable, though, and will build up state as they go.\n\nThank you to `Raymond Wiker \u003chttps://github.com/rwiker\u003e`_ for contributing the initial implementation.\n\n~~~~~~~~~~~~~\nDecoding JSON\n~~~~~~~~~~~~~\n\njson-schema operates mostly on :class:`cl:hash-table` objects.  It requires them to have the ``:test`` argument set to :function:`cl:equal`, so that they work with string keys.  Further, it expects ``:true`` and ``:false`` as the boolean values and ``:null`` as the decoded Javascript ``null``.  Javascrpit arrays should be rendered as lists.  This behavior is provided behind the scenes by `st-json \u003chttps://marijnhaverbeke.nl/st-json/\u003e`_.  The :function:`json-schema.parse:parse` function provides this functionality over strings, streams, and pathnames for you.\n\n\n~~~~~~~~~~~~~~\nNetwork access\n~~~~~~~~~~~~~~\n\nJSON Schema allows schemas to reference other documents over the network.  This library will fetch them automatically, by default.  If you don't want this to be allowed, you should set :variable:`json-schema.reference:*resolve-remote-references*` to ``nil``.  If a schema references a remote one, it will raise a :class:`json-schema.reference:fetching-not-allowed-error` instead of fetching it when fetching references is disallowed.\n","funding_links":[],"categories":["Who Uses the Test Suite","Python ##","Online editors ##"],"sub_categories":["Common Lisp","Third-party APIs"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffisxoj%2Fjson-schema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffisxoj%2Fjson-schema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffisxoj%2Fjson-schema/lists"}