NestJS 11.2 Adds HTTP QUERY and SSE Abort Signals
On August 14, 2026 the NestJS team published v11.2.0, followed hours later by v11.2.1. It is a minor release on the current stable line, so there is nothing to migrate — but two of the additions are more interesting than the version number suggests. Nest now routes the new HTTP QUERY method, and Server-Sent Events handlers can finally see an AbortSignal for the life of the stream.
QUERY: the safe method with a body
RFC 10008, The HTTP QUERY Method, was published in June 2026 as a Proposed Standard by Julian Reschke, James Snell and Mike Bishop. It defines a method that is safe and idempotent like GET, but carries a request body like POST.
That combination has been the missing piece in HTTP for years. Every team that has built a search or reporting endpoint has hit the same fork in the road: cram a complex filter into a query string and fight URL length limits and encoding, or use POST and give up cacheability, retry semantics, and any honest signal to intermediaries that the call does not mutate state. QUERY is the third option — the request has a body, and everything downstream still knows it is a read.
NestJS 11.2.0 makes it a first-class route method (#17162):
import { Controller, Body, QueryMethod } from '@nestjs/common';
@Controller('reports')
export class ReportsController {
@QueryMethod('search')
search(@Body() criteria: SearchCriteriaDto) {
return this.reports.run(criteria);
}
}
The decorator is @QueryMethod(), not @Query(), because @Query() has meant "extract a query-string parameter" in Nest since day one. The team took the same escape route they used for @Search() rather than break a decorator that appears in essentially every Nest codebase in existence. QUERY also joins the RequestMethod enum, so guards, interceptors and anything else reading route metadata pick it up without special-casing.
Platform support
On Fastify the PR wires QUERY up explicitly, with body parsing enabled — that is the part a framework has to do deliberately, since a method nobody has heard of will not get a body parser by accident.
On Express it works for free, provided you are on a recent Node. Native QUERY parsing arrived in the runtime via the llhttp 9.2 bump, and Express's routing layer exposes a method automatically once http.METHODS contains it. On Node.js 22 LTS:
node -e "console.log(require('http').METHODS.includes('QUERY'))"
# true
Treat 22.x as the practical floor. And remember that a method this new has to survive the whole path: a CDN, WAF or reverse proxy in front of your API may well reject an unrecognised verb before Nest ever sees it. Test the full chain, not just the framework.
@SseSignal(): plugging a real SSE leak
The second addition (#17469) is smaller in surface area and larger in consequence if you stream. @SseSignal() is a parameter decorator that injects an AbortSignal scoped to the lifetime of an SSE response. It aborts when the stream terminates — client disconnect, Observable completion, or error.
The bug it fixes is the setup phase. If your handler is async and allocates something before returning its Observable — a database session, an upstream connection, a model stream — and the client has already gone away, that Observable is never subscribed. Its teardown function never runs. The resource leaks, silently, exactly in the situation where clients disconnect most: flaky mobile networks and users closing tabs mid-stream.
@Sse('stream')
async stream(@SseSignal() signal: AbortSignal): Promise<Observable<MessageEvent>> {
const session = await createSession();
if (signal.aborted) {
await session.close();
return EMPTY;
}
return new Observable(subscriber => {
const gen = startGeneration(session);
signal.addEventListener('abort', () => gen.stop(), { once: true });
return () => gen.stop();
});
}
Two caveats straight from the API docs. The signal aborts on normal completion too, so signal.aborted only answers "did the client go away?" during setup, before the Observable exists. And because abort-driven cleanup can run alongside the Observable's own teardown, make it idempotent.
v11.2.1 is a single-line follow-up to this feature — fix(core): early-return SSE abort issue — shipped the same day. Go straight to 11.2.1.
The fix you did not ask for but probably needed
Buried in the bugfix list: singleton providers are now shared with lazily loaded modules (#17430). If you use LazyModuleLoader and have ever debugged a second instance of a provider you were confident was a singleton — a connection pool, a cache client, an in-memory registry — that was this. Also fixed: middleware now runs on routes excluded from the global prefix (#17377), and inherited middleware is no longer double-prefixed (#17350).
fastify moves to 5.12.0 (#17473) for @nestjs/platform-fastify users.
Should you take it
Yes, on the next routine dependency bump. This is a SEMVER-MINOR release inside the line you are already on — no migration guide, no breaking changes. The lazy-module DI fix alone justifies it if you use LazyModuleLoader.
Worth noting what this release is not: it is not NestJS 12, the ESM-and-Vitest major still tracking Q3 2026 under the next tag. 11.2 is the stable line getting real features while that lands — which is the healthier signal of the two.
Running a Nest API where the streaming endpoints leak and nobody is quite sure why? Talk to us.