← Todas las publicaciones
Liferay DXPHeadless APIsRESTHTTPRFC 10008API Design

Beyond GET: What HTTP QUERY (RFC 10008) Could Mean for Liferay's Headless APIs

Por LR Tools · 23 de agosto de 2026 · 6 min read

This piece is a technical follow-up to a post by Laxit Khanpara on Liferay.dev, which first raised the question of whether the newly standardized HTTP QUERY method has a place in Liferay’s Headless APIs. That post makes the case in broad strokes; here, we dig into what RFC 10008 actually specifies and work through where QUERY would — and wouldn’t — fit into a Headless REST API like Liferay’s today.

The problem: search outgrows the URL

A plain GET is fine for simple retrieval. It falls apart the moment real applications need it: dynamic filters, nested conditions, relationship queries across objects, multiple sort orders, pagination, field selection, and — increasingly — search criteria generated by an LLM rather than typed by a person. Liferay’s Headless APIs already support rich OData-style filtering through query parameters, and it works, but it turns into an unmaintainable, hard-to-cache, awkward-to-log URL the moment the criteria get non-trivial:

GET /o/c/employees?filter=(department eq 'IT' and salary gt 50000)

The common workaround is a dedicated POST “search” endpoint that accepts the same criteria as a JSON body instead of a query string:

POST /o/c/employees/search
Content-Type: application/json

{
  "department": "IT",
  "salary": { "gt": 50000 },
  "experience": { "gte": 5 }
}

That’s more ergonomic, but it’s semantically wrong. POST means “create or process a resource.” Searching does neither — you’re not creating an employee record by asking which employees match a filter — and that mismatch is exactly why request caching, safe-retry, and idempotency guarantees don’t apply to a POST search the way they do to GET.

What RFC 10008 actually specifies

RFC 10008, The HTTP QUERY Method, was published in June 2026 (authors: J. Reschke, J.M. Snell, and M. Bishop) as a Proposed Standard. It defines a new HTTP method, QUERY, that closes exactly this gap: a request that is safe and idempotent like GET, but that carries a request body like POST.

A few specifics that matter for API design, straight from the spec:

  • Safe and idempotent. Because a QUERY request can’t change server state, clients and intermediaries can retry it freely without worrying about partial or duplicate effects — the same guarantee GET gives you today.
  • Explicitly cacheable. Unlike POST, QUERY responses are cacheable by design — but since the request body is part of what determines the response, the cache key has to include the body, not just the URI.
  • A new Accept-Query response header. A resource can advertise that it supports QUERY, and which media types it accepts for the query body, via this header — letting clients discover the capability instead of guessing.

In practice, the same search from above becomes:

QUERY /o/c/employees
Content-Type: application/json

{
  "department": "IT",
  "salary": { "gt": 50000 }
}

Same intent as the POST /search version, same read-only guarantee as GET — without either one’s downside.

Where this fits into Liferay’s Headless APIs

The original post lays out several places this would matter for Liferay specifically, and they hold up:

Structured search requests. Filter, sort, and pagination all become fields in one JSON body instead of a hand-assembled OData filter string:

{
  "filter": { "department": "IT", "salary": { "gt": 50000 } },
  "sort": [{ "field": "name", "direction": "ASC" }],
  "page": 1,
  "pageSize": 20
}

Dynamic Objects. Liferay’s Object framework lets administrators define entirely new object types at runtime — which means the set of filterable fields isn’t known at development time either. A structured JSON body is a far better fit for that than composing filter-string syntax dynamically.

Relationship queries. Filtering across a related object, like matching employees whose department has a given name, reads naturally as nested JSON — { "department": { "name": "Engineering" } } — where the equivalent OData expression gets unwieldy fast.

Low-code tooling. Low-code builders already generate JSON internally to represent a user’s filter selections. QUERY removes the translation layer that currently converts that JSON into a filter string just to satisfy GET.

AI-generated queries. LLMs produce structured JSON far more reliably than they produce correctly-escaped OData filter strings, which matters as more search requests originate from an AI agent instead of a person clicking through a UI.

Request validation. A JSON body can be validated against a JSON Schema before it’s ever executed — something you can’t cleanly do to a query string.

The catch: it’s brand new

RFC 10008 is a few months old at the time of writing, and adoption follows standards, not the other way around. Frameworks in Liferay’s own stack — Spring Boot, Jakarta REST — don’t support the QUERY method yet, which means there’s no realistic path to it showing up in Liferay’s Headless APIs until that tooling catches up.

Takeaway

Nothing here argues for replacing GET — simple lookups should stay exactly as simple as they are today. The interesting case is the search endpoints that already outgrew a query string and quietly became a semantically-wrong POST. For those, QUERY is a real fix, not a workaround: same safety and cacheability guarantees developers already rely on with GET, applied to requests that need a body to express what they’re asking for. Whether it lands in Liferay’s Headless platform is, for now, a framework-support question rather than a design one — but it’s worth knowing the shape of the answer before it does.

This article expands on Laxit Khanpara’s original post — read it on Liferay.dev for the author’s own framing, or read RFC 10008 itself for the full specification.

Este artículo está adaptado de: Laxit Khanpara, Liferay.dev

Más del blog

Liferay DXPPostgreSQLDatabase Migration

Migrating Liferay to PostgreSQL: A More Reliable Alternative to Liferay's Beta Tool

23 de agosto de 2026 · 3 min read

Liferay's own database migration tool is still Beta and unreliable in practice. Here's a third-party alternative, the exact 8-step migration procedure, and links to the tool and its docs.

Liferay DXPSecurityCVE

When a CVE Isn't a Liferay Vulnerability: Presence vs. Reachability

23 de agosto de 2026 · 7 min read

A security scanner finding a CVE in a bundled library isn't proof that Liferay DXP is exploitable through it. Here's how Liferay's security team tells the difference — and why an unnecessary dependency upgrade isn't automatically the safer choice.

Liferay DXPFree TierLicensing

DXP Free Tier Licenses: Why the Product Version Doesn't Have to Match Your Runtime

23 de agosto de 2026 · 3 min read

A DXP Free Tier activation key stamped with a quarterly release that hadn't shipped yet looked like a bug. It wasn't — here's what the product-version field in a Liferay license actually means, and why it isn't a strict compatibility gate.