Swagger 3.0.0 - doesn't see schema for @RequestBody

Viewed 1575

I have springboot(2.11.RELEASE) webflux application written using kotlin ('1.3.50'). I would like to add swagger documentation. I added to my build.gradle:

compile group: 'io.springfox', name: 'springfox-boot-starter', version: '3.0.0'

my Rest controller looks like this:

@RestController
@RequestMapping("/path", produces = [MediaType.APPLICATION_JSON_VALUE])
@Validated
class CreditApplicationController @Autowired constructor(
    private val creditService: CreditService
) {
    @PostMapping(consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
    fun applyCredit(
        @Valid @RequestBody request: ApplyCreditRequest,
        @OperationId operationId: String
    ): Mono<ResponseEntity<ApplicationCreditResponse>> {
       ...

the ApplyCreditRequest is a simple kotlin data class

    @Validated
    data class ApplyCreditRequest(
        @get:JsonProperty("application_id", required = true)
        @NotBlank(message = "application_id cannot be empty")
        val applicationId: String,
    
        @get:JsonProperty("customer_info", required = true)
        @field:Valid
        val customerInfo: CustomerInfo,
    
        @get:JsonProperty("credit_details", required = true)
        @field:Valid
        val creditDetails: CreditDetails,
    
        @get:JsonProperty("agent", required = true)
        @Valid
        val agent: Agent
)

However when I go to the swagger generated page the request body is shown to be a string. How to make it show as a ApplyCreditRequest json I expect it to be ? enter image description here

UPDATE:

Updated to:

@PostMapping(consumes = [MediaType.APPLICATION_JSON_VALUE], produces = [MediaType.APPLICATION_JSON_VALUE])
     fun applyCredit(
            @io.swagger.v3.oas.annotations.parameters.RequestBody(
                content = [
                    Content(
                        schema = Schema(
                            implementation = ApplyCreditRequest::class
                        )
                    )
                ]
            ) @Valid @RequestBody request: ApplyCreditRequest,
            @OperationId operationId: String
        ): Mono<ResponseEntity<ApplicationCreditResponse>> {

and still doesn't work

3 Answers

In general, you can add an @ApiModel annotation to the object that you will pass in the request.

(You can also annotate the object's properties, using the @ApiModelProperty annotation.)

An example in Java would look something like this:

// TopicContoller.java
// The POST operation accepts a 'Topic' object in the request body, and returns the same object

@RestController
public class TopicContoller {

// Other detail omitted...

    @ApiOperation(
            value = "Add a topic",
            notes = "Adds a new topic.",
            response = Topic.class)
    
    @RequestMapping(method = RequestMethod.POST,value = "/topics")
    public Topic addTopic(@RequestBody Topic topic) {
        topicService.addTopic(topic);
        return topic;
    }

}

// Topic.java 
// The 'Topic' object

@ApiModel(description = "An object that represents a given topic.")
public class Topic {
    
    @ApiModelProperty(notes = "The Topic ID, as a unique String", example = "php")
    private String id;

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }

// Other detail omitted...

}

I had a similar problem with some of my request using the @RequestBody schema and some not, eventually I found the following in the swagger docs

Differences From OpenAPI 2.0

If you used OpenAPI 2.0 before, here is a summary of changes to help you get started with OpenAPI 3.0:

  • GET, DELETE and HEAD are no longer allowed to have request body because it does not have defined semantics as per RFC 7231.

It seems the basic @RequestMapping defaults to a get request.

Changing the Mapping to an explicit @PostMapping in my case got swagger to see the Schema in the request body.

... But that changes the semantics of the REST API, for me that was the lesser of the two evils.

I think you have included the wrong @RequestBody you should have used annotation provided by spring boot not spring fox.

Related