#ApiResponses and #ApiResponses in swagger - spring-boot

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

Related

Swagger SpringDoc: Expanding endpoint freezes browser tab

I have a single-endpoint Spring service that takes a large/complex XML input, and
returns a similarly formatted output. It is defined like so:
#Operation(summary = "Sample Request", operationId = " sampleReq", description = " Data Structure Response", responses = {
#ApiResponse(responseCode = "200", description = "Data Structure response with calculations ") })
#PostMapping(consumes = { MediaType.APPLICATION_XML_VALUE }, produces = { MediaType.APPLICATION_XML_VALUE })
public ResponseEntity<ComplexStructure> calculate(#RequestBody ComplexStructure request) {
// ...
}
When I have it set up like this, loading the webpage causes it to hang after expanding the POST operation.
What I'd like to do is simply remove the (what I assume is breaking it) schema generation. For example, I'm fine if it looks like this: To achieve this example, I replaced ComplexStructure with String, but I'd rather not do that.

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

Optional query string enum parameter - openapi, springboot

I have an OpenApi spec:
paths:
/lessons:
get:
tags:
- lesson
operationId: getLessons
parameters:
- in: query
name: daysOfWeek
schema:
type: array
items:
$ref: '#/components/schemas/DaysOfWeekEnum'
Using swagger codegen this generates an endpoint like:
#ApiOperation(value = "Get a collection lessons", nickname = "getLessons", notes = "", response = LessonDto.class, responseContainer = "List", tags={ "lesson", })
#ApiResponses(value = {
#ApiResponse(code = 200, message = "List of Lessons", response = LessonDto.class, responseContainer = "List") })
#RequestMapping(value = "/lessons",
produces = { "application/json" },
method = RequestMethod.GET)
default ResponseEntity<List<LessonDto>> _getLessons(#ApiParam(removed for brevity) #Valid #RequestParam(value = "daysOfWeek", required = false, defaultValue="new ArrayList<>()") List<DaysOfWeekEnum> daysOfWeek) {
return getLessons(daysOfWeek);
}
I use TestRestTemplate in a test like so:
ResponseEntity<List<LessonDto>> lessonDtos =
testRestTemplate.exchange("/lessons", HttpMethod.GET, null,
new ParameterizedTypeReference<List<LessonDto>>() {
});
This url works:
/lessons?daysOfWeek=THURSDAY
These urls do not:
/lessons
/lessons?daysOfWeek=SOME_INVALID_VALUE
...and I get the following error:
nested exception is
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot
deserialize instance of java.util.ArrayList out of START_OBJECT
token
Any help appreciated.
In order to give you an empty list, you need to set the default value to be as an empty string:
#RequestParam(value = "daysOfWeek",
required = false,
defaultValue = "") List<DaysOfWeekEnum> daysOfWeek)
So the issue was related to an openapi-generator bug. Summary being:
When parameters of type array are added to an operation, the generated
Spring code includes an invalid defaultValue in the Spring MVC
parameter annotations
The fix was to upgrade to a later version of openapi-generator - 4.0.0 did the trick for me.
As an aside, the error message:
exception is
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot
deserialize instance of java.util.ArrayList out of START_OBJECT token
..was a bit of a red herring and it was actually TestRestTemplate related i.e. the ParameterizedTypeReference part. Changing this to String.class identified the true nature of the error.

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