Repository navigation
8.4.0: generate every OpenAPI 3.2 operation (QUERY, additionalOperations, HEAD/OPTIONS/TRACE) and stop dropping 3.2 contract parts silently - #474
Merged
jemacineiras merged 2 commits intoSep 30, 2026
Conversation
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 43 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
…parts silently Operations: head, options and trace were dropped, and so were OpenAPI 3.2's query and additionalOperations. Every Path Item operation is now generated. Servers map the methods Spring's RequestMethod has no constant for (QUERY, PURGE...) with a generated @HttpMethodMapping, which a generated HttpMethodMappingConfiguration maps through a RequestMappingHandlerMapping of its own (Spring MVC and WebFlux, Boot 2 to 4): it maps only those methods, so Spring still answers the others, 405 included, and it answers 406/415 for a request of its method it cannot serve. Such operations declare what they consume, since Spring reads a @RequestBody's content type only for POST/PUT/PATCH. Clients send them with HttpMethod.valueOf; Spring Boot 2 clients, whose HttpMethod is an enum, fail the generation instead. Also: - an in: querystring parameter, a form-encoded schema of the whole query string, is read as that object sent form-exploded (any other media type fails); clients used to take it and never send it; - a $ref to components/mediaTypes is resolved (it crashed the generator); - a response without description is documented with its summary; - application/json-seq and text/event-stream fail the generation, as their items were read as a single JSON document. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
joseegman-idoneea
force-pushed
the
feature/openapi-3.2-no-silent-loss
branch
from
September 29, 2026 14:40
f670dad to
ab59c61
Compare
jemacineiras
approved these changes
Sep 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The engine accepted
openapi: 3.2.0, but running a 3.2 contract for each new feature through it showed parts dropped without a word, or crashing the generator:queryoperationadditionalOperations(e.g.PURGE)head,options,trace(not new in 3.2)in: querystringform-exploded query object, everywhere$reftocomponents/mediaTypessummarywithoutdescriptionapplication/json-seq,text/event-streamproduces = "application/json"Methods Spring's
RequestMethodhas no constant for@RequestMappingonly takesRequestMethod's eight methods, so servers mapQUERYand theadditionalOperationsmethods with a generated annotation:The generated
HttpMethodMappingConfiguration(Spring MVC or WebFlux variant) registers aRequestMappingHandlerMappingsubclass. It builds aRequestMappingInfowith a custom method condition from that annotation, and maps nothing else. It does not replace Spring's mapping (noWebMvcRegistrations), so it cannot clash with an application's own configuration.The
@HttpMethodMappingoperations carry no@RequestMapping, so Spring's mapping ignores them. The generated mapping comes first, and a request of another method falls through to Spring's (POST /itemsis still Spring's 405). For a request of its own method it cannot serve, it answers as Spring would (406/415).These operations also declare
consumes, because Spring checks a@RequestBody's content type only for POST/PUT/PATCH. Without it, aQUERYwith atext/plainbody got a 400 "body missing" instead of a 415.It is found by component scanning of the API package, or through
@Import(HttpMethodMappingConfiguration.class).Clients send these methods with
HttpMethod.valueOf(...)or@HttpExchange(method = "QUERY"). Spring Framework 5'sHttpMethodis an enum, so generating a Spring Boot 2 client fails for them.Behaviour changes
head/options/traceoperations now get those methods generated. They were silently missing before.json-seq/SSE contracts now fail the generation. They used to generate code that could not serve the stream. SSE is the next PR.Known limits (README)
ApiRestClienton aRestClient, or on aRestTemplatewith a factory that sends custom methods. The defaultHttpURLConnectionrejectsQUERY("Invalid HTTP method: QUERY", checked).@HttpMethodMappingoperations.TRACEby default.Test plan
New fixture
testOpenApi32. It covers:querywith a body;options,head, andPURGEviaadditionalOperations;in: querystringwith a$refschema;components/mediaTypes$ref;summary-only responses.Generated for the Spring MVC server (Boot 2, Boot 4), WebFlux (Boot 2
getMethodValue(), Boot 3getMethod().name()), RestClient, WebClient and@HttpExchange.Error tests: a Boot 2 client with
QUERY;application/json-seq;text/event-stream; aquerystringthat is not form-encodedNo existing asset changes
Engine: 267 tests green, checkstyle green; Maven plugin ITs green; Gradle
test integrationTestgreen (JDK 21)Runtime check outside the repo, over real HTTP:
QUERYwith a JSON body filters;PURGE204;GETstill served,POST/DELETEstill Spring's 405;QUERYwithtext/plaingets 415;HEADandOPTIONSwith headers;querystringbound per property.RestClient, the WebClient class and a blocking@HttpExchangesendQUERY,PURGE,HEAD,OPTIONSand the query string. The defaultRestTemplatefails as documented.README: new "OpenAPI 3.2 operations" section
Version bumped to 8.4.0 in all 5 places
🤖 Generated with Claude Code