[RFC] JSON Schema validation support

php.internals

Jakub Zelenka

1 year ago
Hello, I would like introduce and open discussion for RFC proposing the addition of JSON Schema validation support to JSON extension: https://wiki.php.net/rfc/json_schema_validation If this is successful, it should be just the first for further improvements (see the future scope). Kind regards, Jakub

Удальцов Валентин

1 year ago
On Sta, 5 July 2025 at 00:04, Jakub Zelenka <bukka@php.net> wrote:
> Hello, > > I would like introduce and open discussion for RFC proposing the addition > of JSON Schema validation support to JSON extension: > > https://wiki.php.net/rfc/json_schema_validation > > If this is successful, it should be just the first for further > improvements (see the future scope). > > Kind regards, > > Jakub >
Hi, Jakub! I like the idea. I have a couple of initial thoughts: 1. Wouldn't it make sense to place all the new classes under the `Json` namespace, similar to how it’s done in `ext-random`? 2. If there’s no way to interact with the `JsonSchema` class, what purpose does it serve? Wouldn’t it be simpler to just extend `json_decode()` with an optional `?string $schema = null` parameter?
-- Kind regards, Valentin

Jakub Zelenka

1 year ago
Hi, On Fri, Jul 4, 2025 at 11:49 PM Valentin Udaltsov < udaltsov.valentin@gmail.com> wrote:
> On Sta, 5 July 2025 at 00:04, Jakub Zelenka <bukka@php.net> wrote: > >> Hello, >> >> I would like introduce and open discussion for RFC proposing the addition >> of JSON Schema validation support to JSON extension: >> >> https://wiki.php.net/rfc/json_schema_validation >> >> If this is successful, it should be just the first for further >> improvements (see the future scope). >> >> Kind regards, >> >> Jakub >> > > Hi, Jakub! > > I like the idea. I have a couple of initial thoughts: > > 1. Wouldn't it make sense to place all the new classes under the `Json` > namespace, similar to how it’s done in `ext-random`? >
This would be widely inconsistent with the current interface / exception class in the extension. The ext-random was a new extension so it's a completely different case. I think it makes much more sense to keep the extension consistent than introducing new interface.
> 2. If there’s no way to interact with the `JsonSchema` class, what purpose > does it serve? Wouldn’t it be simpler to just extend `json_decode()` with > an optional `?string $schema = null` parameter? >
There are couple of reasons for this: - It allows re-using the same parsed schema without a need to parse it multiple times for each decoding / validation - the class internally holds parsed representation of the schema. - We might want to introduce additional flags that will impact the parsing (e.g. default version) - It might allow a way to better cache schema between requests so it could further improve performance in the future - It will allow the possibility to get schema from other sources than string - e.g. from PHP array or even automatic creation from the class (that's why the JsonSchema is created using static method and not using constructor). This might be especially useful for object mapping. Kind regards, Jakub

Ben Ramsey

1 year ago
> On Jul 4, 2025, at 16:01, Jakub Zelenka <bukka@php.net> wrote: > > Hello, > > I would like introduce and open discussion for RFC proposing the addition of JSON Schema validation support to JSON extension: > > https://wiki.php.net/rfc/json_schema_validation > > If this is successful, it should be just the first for further improvements (see the future scope). > > Kind regards, > > Jakub
There are 9 versions of JSON Schema and 11 Internet-Drafts, all of which have expired. Many of these versions are still widely used in the wild (draft-04, draft-05, and draft-06 come to mind as heavily used, despite several newer versions). Which version do you plan to target with this RFC, or will it be able to parse all versions, depending on what the input has specified in the `$schema` properties? I’ve even seen multiple schema versions used within the same set of referenced documents, and as long as the parser knows how to handle all versions, it will parse things just fine. For the reference of others on the list, here’s what I mean by 9 versions and 11 I-Ds: * Version: 2020-12 - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-01 - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00 * Version: 2019-09 - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02 * Version: draft-07 - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01 - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-00 * Version: draft-06 - https://datatracker.ietf.org/doc/html/draft-wright-json-schema-01 * Version: draft-05 - https://datatracker.ietf.org/doc/html/draft-wright-json-schema-00 * Version: draft-04 - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04 * Version: draft-03 - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-03 * Version: draft-02 - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-02 * Version: draft-01 - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-01 Typically, when you create a JSON Schema document, you specify the `$schema` property, the value of which is a URI that refers to the schema version you’re using, like this: ``` { "$schema": "https://json-schema.org/draft/2020-12/schema" } ``` This lets the parser know what “flavor” of JSON Schema you’re using. The problem is that many parsers don’t understand all schema versions, and the most popular one in PHP (justinrainbow/json-schema <https://packagist.org/packages/justinrainbow/json-schema>) only supports draft-03 and draft-04, both well over 12 years old, at this point. Perhaps the JSON Schema library that is most robust and supports the latest versions is the opis/json-schema package <https://opis.io/json-schema/2.x/>. It supports draft-06, draft-07, 2019-09, and 2020-12, which is pretty much all the newer ones that justinrainbow/json-schema doesn’t support. I think your RFC needs to address all these versions and how you plan to address compatibility issues between them all. Since all the I-Ds have expired without a formal IETF RFC being voted on and passing, you should probably call attention to the fact that JSON Schema, while not moving much right now, is still a moving target and any new versions will require updates to the core to support them. Cheers, Ben

Ben Ramsey

1 year ago
> On Jul 4, 2025, at 18:07, Ben Ramsey <ramsey@php.net> wrote: > >> On Jul 4, 2025, at 16:01, Jakub Zelenka <bukka@php.net> wrote: >> >> Hello, >> >> I would like introduce and open discussion for RFC proposing the addition of JSON Schema validation support to JSON extension: >> >> https://wiki.php.net/rfc/json_schema_validation >> >> If this is successful, it should be just the first for further improvements (see the future scope). >> >> Kind regards, >> >> Jakub > > > There are 9 versions of JSON Schema and 11 Internet-Drafts, all of which have expired. Many of these versions are still widely used in the wild (draft-04, draft-05, and draft-06 come to mind as heavily used, despite several newer versions). > > Which version do you plan to target with this RFC, or will it be able to parse all versions, depending on what the input has specified in the `$schema` properties? I’ve even seen multiple schema versions used within the same set of referenced documents, and as long as the parser knows how to handle all versions, it will parse things just fine. > > For the reference of others on the list, here’s what I mean by 9 versions and 11 I-Ds: > > * Version: 2020-12 > - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-01 > - https://datatracker.ietf.org/doc/html/draft-bhutton-json-schema-00 > > * Version: 2019-09 > - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-02 > > * Version: draft-07 > - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-01 > - https://datatracker.ietf.org/doc/html/draft-handrews-json-schema-00 > > * Version: draft-06 > - https://datatracker.ietf.org/doc/html/draft-wright-json-schema-01 > > * Version: draft-05 > - https://datatracker.ietf.org/doc/html/draft-wright-json-schema-00 > > * Version: draft-04 > - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-04 > > * Version: draft-03 > - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-03 > > * Version: draft-02 > - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-02 > > * Version: draft-01 > - https://datatracker.ietf.org/doc/html/draft-zyp-json-schema-01 > > Typically, when you create a JSON Schema document, you specify the `$schema` property, the value of which is a URI that refers to the schema version you’re using, like this: > > ``` > { > "$schema": "https://json-schema.org/draft/2020-12/schema" > } > ``` > > This lets the parser know what “flavor” of JSON Schema you’re using. The problem is that many parsers don’t understand all schema versions, and the most popular one in PHP (justinrainbow/json-schema <https://packagist.org/packages/justinrainbow/json-schema>) only supports draft-03 and draft-04, both well over 12 years old, at this point. > > Perhaps the JSON Schema library that is most robust and supports the latest versions is the opis/json-schema package <https://opis.io/json-schema/2.x/>. It supports draft-06, draft-07, 2019-09, and 2020-12, which is pretty much all the newer ones that justinrainbow/json-schema doesn’t support. > > I think your RFC needs to address all these versions and how you plan to address compatibility issues between them all. > > Since all the I-Ds have expired without a formal IETF RFC being voted on and passing, you should probably call attention to the fact that JSON Schema, while not moving much right now, is still a moving target and any new versions will require updates to the core to support them. > > Cheers, > Ben
Another thing that needs to be addressed in the RFC is how error reporting will work. I see this hinted at under Future Scope, but one of the benefits of the existing JSON Schema Composer packages is the robust level of error reporting they provide. I think robust error reporting is base-level functionality and non-optional for a minimum viable feature. I won’t have a reason to use the built-in JSON Schema functionality until it has a certain level of error reporting that goes well beyond simple `JSON_ERROR_SCHEMA_*` error codes. I see that the JSO C library supports JSON Schema validation for draft-04 and draft-06. IMO, you will need at least 2020-12 support, since this is the version that OpenAPI 3 has adopted, and any tooling for it will require support for parsing 2020-12 schemas. Cheers, Ben

Jakub Zelenka

1 year ago
On Sat, Jul 5, 2025 at 1:29 AM Ben Ramsey <ramsey@php.net> wrote:
> Another thing that needs to be addressed in the RFC is how error reporting > will work. I see this hinted at under Future Scope, but one of the benefits > of the existing JSON Schema Composer packages is the robust level of error > reporting they provide. > >
The error reporting is done using normal error codes and exceptions get some sort of identification message. It doesn't collect multiple errors with exact pointers to the place in the same way as the current JSON parser doesn't do that - this is just how things are in the JSON extension and this doesn't try to address all problems in one go - it basically needs some extra parser context for this which is not there yet.
> I think robust error reporting is base-level functionality and > non-optional for a minimum viable feature. I won’t have a reason to use the > built-in JSON Schema functionality until it has a certain level of error > reporting that goes well beyond simple `JSON_ERROR_SCHEMA_*` error codes. > >
Well you don't have to use it from the start. The reason for introduction in this form is to mainly get something that we can build on. It is also important to know that it makes sense to spend more time on it. It already required lots of time to implement. If we used the same standard on the json parser, we would never have json extension in PHP because the error reporting does not provide complete info.
> I see that the JSO C library supports JSON Schema validation for draft-04 > and draft-06. IMO, you will need at least 2020-12 support, since this is > the version that OpenAPI 3 has adopted, and any tooling for it will require > support for parsing 2020-12 schemas. >
None of the implementations started with support for all drafts from the start. We will eventually support all but I don't see why that would have to be done from the beginning. Kind regards, Jakub

Jakub Zelenka

1 year ago
On Sat, Jul 5, 2025 at 1:41 AM Jakub Zelenka <bukka@php.net> wrote:
> On Sat, Jul 5, 2025 at 1:29 AM Ben Ramsey <ramsey@php.net> wrote: > >> Another thing that needs to be addressed in the RFC is how error >> reporting will work. I see this hinted at under Future Scope, but one of >> the benefits of the existing JSON Schema Composer packages is the robust >> level of error reporting they provide. >> >> > The error reporting is done using normal error codes and exceptions get > some sort of identification message. >
I should probably show some example how this looks like. See this test https://github.com/bukka/php-jsond/blob/1f640becf3cd0f0cca9c72fa5045c7ccefc26d7f/tests/jsond_decode_schema_002.phpt Kind regards, Jakub

Jakub Zelenka

1 year ago
Hi On Sat, Jul 5, 2025 at 1:10 AM Ben Ramsey <ramsey@php.net> wrote:
> There are 9 versions of JSON Schema and 11 Internet-Drafts, all of which > have expired. Many of these versions are still widely used in the wild > (draft-04, draft-05, and draft-06 come to mind as heavily used, despite > several newer versions). > > Which version do you plan to target with this RFC, or will it be able to > parse all versions, depending on what the input has specified in the > `$schema` properties? >
This is noted in the implementation section:
> The current status is almost complete draft 4 and 6 support. Draft 7
support is coming soon. By almost I mean that it needs to implement dependencies (which I plan to sort out before this goes to vote) and it didn't go through complete regression pack which should happen before the first RC. Draft 7 is pretty much just "if" so it should be supported as well as it's pretty similar to dependencies. I will see about other drafts if they could make it to 8.5 but the plan to support eventually all. I will make it a bit clearer in the RFC. Technically this is more library implementation thing but as it's bundled it should be properly noted in the RFC as well.
> > I think your RFC needs to address all these versions and how you plan to > address compatibility issues between them all. > >
All drafts except 4 require $schema to be there so it's the way how to currently select the version. The future scope actually lists the default draft for schemas without $schema so it could be selected by users. We could maybe look into some auto-identification in the future but again it would be the future scope. I will add some note about it to the RFC. Since all the I-Ds have expired without a formal IETF RFC being voted on
> and passing, you should probably call attention to the fact that JSON > Schema, while not moving much right now, is still a moving target and any > new versions will require updates to the core to support them. >
Yeah good point I should mention that new version will be treated as features. Cheers Jakub

Jakub Zelenka

1 year ago
On Fri, Jul 4, 2025 at 11:01 PM Jakub Zelenka <bukka@php.net> wrote:
> Hello, > > I would like introduce and open discussion for RFC proposing the addition > of JSON Schema validation support to JSON extension: > > https://wiki.php.net/rfc/json_schema_validation > > If this is successful, it should be just the first for further > improvements (see the future scope). >
I have done some updates to the RFC and I decided to target 8.6 as there is not enough time to get to the state where I would be fully confident that all edge cases are handled and it cannot crash. Basically I need to also integrate full regression pack into it to be sure that all is good. As it was also pointed out, having just few drafts supported could be quite disappointing for users so the plan is to support all the latest drafts as well from the beginning. This is more an implementation detail though so I plan to open vote some time soon (after the feature freeze) to make sure that the API is acceptable and I can just concentrate on getting the implementation done. Kind regards, Jakub

Alexandre Daubois

1 year ago
Hi Jakub Le mer. 23 juil. 2025 à 15:33, Jakub Zelenka <bukka@php.net> a écrit :
> > Hello, > > I would like introduce and open discussion for RFC proposing the addition of JSON Schema validation support to JSON extension: > > https://wiki.php.net/rfc/json_schema_validation > > If this is successful, it should be just the first for further improvements (see the future scope). > > Kind regards, > > Jakub
Thank you for proposing such a feature! I personally really like it and would be glad to see this land into PHP. I think it would be even more useful if JsonSchema offers more ways to load a schema. Schemas are often either remotely stored or stored in a file. It would be great to add two new factory methods: JsonSchema::fromUri() and JsonSchema::fromFile(). Maybe JsonSchema::createFromString() should also be renamed to fromString() to be consistent with the recent additions to XMLReader. Best, Alex