Search code examples
javaspringswagger

Swagger code gen. Controller implementation


Hello) I`m using swagger code gen for implementing my rest api.

Here is openapi.yaml:

/events:
    post:
      tags:
        - events
      summary: sth
      operationId: eventsRequest
      description: sth
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                title: eventRequest
                type: object
                required:
                  - card
                  - status
                properties:
                  changeDate:
                    type: string
                  status:
                    type: string
                  card:
                    type: string

      responses:
        200:
          description: OK
        202:
          description: Not all were added
          content:
            application/json:
              schema:
                title: NotAllResponse
                type: array
                items:
                  title: eventResponse
                  type: object
                  required:
                    - card
                    - error
                  properties:
                    card:
                      type: string
                    error:
                      type: string

Here is Java code, which swagger generates:

@Api(value = "events", description = "sth")
public interface EventsApi {

    Logger log = LoggerFactory.getLogger(EventsApi.class);

    default Optional<ObjectMapper> getObjectMapper() {
        return Optional.empty();
    }

    default Optional<HttpServletRequest> getRequest() {
        return Optional.empty();
    }

    default Optional<String> getAcceptHeader() {
        return getRequest().map(r -> r.getHeader("Accept"));
    }

    @ApiResponses(value = {
            @ApiResponse(code = 200, message = "OK"),
            @ApiResponse(code = 202, message = "Not all were added", response = EventResponse.class, responseContainer = "List"),
    @RequestMapping(value = "/events",
            produces = {"application/json"},
            consumes = {"application/json"},
            method = RequestMethod.POST)
    default ResponseEntity<Void> eventsRequest(@ApiParam(value = "") @Valid @RequestBody List<EventsRequest> body
    ) {
        if (getObjectMapper().isPresent() && getAcceptHeader().isPresent()) {
        } else {
            log.warn("ObjectMapper or HttpServletRequest not configured in default CardsEventsApi interface so no example is generated");
        }
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);
    }

}

The problem: I need to return 200 code with no body and 202 code with EventResponse object as body.

@Controller
@Validated
public class EventsApiController implements EventsApi {

    private final EventsService eventsService;

    @Autowired
    public EventsApiController(EventsService eventsService) {
        this.eventsService = eventsService;
    }

    @Override
    public ResponseEntity<Void> eventsRequest(List<EventsRequest> requests) {
        Integer hello = eventsService.doSth(requests);
        return ResponseEntity.status(HttpStatus.OK).build();
    }
}

I`m implementing EventsApi and overriding eventsRequest method. But I have no ability to return 202 code with EventResponse body.

Is there any ways to do it?


Solution

  • This is a known defect in the Spring codegen.

    In your case I suggest as a workaround that you edit the swagger yml and move the 202 response to put it first.

    (You may need to leave the 200 first and simple move the content definition up to the 200. I’m not sure if codegen sorts internally first)

    The response type contains an array. Simply return an empty array on the 200.

    Any client code would be testing for 200/202 and ignoring the body on a 200 (which would contain “[]” rather than be blank) so it should be ok.