Skip to content
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

query: potential candidate for query format: jsonpath #2924

Closed
reschke opened this issue Oct 20, 2024 · 30 comments
Closed

query: potential candidate for query format: jsonpath #2924

reschke opened this issue Oct 20, 2024 · 30 comments

Comments

@reschke
Copy link
Contributor

reschke commented Oct 20, 2024

Spec: https://www.rfc-editor.org/rfc/rfc9535.html

  • how to augment the existing media type definition for QUERY (do we need to?)
  • what response format to use? (application/json)?
@timbray
Copy link
Contributor

timbray commented Oct 20, 2024

If I'm building an API around the new QUERY method, surely I'd have to specify the media types for both query and response, right? So I'm not sure what's special about JSONPath.

@reschke
Copy link
Contributor Author

reschke commented Oct 20, 2024

The theory is that for a media type to be applicable for QUERY the semantics for QUERY should be specified somewhere. That idea dates back to the time when people just used application/json as payload format for PATCH, with different ideas what that actually means.

But I agree that the semantics for JsonPath with QUERY are pretty clear, maybe except for the question what the JSON document being queried actually is. But that can remain an implementation detail of the server. Any recommendations about what format we should use in the response? Maybe you even could suggest an example?

@timbray
Copy link
Contributor

timbray commented Oct 20, 2024 via email

@reschke
Copy link
Contributor Author

reschke commented Oct 20, 2024

Ok, just checking: we don't want to define a standard response format, because we want to leave it specific to the server? I agree with that.

But for an example, would you recommend a specific response format (iff that this is just an example)?

@timbray
Copy link
Contributor

timbray commented Oct 20, 2024 via email

@mnot
Copy link
Member

mnot commented Oct 20, 2024

I think the difference here is that PATCH has side effects on the resource, whereas QUERY should not (generally). PATCH needed definition to describe those side effects, so it doesn't become another POST escape hatch.

@reschke
Copy link
Contributor Author

reschke commented Oct 21, 2024

Ok, so we'll just add an example using jsonpath.

@reschke
Copy link
Contributor Author

reschke commented Nov 1, 2024

Proposal:

QUERY /errata.json HTTP/1.1
Host: example.org
Content-Type: application/jsonpath
Accept: application/json

$..[?@doc-id=="RFC9110" && @errata_status_code!="Rejected"].[errata_id, submit_date]

from a fictious RFC errata database, selects all errata for RFC9110 which have not been rejected, and returns id, submission_date for each

HTTP/1.1 200 OK
Content-Type: application/json

[
  "7105",
  "2022-08-26",
  "7109",
  "2022-08-31",
  "7138",
  "2022-09-23",
  "7306",
  "2023-01-13",
  "7419",
  "2023-04-11"
]

@timbray
Copy link
Contributor

timbray commented Nov 1, 2024 via email

@reschke
Copy link
Contributor Author

reschke commented Nov 1, 2024

Oh, indeed. Thanks for catching this. Will edit in place.

@reschke
Copy link
Contributor Author

reschke commented Nov 3, 2024

We could also use this as example of conneg:

HTTP/1.1 200 OK
Content-Type: text/csv

errata_id, submit_date
7105, 2022-08-26
7109, 2022-08-31
7138, 2022-09-23
7306, 2023-01-13
7419, 2023-04-11

@mnot mnot added the editorial label Nov 17, 2024
@mnot
Copy link
Member

mnot commented Nov 17, 2024

Part of #1906

@cabo
Copy link

cabo commented Nov 20, 2024

I agree with using Accept: to specify the desired response format (we could even give application/json a specific meaning in this context); application/jsonpath is fine as a query content type.

@reschke
Copy link
Contributor Author

reschke commented Feb 19, 2025

@timbray @cabo - I need help with getting the syntax correct. What tool should I use? Is https://jsonpath.com/ ok? FWIW, the sample data is https://www.rfc-editor.org/errata.json

@reschke
Copy link
Contributor Author

reschke commented Feb 19, 2025

-> #1906

@cabo
Copy link

cabo commented Feb 19, 2025

@timbray @cabo - I need help with getting the syntax correct. What tool should I use? Is https://jsonpath.com/ ok? FWIW, the sample data is https://www.rfc-editor.org/errata.json

I use a simple tool called jpt (gem install jpt). @glyn probably has more recommendations...
(See also his blog article https://underlap.org/jsonpath-rfc-nearing-publication .)

@reschke
Copy link
Contributor Author

reschke commented Feb 20, 2025

jpt seems to use the same parser as https://jsonpath.com/...

I should have been more precise on what problems I encountered:

Escaping "-" in names. The query

$..[[email protected]=='RFC4954']

results in parse error:

Expected one of [A-Z], [a-z], "_", [�-퟿], [-�], [0-9], " ", "\t", "\n", "\r", "[", ".", "==", "!=", "<=", ">=", "<", ">", "..", "&&", "||", ",", "]" at line 1, column 11 (byte 11):

The other question was how to specify multiple members for output; in the original example I had:

$..[?@doc-id=="RFC9110" && @errata_status_code!="Rejected"].[errata_id, submit_date]

Is this even possible in regular JSONPath?

@martinthomson
Copy link
Contributor

Here's what I found works if I altered their example: $["doc-id"] or $["doc\u002did"]

That is, if you want "-", you have to not use the .<label> syntax, but instead ["<label>"], using JSON-style quoting in that string.

@cabo
Copy link

cabo commented Feb 20, 2025

jpt seems to use the same parser as https://jsonpath.com/...

I should have been more precise on what problems I encountered:

Escaping "-" in names. The query

$..[[email protected]=='RFC4954']

@["doc-id"] is a way to include other characters in a name.

The other question was how to specify multiple members for output; in the original example I had:

$..[?@doc-id=="RFC9110" && @errata_status_code!="Rejected"].[errata_id, submit_date]

Is this even possible in regular JSONPath?

We didn't include projection (the SELECT... part of SQL) in JSONPath.
You get pointers into an instance, or the values at these points.
No construction of new values.

@reschke
Copy link
Contributor Author

reschke commented Feb 20, 2025

I now have

Do you have a good idea how to produce JSONPath results for the response body? Is there a notation I could use? A list of normalized paths perhaps?

@cabo
Copy link

cabo commented Feb 20, 2025

JSONPath does not specify an output format, just saying that this could be a list of normalized paths and/or the values at these paths. The reply at line 896 looks good to me as an example for representing the latter list as a JSON array.

Please do fix line 884 ["doc\u002did"]; I have no idea what made Martin escape the hyphen-minus, which is perfectly valid ASCII at this point.
Also, the line breaking and indentation of the query is quite weird.

@reschke
Copy link
Contributor Author

reschke commented Feb 21, 2025

Please try. "doc-id" is not accepted by the parser: #2924 (comment)

For the query, I wanted to indent it in order to avoid overflowing the rfc txt limits. If you can suggest a better variant, please go ahead.

@cabo
Copy link

cabo commented Feb 21, 2025

   name-segment        = ("[" name-selector "]") /
                         ("." member-name-shorthand)
   member-name-shorthand = name-first *name-char
   name-selector       = string-literal
   string-literal      = %x22 *double-quoted %x22 /     ; "string"
                         %x27 *single-quoted %x27       ; 'string'

hyphen-minus is not a name-char, so a member-name-shorthand like

@.doc-id

is a syntax error, as is

@.doc\u002did

Instead,

@["doc-id"]

or

@['doc-id']

is the correct way to use this member name in a name-segment.
The string-literals inside a name-selector also allow escapes like \u002d, but there is no point for hyphen-minus.

@reschke
Copy link
Contributor Author

reschke commented Feb 21, 2025

That's why I was so confused. Let me try again.

Indeed:

$..[[email protected]_status_code=="Rejected" && @["doc-id"]=="RFC9110"]

does work. I believe I tried

$..[[email protected]_status_code=="Rejected" && @.["doc-id"]=="RFC9110"]

Sorry for the confusion

@glyn
Copy link

glyn commented Feb 24, 2025

@timbray @cabo - I need help with getting the syntax correct. What tool should I use? Is https://jsonpath.com/ ok? FWIW, the sample data is https://www.rfc-editor.org/errata.json

I use a simple tool called jpt (gem install jpt). @glyn probably has more recommendations... (See also his blog article https://underlap.org/jsonpath-rfc-nearing-publication .)

Sorry for the slow reply. Here are two "live" implementations of RFC 9535 which you may already have gotten from my blog post:

@reschke
Copy link
Contributor Author

reschke commented Feb 24, 2025

See #3002

@reschke reschke closed this as completed Feb 24, 2025
@reschke
Copy link
Contributor Author

reschke commented Feb 24, 2025

@glyn - thanks; I just merged the new examples section. Maybe you want to check?

@glyn
Copy link

glyn commented Feb 25, 2025

@reschke:

@glyn - thanks; I just merged the new examples section. Maybe you want to check?

I skimmed through #3002, but wasn't really sure what which JSONPath query expressions you wanted me to check. If you can drop them here, I'll take a look.

@reschke
Copy link
Contributor Author

reschke commented Feb 25, 2025

@glyn
Copy link

glyn commented Feb 26, 2025

$..[
     [email protected]_status_code=="Rejected"
     && @.submit_date>"2024"
   ]
   ["doc-id"]

Confirmed that this is valid JSONPath syntax.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

6 participants