Skip to content

[bugfix] RESTServer: set Content-Type for JSON results#6478

Merged
line-o merged 1 commit into
eXist-db:developfrom
joewiz:bugfix/restserver-json-content-type
Jun 15, 2026
Merged

[bugfix] RESTServer: set Content-Type for JSON results#6478
line-o merged 1 commit into
eXist-db:developfrom
joewiz:bugfix/restserver-json-content-type

Conversation

@joewiz

@joewiz joewiz commented Jun 15, 2026

Copy link
Copy Markdown
Member

[This PR was co-authored with Claude Code. -Joe]

Summary

The REST server's JSON result writer (RESTServer.writeResultJSON) never set the response Content-Type. As a result, query results serialized as JSON — a POST <query method="json"> (the JSON result envelope used by the query sandbox in eXide and other clients) — were returned without a Content-Type header, and output:media-type was silently ignored on that path. Clients then received JSON under the wrong media type, which is the "XML Parsing Error in console" class of failure (browsers try to parse a JSON body as XML).

The XML writer (writeResultXML) already honors output:media-type and sets Content-Type; the JSON writer simply never did.

Fix

In writeResultJSON, set the response Content-Type before the output stream is opened (mirroring the XML path):

  • if the response already carries a Content-Type, leave it;
  • otherwise default to application/json, but honor an explicit output:media-type when the query set one to something other than the XML default (so a custom type like application/vnd.api+json is respected).

The logic lives in a small private helper (setJsonResponseContentType) so the (already large) writeResultJSON method gains no extra branching. A reusable MimeType.JSON_TYPE constant (application/json) is added alongside the existing XML_TYPE/HTML_TYPE/TEXT_TYPE.

Tests

Two new cases in RESTServiceTest:

  • postQueryJsonContentType — a method="json" query returns Content-Type: application/json.
  • postQueryJsonExplicitMediaType — an explicit media-type is honored rather than overridden by the application/json default.

Both pass; the change introduces no new PMD findings (the touched method drops back under the NPath threshold).

Context

This is an independent eXist-core bug that surfaced in discussion of the eXide login work (the same underlying gap behind eXist-db/eXide#253). It's worth fixing on its own because the JSON result envelope is used by any REST/JSON client, not just eXide — eXide's own login has separately moved onto Roaster. A companion effort adds reusable Accept-header content negotiation to the request module; this PR is just the narrow Content-Type bug and stands alone.

writeResultJSON never called response.setContentType(), so REST query
results serialized as JSON (a POST <query method="json"> envelope) were
returned without a Content-Type and output:media-type was silently
ignored on that path — clients received JSON under the wrong media type
(the "XML Parsing Error in console" class of failure). The XML writer
(writeResultXML) already honors output:media-type.

Set the Content-Type in writeResultJSON before the output stream is
opened: default to application/json, but honor an explicit (non-XML-
default) output:media-type. The logic lives in a small helper so the
method gains no extra branching. Add a reusable MimeType.JSON_TYPE
constant alongside XML_TYPE/HTML_TYPE/TEXT_TYPE.

Tests (RESTServiceTest): postQueryJsonContentType asserts the default
application/json; postQueryJsonExplicitMediaType asserts an explicit
media-type is honored.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@joewiz
joewiz requested a review from a team as a code owner June 15, 2026 01:17
@duncdrum
duncdrum requested a review from a team June 15, 2026 08:21
@line-o
line-o merged commit e53576e into eXist-db:develop Jun 15, 2026
9 checks passed
@joewiz
joewiz deleted the bugfix/restserver-json-content-type branch June 16, 2026 03:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants