6

I want to respond with different result objects in a Swagger generated API. The type of object is dependent on the result code. But it seems that the Swagger codegen generates only code that allows the first defined/used type to be returned.

An example Swagger definition that returns different objects in the OK and error case is like:

swagger: "2.0"
info:
  description: "API"
  version: 1.0.0
  title: Example
host: localhost:8080

schemes:
  - http

paths:
  /exampleCall:
    get:
      operationId: exampleCall
      produces:
        -  application/json
      responses:
        200:
          description: OK
          schema:
            $ref: '#/definitions/exampleResponse'
        400:
          description: Error
          schema:
            $ref: '#/definitions/exampleError'
definitions:
  exampleResponse:
    type: object
    properties:
      result:
        type: string
  exampleError:
    type: object
    properties:
      code:
        type: string

This then gets generated by the SwaggerCodeGen into following API interface

@Validated
@Api(value = "exampleCall", description = "the exampleCall API")
@RequestMapping(value = "")
public interface ExampleCallApi {

    ExampleCallApiDelegate getDelegate();

    @ApiOperation(value = "", nickname = "exampleCall", notes = "", response = ExampleResponse.class, tags={  })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "OK", response = ExampleResponse.class),
        @ApiResponse(code = 400, message = "Error", response = ExampleError.class) })
    @RequestMapping(value = "/exampleCall",
        produces = { "application/json" }, 
        method = RequestMethod.GET)
    default ResponseEntity<ExampleResponse> exampleCall() {
        return getDelegate().exampleCall();
    }
}

But when I try to implement the delegate like this

public class ExampleCallApiDelegateImpl implements ExampleCallApiDelegate {

    @Override
    public ResponseEntity<ExampleResponse> exampleCall() {
        ExampleError error = new ExampleError();
        error.setCode("123");
        return new ResponseEntity<ExampleError>(error, HttpStatus.BAD_REQUEST);
    }
}

it of course fails to compile because of incorrect return types.

What would be the proper way to implement different return objects per response code with that Swagger generated API? Is there even a proper way?

Kosi2801
  • 22,222
  • 13
  • 38
  • 45

1 Answers1

0

According to Swagger official documentation:

Swagger is a set of open-source tools built around the OpenAPI Specification that can help you design, build, document and consume REST APIs.

Representational state transfert architectural style enforce a set of several constraints. One of them is having a uniform interface, which itself involve several other constraints, especialy resource manipulation through representations of effective server data.

The way Swagger is built is to enforce at best thoses constraints for building REST APIs, it would violate REST principles if the API would return a representation of another resource if the original request was to create, read, modify or suppress a ressource from the original server.

There is therfore no proper way to return different objects for different response codes in Swagger-generated REST API.

v-g
  • 338
  • 4
  • From my understanding this is untrue. The swagger definition I gave as example is perfectly valid and validates also as such in the editor. This means from the standard it is legal and allowed to return different objects with different codes, it's just not allowed to switch responses for the same code. It also makes sense to return an error-object in an error scenario. This works ok with dynamic languages, my issue is that with the statically compiled Java language the generated structure does not allow to fulfil the promises of the REST API without bending over backwards. – Kosi2801 Jun 16 '23 at 07:55