| ▲ | The HTTP Query Method(ietf.org) |
| 102 points by Ivoah 4 days ago | 45 comments |
| |
|
| ▲ | newscracker 3 hours ago | parent | next [-] |
| A couple of quick observations and comments after skimming through this (some of these are mentioned or hinted at in the RFC). With HTTPS used almost everywhere, using this QUERY method (when standardized) could prevent bookmarking specific “GET” URLs if the developers thoughtlessly replace GET everywhere with QUERY. One of the advantages of GET is the direct visibility, which makes modifications simple and easy for almost anyone (end users, testers, etc.). The larger question I have is who will choose to adopt it sooner, with web servers, web application frameworks and web browsers in the mix. |
| |
| ▲ | arp242 3 hours ago | parent [-] | | The situations where I've wished for GET to be able to have a (typically JSON) body were all in situations where the request isn't "user visible" in the first place. That is: API calls, SPA apps, ajax requests, that sort of thing. Not something people are really supposed to bookmark or call directly. If today you're doing some JS-fu to make an ajax GET request then you already need to do something to have permalinks (if desired). Completely worth bringing up and thinking about, but unless I'm missing something I don't think a QUERY verb will change all that much here? | | |
| ▲ | flakes an hour ago | parent [-] | | > unless I'm missing something I don't think a QUERY verb will change all that much here? The semantics are important. GET APIs are expected to be safe, idempotent, and cache-friendly. When you are unable to use GET for technical reasons and move to POST, suddenly none of the infrastructure (like routers, gateways, or generic http libs) can make these assumptions about your API. For example, many tools will not attempt to put retry logic around POST calls, because they cannot be sure that retrying is safe. Having the QUERY verb allows us to overcome the technical limitations of GET without having to drop the safety expectations. |
|
|
|
| ▲ | gridlocdev 3 hours ago | parent | prev | next [-] |
| I can’t wait for QUERY to become an official RFC. It's felt quite awkward to tiptoe around the existing spec when building features that retrieve data; we've had to either use POST to keep sensitive filter criteria out of http logs or just create a usually massive URL-encoded query string. |
| |
| ▲ | resonious 2 hours ago | parent [-] | | Very timely as I just recently ended up with a URL query string so big that CloudFront rejected the request before it even hit my server.. Ended up switching that endpoint to POST. Would've liked QUERY for that! | | |
| ▲ | bruce511 an hour ago | parent [-] | | I have come across systems that use GET but with a payload like POST. This allows the GET to bypass the 4k URL limit. It's not a common pattern, and QUERY is a nice way to differentiate it (and, I suspect will be more compatible with Middleware). I have a suspicion that quite a few servers support this pattern (as does my own) but not many programmers are aware of it, so it's very infrequently used. | | |
| ▲ | LudwigNagasena 15 minutes ago | parent [-] | | Sending a GET request with a body is just asking for all sorts of weird caching and processing issues. |
|
|
|
|
| ▲ | gbear605 2 hours ago | parent | prev | next [-] |
| At this point I’m infamous in my company for complaining about how something should have been done with a QUERY verb but it hasn’t been approved yet. The cases tend to look like this:
- An endpoint was implemented as a GET endpoint, since it’s for getting data, with the search terms in the query parameters. The search term got too long, breaking a critical behavior in production environments.
- An endpoint was implemented as a POST endpoint, despite it being an idempotent query for data, since the request body is too large to fit in query parameters. New employees repeatedly come in and are confused why it’s not a GET endpoint, or why it doesn’t modify anything. |
| |
| ▲ | tempest_ an hour ago | parent | next [-] | | A POST could be viewed as creating a "search" which, once given an ID could be retrieved later with a GET. I know this densest really work with ad-hock and cheap queries but it does for more expensive / report style ones. | |
| ▲ | thayne 2 hours ago | parent | prev [-] | | Also cases where a GET makes more sense, but there is concern about sensitive data in query parameters getting exposed in logs, so POST is used instead. | | |
|
|
| ▲ | leloctai 2 hours ago | parent | prev | next [-] |
| As inefficient as encoding everything into the URI is, I really enjoy being able to bookmark and share specific filter configuration. More than one I've seen some sites with UI so bad, that manually editing the url is the easiest way to get it to do what i want. |
| |
| ▲ | nrhrjrjrjtntbt 38 minutes ago | parent | next [-] | | Cough Splunk Also another case is as a dev you are dealing with guids all day and it can be fast to swap guids around in the browser bar vs. ui steps. | |
| ▲ | itopaloglu83 2 hours ago | parent | prev [-] | | Okay, I’m a little confused, the HTTP already supports 8000 octets, and some are having issues because they have too many filters? Looking at the logs I see that most of the long URI traffic is due to UTM and other tracking related codes, which are mainly a way to work around 3rd party cookie blocks. I must be missing something, because it sounds like to goal is to have longer URI without the need for encoding URL parameters, but without using POST. |
|
|
| ▲ | jchw 3 hours ago | parent | prev | next [-] |
| Yes! This sounds like a great idea to me. It does have some trade-offs, but I think we would've been better off with this than ever having put queries in the URL in the first place. Rather, if it made enough sense to have some data in the URL itself, it would be better if it could actually be in the path, to distinguish it as a distinct resource. I think there are many reasons why this didn't work out that way but I also think those reasons are mostly historical. I would prefer things like /map/<lat>/<long>/, for example. I don't want to go as far as to say that query parameters were entirely a mistake, but there's nothing they do that couldn't be done otherwise, they just offer a convenient place to delineate unstructured data in a URL that you could then copy around. Sometimes moving that to the path would be awkward (unstructured path elements does exist on the web, but it's weird to do) but often times it would just be better to not have it at all. Don't need UTM codes in my URLs in the first place, and I don't think every single parameter on the page should be in the URL. (If you really wanted to pass someone a saved search full of complex queries, it would be less cumbersome to have a specific URL for saved searches anyhow, in my opinion.) Obviously query parameters are not going anywhere, but if this achieves enough adoption there is a future down the road where we can stop using POST for any query that wants a payload, without needing to change every single HTTP client in the world. (Many of them can already understand custom methods and treat them basically like posts.) |
| |
| ▲ | stephenr 2 hours ago | parent [-] | | > I would prefer things like /map/<lat>/<long>/, for example. PathInfo is a thing you can absolutely use. | | |
| ▲ | jchw 29 minutes ago | parent [-] | | Most web application servers have already equipped to be able to easily parse parameters out of the URL path for many years, of course, it's definitely nothing new, it's just that historically, people reached for URL query parameters for this sort of thing. After all, making a request with query parameters is basically built into the browser; you can do it with <form> and anchor links with no JS needed. Presumably, because of that, many pages will continue to use query parameters for the foreseeable future. I think that's fine, but at least for APIs, the QUERY method could eventually be a very nice thing to have. |
|
|
|
| ▲ | clickety_clack 2 hours ago | parent | prev | next [-] |
| It’s rare that I have a project that justifies the full DDD treatment, but one of the great ideas from it that stuck with me was command/query separation, where you separate out queries, which can be mangled agglomerations of objects for reporting and lists, from commands, which drive your business logic. I love the idea of a separate verb. It always felt like get is just not quite enough. |
| |
|
| ▲ | andyferris 2 hours ago | parent | prev | next [-] |
| Does anyone know what blocks something like this being accepted? I’ve had my eye on this for ages and have had to work around its lack multiple times, so just curious what the hold up could be. |
|
| ▲ | 8cvor6j844qw_d6 2 hours ago | parent | prev | next [-] |
| For the experienced devs. May I ask why would one use POST for everything? I encountered a codebase with only POST for all operations, given my lack of knowledge in this area, I am not sure why one would choose POST only over the standard set of GET, PUT, POST, DELETE, etc. |
| |
| ▲ | nhumrich 4 minutes ago | parent | next [-] | | I prefer POST for everything. The main reason why is because HTTP verbs don't match cleanly to every operation. And it leads to a lot of bike shedding around the exceptions. POST for everything, on the other hand, forces you to put the "method" in the request outside of HTTP semantics, which allows you to "just use" whatever verb makes sense rather than trying to map it to the limited ones available. | |
| ▲ | LudwigNagasena a few seconds ago | parent | prev | next [-] | | Consistency, simplicity, RPC semantics. | |
| ▲ | julianlam 43 minutes ago | parent | prev [-] | | If you encounter a shop that uses POST for everything then they are probably a shop that doesn't know that verbs other than GET and POST exist. ... and they don't use GET everywhere because one time Google scraped that endpoint and dropped the production database. |
|
|
| ▲ | chronicler 3 hours ago | parent | prev | next [-] |
| Making GET requests have bodies as the norm would also handle this |
| |
| ▲ | badbotty 3 hours ago | parent | next [-] | | GET is a keep things simple stupid approach to caching. The URL is the cache key plus any headers touched by the vary header. Adding the requirement to vary on the body and understand the body content semantics brings in a whole lot of complexity that GET avoids. | |
| ▲ | platzhirsch 3 hours ago | parent | prev | next [-] | | I might be misunderstanding something, but it seems the issue isn't really about whether GET can technically carry a body. The deeper concern is that HTTP methods have specific meanings, and mixing those signals can causes confusion and it's nice to have this semantic separation. | | |
| ▲ | cortesoft 3 hours ago | parent | next [-] | | If you look at the summary table, the only difference between a GET and a QUERY is that the query can have a body. Other than that, they have the exact same characteristics and purpose, so there isn’t really a need to semantically separate them. | |
| ▲ | Veserv 3 hours ago | parent | prev [-] | | The problem is that they are not enforced. You can already have GET requests that modify state even though they are not supposed to. What you are actually doing when making a specific kind of request is assuming the actual properties match the documented properties and acting accordingly. A QUERY seems to be no more than a POST that documents it is idempotent. Furthermore, you should only QUERY a resource that has advertised it is idempotent via the “Accept-Query” header. You might as well name that the “Idempotent-Post” header and then you just issue a POST; exactly the same information and properties were expressed and you do not need a new request type to support it. | | |
| ▲ | notatoad 7 minutes ago | parent | next [-] | | HTTP semantics aren’t hard enforced but that only means something if you always control the client, server, and all the middle layers like proxies or CDNs that your traffic flows over. Your GET request can modify state. But if your request exceeds a browser’s timeout threshold, the browser will retry it. And then you get to spend a few days debugging why a certain notification is always getting sent three times (ask me how I know this) Similarly, you can put a body on your GET request in curl. But a browser can’t. And if you need to move your server behind cloudflare one day, that body is gonna get dropped. | |
| ▲ | happytoexplain 3 hours ago | parent | prev | next [-] | | I'm confused - wouldn't idempotent POST be PUT? Isn't the proposed QUERY for fetching semantics? | | |
| ▲ | pcthrowaway 3 hours ago | parent | next [-] | | I think the idea is that POST creates a record (and in theory fails if that record already exists). I guess the commenter above is saying that if you inverted that (fail when the record doesn't exist, return the record if it does) it would be similar to QUERY? Not sure if I agree with that, but PUT's return semantics are a bit vague.. it often returns partial or combined records, or just a 200 OK (with or without a response body), or 204 No Content for unchanged records (with or without a response body) It's clear what POST returns, so... perhaps QUERY is more similar to it in that sense? | | |
| ▲ | johncolanduoni 3 hours ago | parent | next [-] | | Whatever the original intent was, POST definitely does not return a new record consistently in most actual APIs. It's frequently used for actions that don't conceptually create anything at all. | |
| ▲ | LoganDark 2 hours ago | parent | prev [-] | | PUT is the idempotent one. POST typically performs an action; PUT just creates-or-updates. |
| |
| ▲ | Veserv 3 hours ago | parent | prev | next [-] | | The existing mechanism to get QUERY semantics is a POST that encodes the “fetch parameters” in the body and the response contains the fetched values. You then out-of-band document that this specific use of a fetching POST is idempotent. This is literally expressed in the document in section 1: Introduction. They just want to take that POST request and replace the word POST with QUERY which also means the server is intended to assure the request is idempotent instead of needing that documented out-of-band. | |
| ▲ | johncolanduoni 3 hours ago | parent | prev [-] | | For some reason the RFC focuses on idempotency, but then says it's explicitly intended for enabling caching semantics. Caching a query that mutates visible state doesn't really make sense, and like you point out if you just want idempotent modifications PUT already has the relevant semantics. I guess we haven't learned our lesson from making the original HTTP semantics super squishy. |
| |
| ▲ | cortesoft 3 hours ago | parent | prev [-] | | It would be pretty impossible to actually ‘enforce’ that GETs don’t modify state. I am not sure if I would call the lack of enforcement a problem when it is more a simple fact about distributed systems; no specification can enforce what a service does outside of the what is returned in a response. | | |
| ▲ | Veserv an hour ago | parent [-] | | That is exactly my point. There is no reason to syntactically distinguish what is semantically non-distinguishable. The interpretation of a request is up to the server. There is no reason for the client to syntactically distinguish that the request body is for a POST vs QUERY; the request parameters and response have the same shape with the same serialization format. However, on the other side, a server does control interpretation, so it is responsible for documenting and enforcing how it will interpret. QUERY semantics vs generic POST semantics is a receive/server-side decision and thus should not be a syntactic element of client requests, merely a server description of endpoint semantics (“QUERY endpoint” meaning shorthand for POST endpoint with query semantics). edit: Thinking about it some more, there is one possible semantic difference which is that a transparent caching layer could use a syntactically different POST (i.e. QUERY) to know it should be allowed to cache the request-response. I do not know enough about caching layers to know how exactly they make fill/eviction choices to know if that is important. |
|
|
| |
| ▲ | vlovich123 2 hours ago | parent | prev | next [-] | | I suspect the challenge would be all the middleware that assumes that get never had a body. | |
| ▲ | ashu1461 2 hours ago | parent | prev [-] | | or get requests with query params already handles this in majority of the cases, unless the query size is too big (which ideally should not be the case since in the end it is a get request) |
|
|
| ▲ | llIIllIIllIIl 3 hours ago | parent | prev | next [-] |
| How does one share the search results with the url to the page with this query method? |
|
| ▲ | hamasho 3 hours ago | parent | prev | next [-] |
| First impression was "umm... I don't even use SEARCH yet." Then realize this is actually SEARCH method but renamed and more generalized. |
|
| ▲ | fijiaarone 3 hours ago | parent | prev [-] |
| We already have POST, PUT, and PATCH that do the exact same thing. Why not have another version of GET that looks the same as POST and is subject to personal interpretation. FYI:
QUERY is for GET requests where the query string make the URL too long. It does this by sending a body like POST. In the past, POST meant you were sending a body, and GET meant you received a body. And the people got religious about a pseudoacronym called REST. |
| |
| ▲ | johncolanduoni 3 hours ago | parent | next [-] | | Apart from the sectarian conflicts about what REST means, having a HTTP method that proxies can cache like a GET but allows bodies is pretty useful from a purely practical standpoint. You can do this with POST, but it requires proxy-specific configuration. | |
| ▲ | cortesoft 2 hours ago | parent | prev [-] | | The point of the HTTP verbs is to communicate expected behavior. While a server could treat POST, PUT, and PATCH the same, the point of having the verbs at all is to give a standard way to signal clients what is going to happen. While a server can ignore the expectation, it doesn’t mean the expectation isn’t valuable; it allows conforming implementers to communicate what is happening using standard language. |
|