-
-
Notifications
You must be signed in to change notification settings - Fork 553
Description
Describe the bug
When using the annotation @ApiResponse with a content and a mediatype, the schema of my response object is being replaced by a String (instead of the reference to the actual schema).
Example:
@GetMapping("/test")
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "get", description = "Provides a response.")
@ApiResponse(content = @Content(mediaType = MediaTypes.HAL_JSON_VALUE,
schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = Response.class)),
responseCode = "200")
public Response get() {
return new Response("value");
}This is due to a NullPointerException occuring in the new HateoasLinksConverter.
The stacktrace (not displayed as catched in SpringDocAnnotationsUtils line 442) :
java.lang.NullPointerException: Cannot invoke "String.substring(int)" because the return value of "io.swagger.v3.oas.models.media.Schema.get$ref()" is null
at org.springdoc.core.converters.HateoasLinksConverter.resolve(HateoasLinksConverter.java:74)
at org.springdoc.core.converters.PageableOpenAPIConverter.resolve(PageableOpenAPIConverter.java:97)
at org.springdoc.core.converters.PageOpenAPIConverter.resolve(PageOpenAPIConverter.java:102)
at org.springdoc.core.converters.SortOpenAPIConverter.resolve(SortOpenAPIConverter.java:92)
at io.swagger.v3.core.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:97)
at io.swagger.v3.core.jackson.ModelResolver.resolve(ModelResolver.java:493)
at org.springdoc.core.converters.WebFluxSupportConverter.resolve(WebFluxSupportConverter.java:89)
at org.springdoc.core.converters.AdditionalModelsConverter.resolve(AdditionalModelsConverter.java:163)
at org.springdoc.core.converters.FileSupportConverter.resolve(FileSupportConverter.java:72)
at org.springdoc.core.converters.ResponseSupportConverter.resolve(ResponseSupportConverter.java:84)
at org.springdoc.core.converters.SchemaPropertyDeprecatingConverter.resolve(SchemaPropertyDeprecatingConverter.java:95)
at org.springdoc.core.converters.PolymorphicModelConverter.resolve(PolymorphicModelConverter.java:141)
at org.springdoc.core.converters.OAS31ModelConverter.resolve(OAS31ModelConverter.java:49)
at org.springdoc.core.converters.CollectionModelContentConverter.resolve(CollectionModelContentConverter.java:84)
at org.springdoc.core.converters.HateoasLinksConverter.resolve(HateoasLinksConverter.java:87)
at org.springdoc.core.converters.PageableOpenAPIConverter.resolve(PageableOpenAPIConverter.java:97)
at org.springdoc.core.converters.PageOpenAPIConverter.resolve(PageOpenAPIConverter.java:102)
at org.springdoc.core.converters.SortOpenAPIConverter.resolve(SortOpenAPIConverter.java:92)
at io.swagger.v3.core.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:97)
at io.swagger.v3.core.jackson.ModelResolver.resolve(ModelResolver.java:745)
at org.springdoc.core.converters.WebFluxSupportConverter.resolve(WebFluxSupportConverter.java:89)
at org.springdoc.core.converters.AdditionalModelsConverter.resolve(AdditionalModelsConverter.java:163)
at org.springdoc.core.converters.FileSupportConverter.resolve(FileSupportConverter.java:72)
at org.springdoc.core.converters.ResponseSupportConverter.resolve(ResponseSupportConverter.java:84)
at org.springdoc.core.converters.SchemaPropertyDeprecatingConverter.resolve(SchemaPropertyDeprecatingConverter.java:95)
at org.springdoc.core.converters.PolymorphicModelConverter.resolve(PolymorphicModelConverter.java:141)
at org.springdoc.core.converters.OAS31ModelConverter.resolve(OAS31ModelConverter.java:49)
at org.springdoc.core.converters.CollectionModelContentConverter.resolve(CollectionModelContentConverter.java:84)
at org.springdoc.core.converters.HateoasLinksConverter.resolve(HateoasLinksConverter.java:73)
at org.springdoc.core.converters.PageableOpenAPIConverter.resolve(PageableOpenAPIConverter.java:97)
at org.springdoc.core.converters.PageOpenAPIConverter.resolve(PageOpenAPIConverter.java:102)
at org.springdoc.core.converters.SortOpenAPIConverter.resolve(SortOpenAPIConverter.java:92)
at io.swagger.v3.core.converter.ModelConverterContextImpl.resolve(ModelConverterContextImpl.java:97)
at io.swagger.v3.core.converter.ModelConverters.resolveAsResolvedSchema(ModelConverters.java:192)
at org.springdoc.core.utils.SpringDocAnnotationsUtils.extractSchema(SpringDocAnnotationsUtils.java:137)
at org.springdoc.core.service.GenericResponseService.calculateSchema(GenericResponseService.java:563)
at org.springdoc.core.service.GenericResponseService.buildContent(GenericResponseService.java:541)
at org.springdoc.core.service.GenericResponseService.buildContent(GenericResponseService.java:522)
at org.springdoc.core.service.GenericResponseService.buildApiResponses(GenericResponseService.java:595)
at org.springdoc.core.service.GenericResponseService.buildApiResponses(GenericResponseService.java:469)
at org.springdoc.core.service.GenericResponseService.build(GenericResponseService.java:264)
at org.springdoc.api.AbstractOpenApiResource.calculatePath(AbstractOpenApiResource.java:626)
at org.springdoc.api.AbstractOpenApiResource.calculatePath(AbstractOpenApiResource.java:816)
at org.springdoc.webmvc.api.OpenApiResource.lambda$calculatePath$11(OpenApiResource.java:222)
at java.base/java.util.Optional.ifPresent(Optional.java:178)
at org.springdoc.webmvc.api.OpenApiResource.calculatePath(OpenApiResource.java:203)
at org.springdoc.webmvc.api.OpenApiResource.lambda$getPaths$2(OpenApiResource.java:173)
at java.base/java.util.Optional.ifPresent(Optional.java:178)
at org.springdoc.webmvc.api.OpenApiResource.getPaths(OpenApiResource.java:152)
at org.springdoc.api.AbstractOpenApiResource.getOpenApi(AbstractOpenApiResource.java:370)
at org.springdoc.webmvc.api.OpenApiResource.openapiJson(OpenApiResource.java:127)
at org.springdoc.webmvc.api.OpenApiWebMvcResource.openapiJson(OpenApiWebMvcResource.java:117)
How to reproduce
git clone https://github.com/didjoman/Springdoc-String-Schema-returned-mediatype-issue
Run the application (spring boot).
Run curl --location --request GET 'http://localhost:8080/api-docs' --header 'Content-Type: application/json'
Expected behavior
I expect to have the same OAS generated as before v2.8.2, that is to say:
{
"openapi": "3.1.0",
"info": {
"title": "OpenAPI definition",
"version": "v0"
},
"servers": [
{
"url": "http://localhost:8080",
"description": "Generated server url"
}
],
"paths": {
"/test": {
"get": {
"tags": [
"basic-controller"
],
"summary": "get",
"description": "Provides a response.",
"operationId": "get",
"responses": {
"200": {
"description": "OK",
"content": {
"application/hal+json": {
"schema": {
"$ref": "#/components/schemas/Response"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Link": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"hreflang": {
"type": "string"
},
"title": {
"type": "string"
},
"type": {
"type": "string"
},
"deprecation": {
"type": "string"
},
"profile": {
"type": "string"
},
"name": {
"type": "string"
},
"templated": {
"type": "boolean"
}
}
},
"Response": {
"type": "object",
"description": "test description",
"properties": {
"value2": {
"type": "string"
},
"_links": {
"$ref": "#/components/schemas/Links"
}
}
},
"Links": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/Link"
}
}
}
}
}Actual behavior
Since v2.8.2 I have this, the Response schema is not generated and its reference in the path is replaced by the type String:
{
"openapi": "3.1.0",
"info": {
"title": "OpenAPI definition",
"version": "v0"
},
"servers": [
{
"url": "http://localhost:8080",
"description": "Generated server url"
}
],
"paths": {
"/test": {
"get": {
"tags": [
"basic-controller"
],
"summary": "get",
"description": "Provides a response.",
"operationId": "get",
"responses": {
"200": {
"description": "OK",
"content": {
"application/hal+json": {
"schema": {
"type": "string"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Link": {
"type": "object",
"properties": {
"href": {
"type": "string"
},
"hreflang": {
"type": "string"
},
"title": {
"type": "string"
},
"type": {
"type": "string"
},
"deprecation": {
"type": "string"
},
"profile": {
"type": "string"
},
"name": {
"type": "string"
},
"templated": {
"type": "boolean"
}
}
},
"Links": {
"type": "object",
"additionalProperties": {
"$ref": "#/components/schemas/Link"
}
}
}
}
}Additional context
The issue did not occur before v2.8.2, and it is still present in v2.8.4.
I think it may be related to this commit 88f5da0 introducing the HateoasLinkConverter. But it's not clear what should be done to fix it.
Maybe, the swagger-core.ModelResolver should be called with a new AnnotatedType(returnType) .resolveAsRef(true).jsonViewAnnotation(jsonView).ctxAnnotations(annotations) as it is done in SpringDocAnnotationsUtils.extractSchema() line 138 ? Because, here it gets called with resolveAsRef(false), then the ref is not added to the schema at line ModelResolver.resolve() line 1060 and then it breaks in HateoasLinksConverter.resolve() line 74.
Thank you for your help :)