I'm trying to migrate our manually writen OpenAPI (swagger) to a generated OpenAPI using springdoc-openapi for our Spring-Boot application. We got some issues, because the controller responses (mostly ErrorCodes) didn't match to the documentatation.
We already used a @ControllerAdvice annotated handler configuration. Here a snippet:
@ControllerAdvice
public class ExceptionHandler {
@ResponseStatus(code = HttpStatus.NOT_FOUND)
@ApiResponse(responseCode = "404", description = "(NOT FOUND) Resource does not exist!", content = @Content)
@ExceptionHandler(NotFoundException.class)
public void handleException(NotFoundException e) {
log.warn("Returning {} due to a NotFoundException: {}", HttpStatus.NOT_FOUND, e.toString());
}
@ResponseStatus(value = HttpStatus.BAD_REQUEST)
@ApiResponse(responseCode = "400", description = "(BAD REQUEST) Given resource is invalid!", content = @Content)
@ExceptionHandler(InvalidResourceException.class)
public void handleException(InvalidResourceExceptione) {
log.error("Invalid resource: {}", e.toString());
}
The generated API now showed all defined ApiResponses as responses for all controllers and endpoints. So I splittet the handler config using @ControllerAdvice(basePackageClasses = MyController.class) to group the possible exceptions. But there are still responses that are not fitting to all endpoints of a controller. Like:
@RestController
public class MyController {
@ResponseStatus(HttpStatus.CREATED)
@Operation(summary = "Create", description = "Create myResource!")
@PostMapping(value = "/myResources/", produces = {"application/json"})
@ResponseBody
public Integer create(@RequestBody MyResource newResource) throws InvalidResourceException {
return creationService.createResource(newResource).getId();
}
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "Update", description = "Update myResource!")
@PutMapping(value = "/myResources/{id}", produces = {"application/json"})
public void update(@PathVariable("id") Integer id, @RequestBody MyResource newResource)
throws ResourceNotFoundException, InvalidResourceException {
return updateService.updateResource(id, newResource);
}
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "Get", description = "Get myResource!")
@GetMapping(value = "/myResources/{id}", produces = {"application/json"})
@ResponseBody
public MyResource get(@PathVariable("id") Integer id) throws ResourceNotFoundException {
return loadingService.getResource(id);
}
}
POST will never respond with my 'business' 404 and GET will never respond with my 'business' 400. Is it possible to annotate an endpoint, so that not possible response codes are hidden in the API?
I tried to override the responses, but didn't work as intended:
@ResponseStatus(HttpStatus.OK)
@Operation(summary = "Get", description = "Get myResource!")
@ApiResponses({@ApiResponse(responseCode = "200", description = "(OK) Returning myResource"),
@ApiResponse(responseCode = "404", description = "(NOT FOUND) Resource does not exist!")})
@GetMapping(value = "/myResources/{id}", produces = {"application/json"})
@ResponseBody
public MyResource get(@PathVariable("id") Integer id) throws ResourceNotFoundException {
return loadingService.getResource(id);
}
400 still shows up...