swagger-api / swagger-api/swagger-core
Generated but not references ResponseEntity*** type in schema if rest-api-class is using spring's ResponseEntity
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 7.5k
- Forks
- 2.3k
- Avg merge
- 18h 1m
- Merged PRs (30d)
- 10
Description
I have such an interface:
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
import static org.springframework.http.MediaType.APPLICATION_PROBLEM_JSON_VALUE;
import jakarta.validation.constraints.NotBlank;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import org.springframework.http.ProblemDetail;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
@Validated
@Path(ConfigurationControllerApi.ConfiguratioApiPath.V1)
@RequestMapping(path = ConfigurationControllerApi.ConfiguratioApiPath.V1)
@SecurityRequirement(name = "basicScheme")
@ApiResponses(value = {
@ApiResponse(
responseCode = "400", description = "An validation error happens"),
@ApiResponse(
responseCode = "500", description = "Internal server error",
content = {@Content(mediaType = APPLICATION_PROBLEM_JSON_VALUE, schema = @Schema(implementation = ProblemDetail.class))})})
public interface ConfigurationControllerApi {
// skip some constants for path, parameter names etc
@Operation(
summary = "Close a configuration.",
description = "You must use this method to tell the service that a given configuration is no longer needed.",
operationId = "closeConfiguration",
tags = {
ConfigurationApiTags.SERVICE,
ConfigurationApiTags.REMOVE,
ConfigurationApiTags.WRITE,
ConfigurationApiTags.CONFIGURATION,
})
@ApiResponses(value = {
@ApiResponse(
responseCode = "200",
description = "Ok",
content = {
@Content(mediaType = APPLICATION_JSON_VALUE, schema = @Schema(implementation = CloseConfigurationResult.class))
}),
})
@DELETE
@Path(ConfiguratioApiPath.CLOSE_CONFIGURATION)
@Produces(APPLICATION_JSON_VALUE)
@DeleteMapping(path = ConfiguratioApiPath.CLOSE_CONFIGURATION, produces = APPLICATION_JSON_VALUE)
ResponseEntity<CloseConfigurationResult> closeConfiguration(
@Parameter(description = "Id of the configuration you would like to close/destroy.") //
@PathParam(value = ConfigurationApiParameter.CONFIGURATION_ID) //
@PathVariable(value = ConfigurationApiParameter.CONFIGURATION_ID) //
@NotBlank //
@ConfigurationId // my own validation annotation
String configurationId);
}
I run this in a maven build:
<plugin>
<groupId>io.swagger.core.v3</groupId>
<artifactId>swagger-maven-plugin-jakarta</artifactId>
<version>2.2.21</version>
<configuration>
<outputFormat>JSONANDYAML</outputFormat>
<encoding>UTF-8</encoding>
<sortOutput>true</sortOutput>
<prettyPrint>true</prettyPrint>
<readAllResources>false</readAllResources>
<!-- see src/main/resources/META-INF/cc-api-openapi-defaults.yaml - filtered by maven during build with some values from cc top-level pom!-->
<openapiFilePath>${project.build.outputDirectory}/META-INF/cc-api-openapi-defaults.yaml</openapiFilePath>
<openapi31>false</openapi31>
</configuration>
<executions>
<execution>
<id>generate-api-cc-configuration</id>
<goals>
<goal>resolve</goal>
</goals>
<configuration>
<contextId>configuration</contextId>
<outputPath>${project.basedir}/target/openapi-generated/v${api.version.new}/</outputPath>
<outputFileName>${cc.openapi.configuration.new}</outputFileName>
<resourceClasses>com.foobar.rest.api.ConfigurationControllerApi</resourceClasses>
</configuration>
</execution>
....
Everything works fine ... but as an additional result I got a generated but not references:
It seems ResponseEntity is handled by openapi generator but why?!
"ResponseEntityCloseConfigurationResult" : {
"type" : "object",
"properties" : {
"body" : {
"$ref" : "#/components/schemas/CloseConfigurationResult"
},
"headers" : {
"type" : "object",
"additionalProperties" : {
"type" : "array",
"items" : {
"type" : "string"
}
},
"properties" : {
"accept" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/MediaType"
}
},
"acceptCharset" : {
"type" : "array",
"items" : {
"type" : "object",
"properties" : {
"registered" : {
"type" : "boolean"
}
}
}
},
"acceptLanguage" : {
"type" : "array",
"items" : {
"type" : "object",
"properties" : {
"range" : {
"type" : "string"
},
"weight" : {
"type" : "number",
"format" : "double"
}
}
}
},
"acceptLanguageAsLocales" : {
"type" : "array",
"items" : {
"type" : "object",
"properties" : {
"country" : {
"type" : "string"
},
"displayCountry" : {
"type" : "string"
},
"displayLanguage" : {
"type" : "string"
},
"displayName" : {
"type" : "string"
},
"displayScript" : {
"type" : "string"
},
"displayVariant" : {
"type" : "string"
},
"extensionKeys" : {
"type" : "array",
"items" : {
"type" : "string"
},
"uniqueItems" : true
},
"iso3Country" : {
"type" : "string"
},
"iso3Language" : {
"type" : "string"
},
"language" : {
"type" : "string"
},
"script" : {
"type" : "string"
},
"unicodeLocaleAttributes" : {
"type" : "array",
"items" : {
"type" : "string"
},
"uniqueItems" : true
},
"unicodeLocaleKeys" : {
"type" : "array",
"items" : {
"type" : "string"
},
"uniqueItems" : true
},
"variant" : {
"type" : "string"
}
}
}
},
"acceptPatch" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/MediaType"
}
},
"accessControlAllowCredentials" : {
"type" : "boolean"
},
"accessControlAllowHeaders" : {
"type" : "array",
"items" : {
"type" : "string"
}
},
"accessControlAllowMethods" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/HttpMethod"
}
},
"accessControlAllowOrigin" : {
"type" : "string"
},
"accessControlExposeHeaders" : {
"type" : "array",
"items" : {
"type" : "string"
}
},
"accessControlMaxAge" : {
"type" : "integer",
"format" : "int64"
},
"accessControlRequestHeaders" : {
"type" : "array",
"items" : {
"type" : "string"
}
},
"accessControlRequestMethod" : {
"$ref" : "#/components/schemas/HttpMethod"
},
"all" : {
"type" : "object",
"additionalProperties" : {
"type" : "string"
},
"writeOnly" : true
},
"allow" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/HttpMethod"
},
"uniqueItems" : true
},
"basicAuth" : {
"type" : "string",
"writeOnly" : true
},
"bearerAuth" : {
"type" : "string",
"writeOnly" : true
},
"cacheControl" : {
"type" : "string"
},
"connection" : {
"type" : "array",
"items" : {
"type" : "string"
}
},
"contentDisposition" : {
"$ref" : "#/components/schemas/ContentDisposition"
},
"contentLanguage" : {
"type" : "object",
"properties" : {
"country" : {
"type" : "string"
},
"displayCountry" : {
"type" : "string"
},
"displayLanguage" : {
"type" : "string"
},
"displayName" : {
"type" : "string"
},
"displayScript" : {
"type" : "string"
},
"displayVariant" : {
"type" : "string"
},
"extensionKeys" : {
"type" : "array",
"items" : {
"type" : "string"
},
"uniqueItems" : true
},
"iso3Country" : {
"type" : "string"
},
"iso3Language" : {
"type" : "string"
},
"language" : {
"type" : "string"
},
"script" : {
"type" : "string"
},
"unicodeLocaleAttributes" : {
"type" : "array",
"items" : {
"type" : "string"
},
"uniqueItems" : true
},
"unicodeLocaleKeys" : {
"type" : "array",
"items" : {
"type" : "string"
},
"uniqueItems" : true
},
"variant" : {
"type" : "string"
}
}
},
"contentLength" : {
"type" : "integer",
"format" : "int64"
},
"contentType" : {
"$ref" : "#/components/schemas/MediaType"
},
"date" : {
"type" : "integer",
"format" : "int64"
},
"empty" : {
"type" : "boolean"
},
"etag" : {
"type" : "string"
},
"expires" : {
"type" : "integer",
"format" : "int64"
},
"host" : {
"type" : "object",
"properties" : {
"address" : {
"type" : "object",
"properties" : {
"address" : {
"type" : "array",
"items" : {
"type" : "string",
"format" : "byte"
}
},
"anyLocalAddress" : {
"type" : "boolean"
},
"canonicalHostName" : {
"type" : "string"
},
"hostAddress" : {
"type" : "string"
},
"hostName" : {
"type" : "string"
},
"linkLocalAddress" : {
"type" : "boolean"
},
"loopbackAddress" : {
"type" : "boolean"
},
"mcglobal" : {
"type" : "boolean"
},
"mclinkLocal" : {
"type" : "boolean"
},
"mcnodeLocal" : {
"type" : "boolean"
},
"mcorgLocal" : {
"type" : "boolean"
},
"mcsiteLocal" : {
"type" : "boolean"
},
"multicastAddress" : {
"type" : "boolean"
},
"siteLocalAddress" : {
"type" : "boolean"
}
}
},
"hostName" : {
"type" : "string"
},
"hostString" : {
"type" : "string"
},
"port" : {
"type" : "integer",
"format" : "int32"
},
"unresolved" : {
"type" : "boolean"
}
}
},
"ifMatch" : {
"type" : "array",
"items" : {
"type" : "string"
}
},
"ifModifiedSince" : {
"type" : "integer",
"format" : "int64"
},
"ifNoneMatch" : {
"type" : "array",
"items" : {
"type" : "string"
}
},
"ifUnmodifiedSince" : {
"type" : "integer",
"format" : "int64"
},
"lastModified" : {
"type" : "integer",
"format" : "int64"
},
"location" : {
"type" : "string",
"format" : "uri"
},
"origin" : {
"type" : "string"
},
"pragma" : {
"type" : "string"
},
"range" : {
"type" : "array",
"items" : {
"$ref" : "#/components/schemas/HttpRange"
}
},
"upgrade" : {
"type" : "string"
},
"vary" : {
"type" : "array",
"items" : {
"type" : "string"
}
}
}
},
"statusCode" : {
"$ref" : "#/components/schemas/HttpStatusCode"
},
"statusCodeValue" : {
"type" : "integer",
"format" : "int32"
}
}
},
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the swagger-maven-plugin-jakarta resolve execution and the ConfigurationControllerApi resource class shown in the report. Reproduce the generated OpenAPI output for the ResponseEntity return type, then trace how that return type is represented; done means the unintended ResponseEntityCloseConfigurationResult schema is no longer emitted while CloseConfigurationResult remains correctly referenced.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java, spring
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 30/100