<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rushit Anadkat</title>
    <description>The latest articles on DEV Community by Rushit Anadkat (@rushit_anadkat_0fdf315193).</description>
    <link>https://dev.to/rushit_anadkat_0fdf315193</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2122594%2Fd6015d60-3cff-4bcd-afe9-93dcc4107041.jpg</url>
      <title>DEV Community: Rushit Anadkat</title>
      <link>https://dev.to/rushit_anadkat_0fdf315193</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rushit_anadkat_0fdf315193"/>
    <language>en</language>
    <item>
      <title>The HTTP QUERY Method: What It Actually Does for Developers</title>
      <dc:creator>Rushit Anadkat</dc:creator>
      <pubDate>Mon, 13 Jul 2026 06:02:35 +0000</pubDate>
      <link>https://dev.to/rushit_anadkat_0fdf315193/the-http-query-method-what-it-actually-does-for-developers-m09</link>
      <guid>https://dev.to/rushit_anadkat_0fdf315193/the-http-query-method-what-it-actually-does-for-developers-m09</guid>
      <description>&lt;p&gt;&lt;em&gt;RFC 10008 gave us a safe, idempotent request with a body. Here's what that changes in your day-to-day work — no spec-lawyering required.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Every backend dev has written this comment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// POST because GET can't have a body. This does NOT modify anything.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's an apology to the protocol. You know the endpoint is a read. HTTP just never gave you an honest way to say so. So you reached for &lt;code&gt;POST&lt;/code&gt;, told every cache and proxy in the path to assume the worst, and moved on.&lt;/p&gt;

&lt;p&gt;In June 2026 the IETF published &lt;strong&gt;RFC 10008&lt;/strong&gt;, defining a new method: &lt;strong&gt;QUERY&lt;/strong&gt;. In one line: &lt;em&gt;a request that's safe and idempotent like GET, but carries a body like POST.&lt;/em&gt; That's it. But that one line quietly removes a pile of workarounds you've been carrying for years. Let's talk about the wins — for you, not for the standards body.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fc4dgyv4nrryqc2g1w5om.png" alt="For 20 years, the " width="800" height="533"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Win #1: Your API becomes self-documenting
&lt;/h2&gt;

&lt;p&gt;Right now, &lt;code&gt;POST /search&lt;/code&gt; tells a new teammate nothing. Does it write? Does it cost money to call twice? They have to read your code or your docs to find out.&lt;/p&gt;

&lt;p&gt;QUERY answers that in the method name. It's registered as &lt;strong&gt;safe and idempotent&lt;/strong&gt;, so anyone — a human, a client library, a proxy — knows it's a read &lt;em&gt;without knowing your API&lt;/em&gt;. The guarantee moves out of your docs and into the protocol.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What you feel:&lt;/strong&gt; fewer "does this POST actually change anything?" questions in code review and onboarding. The method says it.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Win #2: No more URL-length roulette
&lt;/h2&gt;

&lt;p&gt;You've hit this: a filter object grows, someone base64-encodes it into a query param, it works in staging, then a proxy in production caps the URL and you get a &lt;code&gt;414&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;QUERY puts the query in the &lt;strong&gt;body&lt;/strong&gt;, where GraphQL documents, nested filters, geo-polygons, and SQL strings actually fit. No more guessing whether an 8 KB URL survives every hop between client and origin. No more encoding a JSON tree into a URI-safe string and praying.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What you feel:&lt;/strong&gt; you delete the base64 hack, the URL goes back to being just &lt;code&gt;/products&lt;/code&gt;, and your filter is readable JSON again.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F2u9lwkx02jfxckbaaf8m.png" alt="The same search as GET, POST, and QUERY. QUERY looks like POST on the wire but keeps GET's guarantees." width="800" height="470"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Win #3: Retries become free
&lt;/h2&gt;

&lt;p&gt;This is the underrated one. Because QUERY is &lt;strong&gt;idempotent&lt;/strong&gt;, a client or proxy can safely resend it after a timeout or dropped connection — the result of ten identical QUERYs equals one.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;POST /search&lt;/code&gt;, you can't do that. A POST that times out &lt;em&gt;might&lt;/em&gt; have acted on the server, so you either hand-roll retry guards or just eat the failure. QUERY inherits retry-safety from the protocol, so your resilience story gets simpler and your tail latency gets better with zero extra code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What you feel:&lt;/strong&gt; you stop writing bespoke "is it safe to retry this read?" logic. It always is.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Win #4: Reads you couldn't cache are now cacheable
&lt;/h2&gt;

&lt;p&gt;POST responses are effectively uncacheable at the HTTP layer. That's why teams pull tricks like persisted queries just to get a CDN to help with reads.&lt;/p&gt;

&lt;p&gt;QUERY responses &lt;strong&gt;are&lt;/strong&gt; cacheable. The catch — and I'll be straight with you — is that the cache key includes the request &lt;em&gt;body&lt;/em&gt;, not just the URL, so the cache has to read and normalize the body before it can find a hit. That's genuinely harder than GET, and it only pays off when your bodies are small and repetitive.&lt;/p&gt;

&lt;p&gt;The spec gives you an elegant escape hatch: a successful QUERY can return a &lt;code&gt;Location&lt;/code&gt; pointing at a stable, GET-able URL for the same query. After the first call, clients switch to cheap conditional GETs (&lt;code&gt;If-None-Match&lt;/code&gt; → &lt;code&gt;304&lt;/code&gt;), and your hot path is back to simple, URL-keyed caching.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Firrcs69zgzc0fca05ygc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Firrcs69zgzc0fca05ygc.png" alt="First QUERY hands back a GET-able URL; after that, clients poll it with cheap conditional GETs." width="800" height="410"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What you feel:&lt;/strong&gt; search and filter endpoints can finally sit behind a CDN — with a clear pattern for the paths where body-keyed caching would be awkward.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Win #5: Cleaner, safer logs
&lt;/h2&gt;

&lt;p&gt;URLs get logged everywhere — access logs, browser history, bookmarks, that one proxy nobody owns. If your query contains anything sensitive (an email, a token, a customer ID in a filter), it's now smeared across every log along the route.&lt;/p&gt;

&lt;p&gt;QUERY keeps the query in the body, which is far less likely to be logged. You get cleaner access logs &lt;em&gt;and&lt;/em&gt; a smaller privacy footprint, for free, just by picking the right method.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What you feel:&lt;/strong&gt; sensitive search terms stop showing up in log aggregators you forgot existed.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Win #6: It fits the tools you already fight with
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GraphQL:&lt;/strong&gt; queries (the reads) can move to QUERY and become HTTP-cacheable without touching your schema. Mutations stay on POST, where they belong.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Elasticsearch / OpenSearch:&lt;/strong&gt; the JSON Query DSL has always ridden on a body over GET/POST — undefined behavior you've tolerated for a decade. QUERY standardizes exactly that pattern.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI / RAG retrieval, search, analytics, SQL-over-HTTP:&lt;/strong&gt; fat filter bodies, vector params, and JSONPath expressions map cleanly onto QUERY instead of an abused POST.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;QUERY isn't a query &lt;em&gt;language&lt;/em&gt; — it's the honest transport those languages have been missing.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you can do today
&lt;/h2&gt;

&lt;p&gt;HTTP methods are just strings, so clients can send QUERY right now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Browser / Node fetch — works today&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.example.com/products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;QUERY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;shoes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maxPrice&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;products&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the server, some frameworks already have first-class support. &lt;strong&gt;Fastify v5&lt;/strong&gt; is the smoothest:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Fastify&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;fastify&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Fastify&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addHttpMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;QUERY&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;hasBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/products&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;runSearch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;.NET&lt;/strong&gt; works via &lt;code&gt;MapMethods("/products", new[] { "QUERY" }, …)&lt;/code&gt;, and &lt;strong&gt;OpenAPI 3.2&lt;/strong&gt; (since Sept 2025) can document &lt;code&gt;query&lt;/code&gt; operations natively. Express and Spring don't have native routing yet, so you handle the method manually (middleware / servlet filter) for now.&lt;/p&gt;




&lt;h2&gt;
  
  
  The honest caveats (so you're not surprised)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cross-origin from a browser preflights.&lt;/strong&gt; QUERY isn't CORS-safelisted, so every cross-origin call adds an OPTIONS round trip. Cache it with &lt;code&gt;Access-Control-Max-Age&lt;/code&gt;, or use the &lt;code&gt;Location&lt;/code&gt;→GET pattern on hot paths.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ecosystem support is uneven.&lt;/strong&gt; Some WAFs, gateways, and older proxies may reject an unfamiliar verb. Test your whole edge, not just your app.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Never use it for writes.&lt;/strong&gt; Safe and idempotent are promises. If it changes state, it's a POST/PUT/PATCH.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content-Type is mandatory.&lt;/strong&gt; No media type, or a wrong one, and a conforming server rejects the request.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My take:&lt;/strong&gt; if you control the full stack, start using QUERY now. For a public API with unknown clients, ship QUERY &lt;em&gt;beside&lt;/em&gt; your existing POST route until intermediaries catch up. (That last part is my recommendation, not the spec's.)&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fkov0wc0zyz8gm506kipm.png" alt="QUERY in one picture: six workarounds it retires." width="800" height="500"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;QUERY doesn't add complexity to your life — it removes a workaround. Reads stop pretending to be writes. Filters leave the URL. Retries and caching come along for free. Logs get cleaner. And the next dev who reads your API knows, from the method alone, that nothing gets modified.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;// POST because GET can't have a body&lt;/code&gt; comment was never a design choice. It was a twenty-year gap in the protocol leaking into your code. RFC 10008 closes it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Sources: RFC 10008 (rfc-editor.org/info/rfc10008); RFC 9110 HTTP Semantics; WHATWG Fetch (CORS/preflight); OpenAPI 3.2.0 announcement (openapis.org); Fastify &lt;code&gt;addHttpMethod&lt;/code&gt; docs. Claims labeled "my take" are opinion, not part of the standard.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published on &lt;a href="https://medium.com/@rushitanadkat94179/the-http-query-method-what-it-actually-does-for-developers-2ca4259f925a" rel="noopener noreferrer"&gt;Medium&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>http</category>
      <category>api</category>
    </item>
  </channel>
</rss>
