Unable to show Custom Header in Open API UI - spring

How to set Custom Header when using Open API 3? I am using Spring Boot + springdoc-openapi-ui example. In this example I am looking to pass the different headers in the request. Below configurations doesn't show option to select the customer header.
What else do I need to change?
#Bean
public OpenAPI customOpenAPI(#Value("${springdoc.version}") String appVersion) {
return new OpenAPI()
.components(new Components().addSecuritySchemes("basicScheme", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic"))
.addParameters("myHeader1", new Parameter().in("header").schema(new StringSchema()).name("myHeader1")).addHeaders("myHeader2", new Header().description("myHeader2 header").schema(new StringSchema())))
.info(new Info()
.title("Petstore API")
.version(appVersion)
.description("This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.")
.termsOfService("http://swagger.io/terms/")
.license(new License().name("Apache 2.0").url("http://springdoc.org")));
}

You can add your custom Header to your operation documentation using the Following annotation #Parameter(in = ParameterIn.HEADER).
For example:
#RestController
#RequestMapping("/api")
#Tag(name = "contact", description = "the Contact API")
public class HelloController {
#Operation(summary = "Find Contacts by name", description = "Name search by %name% format", tags = {"contact"})
#ApiResponses(value = {
#ApiResponse(responseCode = "200", description = "successful operation", content = #Content(array = #ArraySchema(schema = #Schema(implementation = PersonDTO.class))))})
#Parameter(in = ParameterIn.HEADER, description = "Custom Header To be Pass", name = "Accept-version"
, content = #Content(schema = #Schema(type = "string", defaultValue = "v1", allowableValues = {"v1", "v2"}, implementation = PersonDTO.class)))
#GetMapping(value = "/contacts", /*produces = { "application/json", "application/xml" },*/ headers = {"Accept-version=v10"})
public ResponseEntity<List<PersonDTO>> findAll(
#Parameter(description = "Page number, default is 1") #RequestParam(value = "page", defaultValue = "1") int pageNumber,
#Parameter(description = "Name of the contact for search.") #RequestParam(required = false) String name) {
return null;
}}

SOLVED: To have header parameters applied to all requests:
All the suggestions I found didn't work and did some digging and found this solution below:
#Bean
public GlobalOpenApiCustomizer customizer() {
return openApi -> openApi.getPaths().values().stream().flatMap(pathItem -> pathItem.readOperations().stream())
.forEach(operation -> operation.addParametersItem(new HeaderParameter().name("[YOUR_NAMR]")
.description("[YOUR_DESC]")
.in(ParameterIn.HEADER.toString())
.schema(new Schema<>().format("[e.g UUID]").type("[e.g STRING]")) //will be: string($uuid)
.required(true)));
}
Found the solution here: https://springdoc.org/faq.html

Related

What is the Swagger 2 Annotation for the responseContainer?

I working on a Migration from Springfox to Springdoc with Swagger version 2.1.9.
Therefore the Annotations must be rewritten and I cant find the equivalent Annotations for the old Swagger Annotations.
I have this API Controller:
#GetMapping
#ApiOperation(value = "Load Building")
#ApiResponses(value = {
#ApiResponse(code = 200, message = "OK", response = Building.class, responseContainer = "Page")
})
public ResponseEntity<Page<Building>> getBuilding(Pageable building) {
final Page<Building> building = buildingrepo.findAll(page).map(bw -> mapper.map(bd, Building.class));
return ResponseEntity.ok().body(building);
With the new Swagger Annotation it must be re-written, but I don`t know how i put the "Building.class" into the Pageable in the Response Schema. I cant use "responseContainer" anymore
#GetMapping
#Operation(summary = "Load Building")
#ApiResponses(value = {
#ApiResponse(responseCode = "200",
description = "OK",
content = #Content(schema = #Schema(implementation = Building.class))) // <--- Here i need the Page class somehow as Container!!!
})
public ResponseEntity<Page<Building>> getBuilding(Pageable building) {
final Page<Building> building = buildingrepo.findAll(page).map(bw -> mapper.map(bd, Building.class));
return ResponseEntity.ok().body(building);
The Output Response in the Api Docs schould look like this:
responses:
200:
schema:
$ref: "#/definitions/Page<Building>"
And also in the Swagger UI as Example:
{
"content": [
{ Building: "" }
]
}
I cant find the right Parameter for the "responseContainer"
Swagger 2's equivalent to a responseContainer is to wrap the Schema in an ArraySchema. For an endpoint returning List<Foo> :
#ApiResponses(#ApiResponse(responseCode = "200", description = "List of Foos",
content = #Content(array = #ArraySchema(uniqueItems = false,
schema = #Schema(implementation = com.mycompany.Foo.class))
)))
Note uniqueItems is false by default so can be omitted above. However, explicitly set this value to true if you're returning a Set instead of a List.
References:
https://docs.swagger.io/swagger-core/v2.1.1/apidocs/io/swagger/v3/oas/annotations/media/ArraySchema.html

How to create multiple schema in #RequestBody of swagger openapi specification 3.0 using springdoc?

I have the below api for which I need to have two parameters of content type application/x-www-form-urlencoded and therefore am using #RequestBody instead of #Parameter
#Operation(summary = "Revoke given permissions", description = "Allows admin to revoke permissions to users")
#RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void revokePermission(
#RequestBody(description = "the permission id", content = #Content(mediaType = "application/x-www-form-urlencoded",
schema = { #Schema(type = "String", name = "permission_id",
description = "id of the permission to be revoked", required = true)},
{ #Schema(type = "String", name = "permission_type",
description = "the permission type")}))
String permission_id, String permissionType) {
do_something();
}
I need the swagger.json to be like below example, but I do not know how to generate it using springdoc .I tried #ArraySchema also , but I am not getting the output I need. I am making some mistakes in the syntax and not able to find examples online.
"requestBody": {
"content": {
"application/x-www-form-urlencoded": {
"schema": {
"properties": {
"permission_id": {
"description": "id of the permission to be revoked",
"type": "string"
},
"permission_type": {
"description": "the permission type",
"type": "string"
}
},
"required": ["permission_id"]
}
}
}
}
Any help is highly appreciated. TIA
The The simplest way to achieve what you want is to define the permission data in simple object as follow:
#Schema(name = "permissionData")
public class PermissionData {
#Schema(type = "String", name = "permiddionId", description = "id of the permission to be revoked", required = true)
#JsonProperty("permiddionId")
String permiddionId;
#Schema(type = "String", name = "permissionType",description = "the permission type")
#JsonProperty("permissionType")
String permissionType;
}
And then you controller method:
#Operation(summary = "Revoke given permissions", description = "Allows admin to revoke permissions to users")
#RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public void revokePermission(#RequestBody(description = "the permission data") PermissionData permissionData) {
}

#ApiResponses and #ApiResponses in swagger

I have annotated my method like,
#ApiOperation( value = "Get time spent on category", response = CategoryBean.class, responseContainer = "List", notes = "API to get the time spent on all tasks based on category" )
#ApiImplicitParams( {
#ApiImplicitParam( name = "x-auth-token", value = "", dataType = "string", required = true, paramType = "header" ) } )
#ApiResponses( value = {
#ApiResponse( code = 200, message = "Success", response = CategoryBean.class, responseContainer = "List" ) } )
#RequestMapping( value = "/getTimeSpentOnCategory", method = RequestMethod.POST )
public ResponseEntity<?> getTimeSpentOnCategory( #RequestBody DashboardTaskRequestBean bean )
{/**some operation**/}
But in my swagger UI, I'am not able to get the Status code 200 and its message. Please explain why?
The following picture is the snapshot of the UI,
This is a known issue and looks like it is fixed with version 3.0.
As I see it, you are able to see the response structure at the top, but it is not visible in the table at the bottom of the screenshot.
This is also raised here and is fixed with version 3.0 :
https://github.com/swagger-api/swagger-ui/issues/1505
https://github.com/swagger-api/swagger-ui/issues/1297

Swagger spring fox do not handle Response Model for List and arrays

I'm trying to expose an api with spring mvc and documenting it with swagger.
#RequestMapping(value="/entry/", method=RequestMethod.GET)
#ApiOperation(value = "Retrieves all diary entries persisted in the database",produces = "application/json" ,responseContainer = "List", response = Entry.class)
public List<Entry> getDiaryEntries() {
List<Entry> diaryEntries =new ArrayList<>();
diaryEntries.add(new Entry());
return diaryEntries;
}
when I look at the swagger ui
[
the array content looks undefined altho I specified responseContainer = "List", response = Entry.class.
I would expect something like
[{ "title" : "" , "text":"" } ]

Integrating swagger-maven-plugin into Spring application

I'm getting hard time trying to incorporate Swagger into my Spring application. I'm trying to just generate .json file using com.github.kongchen:swagger-maven-plugin:3.1.0 and io.swagger:swagger-core:1.5.0 for annotations, but generated file is totally empty:
{
"swagger" : "2.0",
"info" : {
"version" : "v1",
"title" : "KVS"
}
}
controller example
#RestController
#Api(
tags = { "k/v" },
value = "Main microservice entrypoint",
produces = "application/json",
consumes = "application/json",
protocols = "http,https"
)
class AbcController {
#ApiOperation(value = "/")
#ApiResponses({
#ApiResponse(code = 200, message = "Request entry", response = KvsEntry.class),
#ApiResponse(code = 404, message = "Entry not found", response = Void.class)
})
#RequestMapping(value = "/", method = RequestMethod.POST)
public ResponseEntity<KvsEntry> create(#Validated #RequestBody KvsEntry kvsEntry) {
kvsEntry = keyValueService.saveEntry(kvsEntry);
return new ResponseEntity<>(kvsEntry, HttpStatus.OK);
}
}
I still can get some results using <springmvc>false</springmvc> configuration and JAX-RS annotations (not quite correct, i'd say), but that would be quite counterproductive. What may i be doing wrong?
Please check simple sample of working plugin with Spring MVC annotations on this repo:
https://github.com/khipis/swagger-maven-example
Plugin is sensitive on dependencies versions and presence or not of specific annotations.

Resources