Remix.run Logo
brookst 7 hours ago

Wouldn’t just putting an etag on POST requests accomplish the same thing? If I’m understanding it the server has to maintain state to ensure idempotency.

CodesInChaos 7 hours ago | parent | next [-]

QUERY is GET with a request body. So it must be safe, not just idempotent. Where safe means it has no significant side-effects. Typically servers will not keep any state for QUERY requests.

There is one interesting variant though, which uses state: The client sends a QUERY containing the full query, and the server returns a url usable with GET with which this query can be triggered in the future. Similar to prepared statements in SQL databases.

Using QUERY for GraphQL queries (not mutations) would be a good match. These only read data, but are sometimes bigger than the url length limit.

brookst 6 hours ago | parent | next [-]

Thanks for the explanation!

I still don’t get how idempotency can typically be ensured without state. It very much depends on data model and application design. Even side effects like using a user’s lookup quota need to be handled at a higher layer than HTTP (I think?).

wongarsu 5 hours ago | parent | next [-]

Imagine a forum where comment ids are client-generated UUIDs, and comments are inserted with "ON CONFLICT IGNORE". Submitting the same comment twice would simply be a noop

But what the Query method really targets are things like a graphql query that can be multiple kb for a single query, but only reads data. Sure, it might count against rate limits, trigger logs, etc. But at a conceptual level resubmitting the same query should give the same result (if the data didn't change). And since you are only reading data, resubmitting is safe

inigyou 4 hours ago | parent | prev | next [-]

Yes it varies. Using the QUERY method doesn't automatically mean your app is idempotent - it means the browser, and any intermediaries, can assume it's idempotent. So when you go forward and then back they're free to reissue the request and you won't get the "this may repeat whatever you just did" popup.

If it's not actually idempotent but you're telling the browser it is, of course you may cause bugs. Same as GET.

CodesInChaos 3 hours ago | parent [-]

I think PUT, which is idempotent, would still require the "repeat action" warning, since it will overwrite any changes that happened to the same resource in the mean time (unless used with `if-match` or similar). QUERY won't require such warnings because it's safe, not just idempotent.

Joker_vD 6 hours ago | parent | prev | next [-]

> I still don’t get how idempotency can typically be ensured without state.

Well, how is "GET /index.html HTTP/1.1" made idempotent in practice without (additional) state?

CodesInChaos 6 hours ago | parent | prev [-]

Minor side-effects like quotas or request logging are generally ignored when considering the semantics of http methods. I don't see any complications for QUERY that don't already apply to GET. It just allows you to bypass the url length limit by putting the data in the body instead of the url itself.

uberex 4 hours ago | parent [-]

Exactly. "GET / is idempotent" ... "But I just launched a DDOS against / and now it returns 502...

trollbridge 7 hours ago | parent | prev | next [-]

Ideally, libraries like FastAPI, etc. could be configured to translate QUERYs to GETs, until you can rewrite your code to automatically support both.

5 hours ago | parent | prev | next [-]
[deleted]
n_e 6 hours ago | parent | prev [-]

Interestingly, despite the QUERY request being safe, the RFC says it's subject to preflight requests:

> A QUERY request from user agents implementing Cross-Origin Resource Sharing (CORS) will require a "preflight" request, as QUERY does not belong to the set of CORS-safelisted methods (see [FETCH]).

CodesInChaos 6 hours ago | parent [-]

That paragraph merely describes how existing browsers behave, it doesn't specify how future browsers must behave. After all, a HTTP RFC isn't really the right place to specify browser specific behavior like CORS, that belongs in a W3C/WHATWG specification.

6 hours ago | parent | prev | next [-]
[deleted]
Joker_vD 6 hours ago | parent | prev [-]

    Unlike POST, however, the method is explicitly safe and idempotent, allowing
    functions like caching and automatic retries to operate.
Essentially, it's for things that are inherently safe/idempotent already (e.g. search or indeed, anything that you don't mind being retried) but require a lot of data passed in the request.