What happens when the data you use to make a query is too complex for you to pass as an HTTP query parameter? Sometimes, queries are more sophisticated than the usual "free text" you enter on your favorite search engine. Whenever that happens, you need to find a way to pass all the query parameters to the API server in a clean way. Stay with me to learn more about different options and what the HTTP QUERY method brings to the table.
This article is brought to you with the help of our supporter: Speakeasy.
Further expanding its best-in-class API tooling, Speakeasy now empowers teams with open standards. The platform simplifies OpenAPI Overlay adoption so you can focus on building. Click the button below to check out the playground.
For every five API operations, three are three queries. At least that's what I found after analyzing almost 2,000 public API definitions. Most of these queries are so simple that you don't even need to pass any parameters. However, some of them can be extremely complicated to use (I've seen operations with more than 10 parameters). If you're the consumer of one of those operations you have to stick to what the API provides. But if you're the producer you're free to choose how you design those operations. And, this is why some APIs offer query operations behind HTTP POSTs.
Now, according to the RESTful way, you use the HTTP POST verb whenever you want to create a resource. You definitely don't use HTTP POST to perform a query. And, yet, that's what many people propose with their API designs. In fact, this has been happening for quite some time. For example, Microsoft recommends passing OData query parameters in an HTTP POST body whenever the URL gets too long. And, that's the usual recommendation you get when you ask around.
This misuse of HTTP POST to perform query operations is one of the reasons James Snell et. al. started their work on a viable alternative standard about 10 years ago. They first named the new method SEARCH and later changed it to QUERY. And, we're lucky because they published an update just a few days ago, on March 12, 2025. They present the QUERY method as a solution to expressing complex query parameters in a GET, and also to the unsafe and non-idempotent POST. HTTP QUERY gives you the best of both worlds. It's safe, idempotent, and cacheable as a GET would be, and also carries a body payload as a POST would.
One part of the specification that caught my attention is their approach to how the QUERY method is cacheable. Specifically, how they propose that the cache key for a query is formed. You know how a cache key for a GET request is formed, right? It's usually the URL, including any parameters. Every time you make a GET request using the exact same URL as before, you might end up obtaining a response from a cache and not from the original server. But, now the authors are proposing that the cache key for a QUERY request "must incorporate the request content." Additionally, they propose to normalize the cache key by removing any encodings, and normalizing it, including optimization based on the semantics of the content. This is very interesting because it can potentially lead to a more robust cache layer that can handle more use cases than what's now possible. CDNs, for instance, could benefit from this change in how cache keys are crafted.
Another part of the specification I found interesting is the authors' proposal of the "Accept-Query" response header field. Its purpose is to "directly signal support for the QUERY method while identifying the specific query format media type(s) that may be used." While signaling support for the QUERY method is nice, what's even more interesting is announcing what query formats the server supports. You could use the "Accept-Query" response header to let consumers know they can perform queries in, for instance, SQL, or OData query options. Or, some other query language. Different servers can offer query formats. Well, in theory, you can use different query languages on the same server, or even on the same resource.
It's up to the API producer to define the query format—or language—to support. There's an interesting opportunity here related to API Governance. I imagine that for large enough landscapes you might already find a combination of HTTP POST query operations using different query formats. One of the tasks would be to map those combinations, understand their differences, and come up with a standardized recommendation. And this work can already start, even before the HTTP QUERY becomes an IETF standard and not just a draft as it is now.