The Controller

 The Controller




The @RestController is the central artifact in the entire web tier of the RESTful API. For the purpose of this post, the controller is modeling a simple REST resource – Foo:



@RestController
@RequestMapping(“/foos”)
class FooController {


@Autowired
private IFooService service;


@GetMapping
public List<Foo> findAll() {
return service.findAll();
}


@GetMapping(value = “/{id}”)
public Foo findById(@PathVariable(“id”) Long id) {
return RestPreconditions.checkFound(service.findById(id));
}


@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public Long create(@RequestBody Foo resource) {
Preconditions.checkNotNull(resource);
return service.create(resource);
}


@PutMapping(value = “/{id}”)
@ResponseStatus(HttpStatus.OK)
public void update(@PathVariable( “id” ) Long id, @RequestBody Foo resource) {
Preconditions.checkNotNull(resource);
RestPreconditions.checkNotNull(service.getById(resource.getId()));
service.update(resource);
}


@DeleteMapping(value = “/{id}”)
@ResponseStatus(HttpStatus.OK)
public void delete(@PathVariable(“id”) Long id) {
service.deleteById(id);
}
}

You may have noticed I’m using a straightforward, Guava-style RestPreconditions utility:


public class RestPreconditions {
    public static <T> T checkFound(T resource) {
        if (resource == null) {
            throw new MyResourceNotFoundException();

}

        return resource;
    }


The controller implementation is non-public – this is because it doesn’t need to be.

Usually, the controller is the last in the chain of dependencies. It receives HTTP requests from the Spring front controller (the DispatcherServlet) and simply delegates them forward to a service layer. If there’s no use case where the controller has to be injected or manipulated through a direct reference, then I prefer not to declare it as public.

The request mappings are straightforward. As with any controller, the actual value of the mapping, as well as the HTTP method, determine the target method for the request. @RequestBody will bind the parameters of the method to the body of the HTTP request, whereas @ResponseBody does the same for the response and return type.

The @RestController is a shorthand to include both the @ResponseBody and the @Controller annotations in our class.

They also ensure that the resource will be marshalled and unmarshalled using the correct HTTP converter. Content negotiation will take place to choose which one of the active converters will be used, based mostly on the Acceptheader, although other HTTP headers may be used to determine the representation as well. 



Post a Comment (0)
Previous Post Next Post