Search code examples
restweb-servicesspring-bootcontrollermedia-type

Controller return type and httpStatus best practice and production/consumption on method in REST WS


I commence in REST and I have some questions:

  • What type must the controller return? Typically, I'm asking if my Rest @Controller must return Item object as it is or encapsulate it in ResponseEntity in order to specify http-status-code.
  • What http status code to use in a GET method on a particular item ("/items/2") if the given item does not exists: HttpMediaStatus.OK(200) and null return or HttpStatus.NO_CONTENT(204) and null return ?

Second part: I saw it was possible to specify @Produces and @Consumes on WS method but what the use of that? My application and my methods work so, why specify MediaType.APPLICATION_JSON_VALUE? Doesn't Spring/SpringBoot automatically convert Item or ResponseEntity into json?

Context: using Spring Boot, hibernate, REST webservice.

Thank you.


Solution

  • Many questions in one, I'll provide short answers with a bunch of link to relevant articles and the reference documentation.

    What type must the controller return?

    Depends on your annotation and the RESTful-ness of your service. There are three annotations you can use for controllers: @Controller, @RestController and @RepositoryRestController.

    Controller is the base annotation to mark your class as a controller. The return type of the controller endpoint methods can be many things, I invite you to read this dedicated post to get a grasp of it. When developing a pure-REST service, you will focus on using RestController and RepositoryRestController. RestControlleris Controller + ResponseBody. It binds the return value of the endpoint method to the web response body:

    @RestController
    public ItemController {
    
        @RequestMapping("/items/{id}")
        public Item getItem(@PathVariable("id") String id) {
             Item item = ...
    
             return item;
        }
    
    }
    

    With this, when you hit http:/.../api/items/foo, Spring does its magic, automatically converting the item to a ResponseEntity with a relevant 40X status code and some default HTTP headers.

    At some point, you will need more control over the status code and headers, while still benefiting from Spring Data REST's settings. That's when you will use RepositoryRestController with a ResponseEntity<Item> as return type, see the example the Spring Data REST reference.

    What http status code to use in a GET method on a particular item if the given item does not exists?

    Bluntly said: use HttpStatus.NOT_FOUND. You're looking for a resource that does not exist, there's something wrong.

    That being said, it is completely up to you to decide how to handle missing resources in your project. If your workflow justifies it, a missing resource could be something completely acceptable that indeed returns a 20X response, though you may expect users of your API to get confused if you haven't warned them or provided some documentation (we are creatures of habits and conventions). But I'd still start with a 404 status code.

    (...) @Produces and @Consumes on WS method but what the use of that? My application and my methods work so, why specify MediaType.APPLICATION_JSON_VALUE? Doesn't Spring/SpringBoot automatically convert Item or ResponseEntity into json?

    @Consumes and @Produces are respectively matched against content-type and accept headers from the request. It's a mean of restricting the input accepted and the output provided by your endpoint method.

    Since we're talking about a REST service, communications between clients of the API and the service are expected to be JSON-formatted. Thanks to Spring HATEOAS, the answer are actually formatted with the application/hal+json content-type. In that scenario, you can indeed not bother with those two annotations. You will need them if you develop a service that accepts different content-types (application/text, application/json, application/xml...) and provides, for instance, HTML views to users of your website and JSON or XML response to automated clients of your service.

    For real life examples:

    • Facebook provides the Graph API for applications to read to/write from its graph, while users happily (?) surf on web pages
    • Google does the same with the Google Maps API