-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[JsonPath] Add the component #59655
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[JsonPath] Add the component #59655
Conversation
e7e8192
to
32623b5
Compare
src/Symfony/Component/JsonCrawler/Exception/InvalidJsonException.php
Outdated
Show resolved
Hide resolved
32623b5
to
95e2a6a
Compare
Not to forget |
19f1073
to
5669a25
Compare
Add the raw |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool!
Absolutely! That's the first thing I thought of. |
5669a25
to
b32574b
Compare
Why "JsonCrawler" and not "JsonPath"? |
src/Symfony/Component/JsonCrawler/Tokenizer/JsonPathTokenizer.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/JsonCrawler/Tokenizer/JsonPathTokenizer.php
Outdated
Show resolved
Hide resolved
Had the same thought earlier today, happy to see I'm not the only one! Let's see if anybody's against this naming. Otherwise, let's call it JsonPath, makes more sense to me as well. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I also think that JsonPath would be more appropriate as this is a well-known name of the spec that is implemented.
But maybe it should be part of the PropertyAccess? component. Why restrict this rich syntax to JSON documents when you can browse a tree of PHP objects in the same way. It would give more power to the PropertyAccess component.
@GromNaN I think that's a good question. Here's why I'm not 100% sure that would be a fit.
Given the complexity of PropertyAccess (the logic to know if a property is writable/readable, get the value, read it, etc. is far from being trivial), I'm afraid it would bring a lot more complexity to JsonPath. The few times I fixed something in PropertyAccess was a whole challenge by itself just to understand all supported cases. JsonPath only deals with always-readable scalar values in arrays, which makes things way more simple. However, what would be possible is to create something like a converter in a second time, to convert a JsonPath to a PropertyPath. PropertyAccess could then have an opt-in possibility to be used together with JsonPath.
Definitely, but wouldn't it be too much power actually? PropertyAccess is, again, very complex and supports a lot of cases. But let's put implementation complexity aside. In my opinion, it would be very confusing for developers to have, in the same component, two different syntaxes that look alike, but doesn't have the same possibilities at all. For newcomers, it could be really puzzling. Finally, if external packages (like testing frameworks and the ones I mentioned in the description) would like to support JsonPath, I'm not sure we should force to install the whole PropertyAccess component with it. But I still think that having an opt-in dependency to JsonPath in PropertyAccess, to convert from one syntax to another, is something that may be investigated! |
1d6f001
to
ce60d57
Compare
src/Symfony/Component/JsonCrawler/Exception/JsonCrawlerException.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/JsonCrawler/Exception/InvalidJsonPathException.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/JsonCrawler/Exception/InvalidInputJsonException.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/JsonPath/Exception/InvalidInputJsonException.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/JsonPath/Exception/InvalidJsonPathException.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/JsonPath/Exception/JsonCrawlerException.php
Outdated
Show resolved
Hide resolved
@alexandre-daubois You can rebase this one to use the new |
08d7429
to
9e3b2ec
Compare
Updated with JsonStreamer, thank you! |
9e3b2ec
to
fc000fb
Compare
src/Symfony/Component/JsonPath/Exception/InvalidInputJsonException.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/JsonPath/Exception/InvalidInputJsonException.php
Outdated
Show resolved
Hide resolved
src/Symfony/Component/JsonPath/Exception/InvalidInputJsonException.php
Outdated
Show resolved
Hide resolved
fc000fb
to
dc999a3
Compare
dc999a3
to
277bea6
Compare
Rebased on 7.3. Status: Needs Review |
6dca608
to
1c96e3e
Compare
1c96e3e
to
f34f4c4
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking loud about the scope and the name of the component: would it be the place to support navigating hypermedia APIs?
It deserves further investigation about the scope indeed, but we could imagine a |
Thank you @alexandre-daubois. |
…(alexandre-daubois) This PR was merged into the 7.3 branch. Discussion ---------- [JsonPath] Fix error message when evaluating a resource | Q | A | ------------- | --- | Branch? | 7.3 | Bug fix? | no | New feature? | no | Deprecations? | no | Issues | - | License | MIT After #59655 (comment) Commits ------- e5cc3d4 [JsonPath] Fix error message when evaluating a resource
JsonPath component
Today I'm presenting the JsonPath component. Thanks to this component, it will be possible to query JSON strings using the JSON Path syntax, as described in the recent RFC 9535. This RFC was released in February 2024 and is published here: https://datatracker.ietf.org/doc/html/rfc9535.
Here's a preview of what's possible:
As stated in RFC 9535, this component embeds a few read-to-use functions:
length
count
value
search
match
Integration of JsonStreamer for performance
Thanks to the powerfulness of JsonStreamer's Splitter, we're able to guess which part of the JSON needs and doesn't need to be decoded. Querying a whole node means we can only
json_decode()
the substring containing the node. The same goes when encountering array keys. We extract the relevant substring thanks to Splitter that provides an API for that. It brings support for JSON-as-resource evaluation.We stop when we encounter an operation that implies filtering as we need to decode the whole node to filter children.
What about other packages?
A few alternatives exist, however they were not updated in the last few years. If they are up-to-date, they do not seem to be following RFC 9535, but rather a partial implementation of https://goessner.net/articles/JsonPath/.
Why not include it in DomCrawler or PropertyAccess?
That was my first thought, however DomCrawler and JsonPath actually share absolutely no logic and their purpose is really different. As they have not much in common, that would be no ideal to tie them up.
PropertyAccess could be another possibility, here's where I explained why I think this would not be a correct fit: #59655 (comment).
Does it need external dependencies?
No! This component is written in vanilla PHP and doesn't require any third-party package to work.
How will it be leveraged in Symfony/PHP?
So many possibilities 😉 The first I can think of is leveraging this component in integration tests.
Indeed, this would allow to easily validate and write new assert methods when writing integration tests with Symfony. Validating JSON returned by an API thanks to this notation would be way easier (and more readable). In short, HttpClient, BrowserKit and
WebTestCase
could beneficiate from this (especiallyBrowserKitAssertionsTrait
where asserts on Json could be added!).Symfony would not be the only beneficiary: we can easily imagine that libraries like Behat (or PHPUnit, why not) could use this package to implement asserts on JSON.
Apart from testing frameworks, this package can also be used to quickly extract precise data from a JSON. So, possibilities here are also endless.
Possible evolution