Repository navigation
Conversation
|
Added a test-only commit: the chunked oversized-body case now accepts either the |
There was a problem hiding this comment.
🟡 Changes recommended
The customizer can change the selected operation after transport validation, allowing mutations over GET and subscriptions to bypass execution restrictions.
4 open issues
What changed in this PR
Completes the GraphQL server HTTP binding on top of the G0 extension, adding request controls and Restlet context integration for G1.
Changes:
- Adds opt-in GET queries, operation restrictions, parameter validation, and response-media-specific status codes.
- Introduces request-size limits, per-adapter parser options, and execution customization with protected request context keys.
- Adds binding tests and shared schema fixtures, and updates the changelog.
| File | Description |
|---|---|
org.restlet.ext.graphql/src/test/java/org/restlet/ext/graphql/TickPublisher.java |
Adds a publisher fixture to detect subscription execution. |
org.restlet.ext.graphql/src/test/java/org/restlet/ext/graphql/GraphqlTestSchemas.java |
Adds context, DataLoader, and subscription test fields. |
org.restlet.ext.graphql/src/test/java/org/restlet/ext/graphql/GraphqlServerBindingTestCase.java |
Tests HTTP rules, limits, authentication context, and configuration freezing. |
org.restlet.ext.graphql/src/main/java/org/restlet/ext/graphql/RestletGraphql.java |
Defines public request and client-info context keys. |
org.restlet.ext.graphql/src/main/java/org/restlet/ext/graphql/GraphqlServerAdapter.java |
Implements the expanded HTTP binding and execution controls. |
changes.md |
Documents the new server-binding capabilities. |
Review effort: Balanced
- GET for queries only, when enabled (off by default); other operations over GET get 405 with Allow: POST. - 415 for non-JSON POST bodies; 400 for batches and malformed parameters; 413 above maxRequestBytes (1 MiB), checked on the declared size and while reading. - Documents are parsed with the adapter's ParserOptions before execution to select the operation. Parse errors, validation errors and missing or unknown operations get 400 with application/graphql-response+json and 200 with application/json. Execution results are 200, even with field errors. - ParserOptions are passed per execution through the GraphQLContext, never through graphql-java's process-wide defaults. - RestletGraphql.REQUEST and CLIENT_INFO context keys, set after the execution input customizer so they can't be replaced. - Subscriptions are rejected without being executed until G3. Refs #1583 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Jerome Louvel <374450+jlouvel@users.noreply.github.com>
The server answers 413 before reading the whole chunked body and closes the connection, so the client may fail while still writing it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Jerome Louvel <374450+jlouvel@users.noreply.github.com>
Select the operation once the execution input is customized, so that a customizer can't run a mutation over GET or a subscription. Treat an empty operationName as omitted, advertise GET in Allow when enabled and add Vary: Accept to negotiated responses. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
06249a5 to
c4b92ab
Compare
|





Closes #1583. Part of #1581.
Summary
Completes the GraphQL over HTTP binding of
GraphqlServerAdapter.POSTfor all operations.GETfor queries only when enabled; other operations overGETget405withAllow: POSTapplication/json; others get415. A JSON array (batch) gets400, never executedapplication/graphql-response+jsonwhen named by the client, otherwiseapplication/json;406if neither400for malformed requests. Parse/validation errors and missing or unknown operations:400withgraphql-response+json,200withapplication/json.200once execution starts, even with field errors413abovemaxRequestBytes, checked on the declared size and while reading. Parser limits from the adapter'sParserOptions, passed per execution in theGraphQLContext, never through graphql-java's process-wide static defaultsRestletGraphql.REQUESTandRestletGraphql.CLIENT_INFOin theGraphQLContext, set after the customizer so neither it nor callerextensionscan replace themPolicies stay native: depth and complexity limits (
MaxQueryDepthInstrumentation,MaxQueryComplexityInstrumentation), introspection and exception rendering (DataFetcherExceptionHandler) are configured on theGraphQLinstance.The document is parsed once by the adapter (to select the operation and enforce the
GETand subscription rules before anything executes) and again by graphql-java. The adapter does not install aPreparsedDocumentProvider, which remains the application's choice.Validation
./mvnw -B verify -P default,test -pl org.restlet.ext.graphql: 25 tests, 0 failures; 95.8% instruction coverage (gate 80%); Spotless, SpotBugs, Javadoc,-Werrorand dependency convergence pass.New
GraphqlServerBindingTestCase(12 tests):GETdisabled by default,GETqueries with variables andoperationName,GETmutations rejected,415, malformed parameters, status per media type for five kinds of document errors, field errors, subscriptions rejected without creating their publisher,413with declared and chunked bodies, per-adapter parser limits with the process-wide defaults unchanged, request andDataLoaderthrough the customizer (which can't spoof the request key), the user of aChallengeAuthenticatorreaching a data fetcher, frozen configuration.The community
graphql-httpaudit suite (JavaScript) is not wired in; the cases above follow its server rules.🤖 Generated with Claude Code