Skip to content

Regression: @Header(schema = @Schema(type = "string")) generates empty or broken schema in OpenAPI output since 2.8.0 #2972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bvo42 opened this issue Apr 22, 2025 · 5 comments
Labels
bug Something isn't working

Comments

@bvo42
Copy link

bvo42 commented Apr 22, 2025

Description:

In versions prior to 2.8.0 of springdoc-openapi, using @Header with @Schema(type = "string") correctly generated the expected schema in the OpenAPI documentation.

However, starting with 2.8.0, the generated schema became incorrect, and as of 2.8.6 it results in a completely empty schema.


Reproducer Example:

@ApiResponse(
  responseCode = "201",
  description = "Created",
  headers = {
    @Header(name = "Location", required = true, schema = @Schema(type = "string"))
  }
)

Expected OpenAPI Output (as seen with 2.7.0):

headers:
  Location:
    required: true
    schema:
      type: string
    style: simple

Actual Output:

  • With 2.8.0:
headers:
  Location:
    required: true
    schema:
      example: null
    style: simple
  • With 2.8.6:
headers:
  Location:
    required: true
    schema: {}
    style: simple

Workaround:

Switching to implementation = String.class fixes the issue:

@Header(name = "Location", required = true, schema = @Schema(implementation = String.class))

This produces the correct OpenAPI YAML again.


Environment:

  • springdoc-openapi version: 2.8.6
  • Spring Boot version: 3.4.4
  • Java version: OpenJDK 17

Additional Notes:

This seems to be a regression introduced in 2.8.0. The schema handling for headers appears to be broken when using type = "string", which previously worked. The problem did not exist in 2.7.0.

Please let me know if you need a full minimal sample project to reproduce.

@bvo42
Copy link
Author

bvo42 commented Apr 23, 2025

Update / New Finding:

I've discovered that the issue described above does not occur when I explicitly set the OpenAPI version to 3.0 using the following configuration:

springdoc:
  api-docs:
    version: OPENAPI_3_0

@Mattias-Sehlstedt
Copy link

Hi,

This is most likely, as you yourself have already seen, due to your application producing an OpenAPI 3.1 specification.

The default specification that springdoc produces was changed in 2.8.0 (#2790). If you revert to 3.0.1 (as you have already described) then I assume it would retain the previous behavior.

What could be reason for the issues with 3.1 is that swagger-core has introduced types for their schema representation to account for the change in how types are expressed from 3.0 to 3.1 (3.0 had a single type, and null was represented as its own nullable setting. With 3.1 type is now instead a list, which can for example be "type": string, null. See this for a short description). In order to handle this change they now also allow for types.

So you could investigate if setting types in your schema annotation would fix the issue if you are interested in updated the OpenAPI specification version.

@bvo42
Copy link
Author

bvo42 commented Apr 24, 2025

Hi Mattias,

The default specification that springdoc produces was changed in 2.8.0 (#2790).

Yes, I've noticed that now too ;) Interesting decision by SpringDoc to switch from OpenAPI 3.0 to 3.1 in a minor version update... I really didn't expect that.

So you could investigate if setting types in your schema annotation would fix the issue if you are interested in updated the OpenAPI specification version.

Yes, we can do that. It would take a lot of effort because we have many services distributed across multiple teams, but I prefer the @Schema(implementation = String.class) variant anyway.

What could be reason for the issues with 3.1 is that swagger-core has introduced types ...

Thanks for the insight. Unfortunately, I'm not familiar with the internals of SpringDoc. However, from a user perspective, I expect @Schema(implementation = String.class) and @Schema(type = "string") to behave the same, since they express pretty much the same thing, and when generating clients, type = "string" is converted back to a Java String. Even though it's possible to specify a list of types in OA 3.1, the old notation is still perfectly fine, which is why I expect @Schema(type = "string") to still work. Here's an example from https://app.swaggerhub.com;

openapi: 3.1.0
info:
  title: Swagger Petstore - OpenAPI 3.1
...
paths:
  /user/login:
    get:
      ...
      responses:
        '200':
          headers:
            X-Rate-Limit:
              schema:
                type: integer
                format: int32
            X-Expires-After:
              schema:
                type: string
                format: date-time
...

@Mattias-Sehlstedt
Copy link

springdoc-openapi relies a lot on swagger-core when it comes to converting code into a specification. What swagger-core offers is the annotations as well as introspection of these that are then collected in their OpenAPI object.

I have debugged the issue and to me it does not seem to be a behavior that should reside in springdoc-openapi, but it would rather be something that should be raised to swagger-core. The issue is that the introspection just retains the exact schema specified by the user when the introspection diverges here (between either using type or implementation) down to here. Using implementation instead takes another path here and is interpreted differently. So when an OpenAPI 3.1 schema object that lacks a types definition is returned, then that is not part of the schema (while the implement can figure out that it is a 3.1 schema and thus modifies the types field rather than type.

So the current best approach would be to revert the OpenAPI schema version if it is too large of an overhead to adjust the Schema annotation to match the new OpenAPI specification types.

It could also be possible to inject some extra behavior to adjust the default behavior, but again, maybe too much work for no real gain unless you really want 3.1 for its extra features.

@bnasslahsen
Copy link
Collaborator

@bvo42,

As explained by @Mattias-Sehlstedt this is related to the current swagger-core implementation. Please log an issue for the swagger-core team to keep the compatibility.
Meanwhile, i have adde a fix for this behavior.

@bnasslahsen bnasslahsen added the bug Something isn't working label May 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants