DEV Community

eidher
eidher

Posted on • Edited on

5 2

Spring MVC REST

Representational state transfer (REST) is an architectural style that describes best practices to expose web services over HTTP, emphasizing performance, scalability, simplicity, modifiability, visibility, portability, and reliability.

REST exposes resources through URIs using nouns (not verbs), supporting a limited set of operations (GET, PUT, POST, DELETE). Clients can request particular representations (HTML, XML, JSON, etc) that can link to other resources, and use Hypermedia as the Engine of Application State (HATEOAS). It uses a stateless architecture, headers, and status codes to communicate with clients.

Spring MVC provides REST support. The RequestMapping annotation is used to map web requests. The RequestMethod enumerators are: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS, and TRACE.

@RequestMapping(path="/accounts", method=RequestMethod.GET)
Enter fullscreen mode Exit fullscreen mode

Since Spring 4.3, instead of RequestMapping you can use these annotations:

  • @GetMapping: To fetch a resource
  • @PostMapping: To create a new resource
  • @PutMapping: To update entirely a resource
  • @DeleteMapping: To delete an existing resource
  • @PatchMapping: To update partially a resource

For HEAD, OPTIONS, and TRACE use RequestMethod enumerators.

    @GetMapping(value = "/accounts")
    public @ResponseBody List<Account> accountSummary() {
        return accountManager.getAllAccounts();
    }

    @GetMapping(value = "/accounts/{id}")
    public @ResponseBody Account accountDetails(@PathVariable int id) {
        return retrieveAccount(id);
    }
Enter fullscreen mode Exit fullscreen mode

HTTP GET returns data in the response body. The @ResponseBody annotation allows us to return a serialized object. If the class is annotated as a @RestController, there is no need for @ResponseBody on GET methods.

To have more control over the response (e.g, set headers and control content), you can use ResponseEntity:

    @GetMapping(value = "/accounts/{id}")
    public ResponseEntity<Account> accountDetails(@PathVariable long id) {
        Account account = accountService.getAccount(id);
        return ResponseEntity
                .ok()
                .header("Last-Modified", account.getLastUpdate())
                .body(account);
    }
Enter fullscreen mode Exit fullscreen mode

In the example above, the ResponseEntity is built calling the ok method, which returns the 200 status code (success). See HttpStatus documentation. You also can add the @ResponseStatus annotation over the method.

Similarly to @ResponseBody, the @RequestBody annotation allows us to convert automatically incoming data based on the content type of the request.

    @PostMapping(value = "/accounts")
    @ResponseStatus(HttpStatus.CREATED)
    public ResponseEntity<Void> createAccount(@RequestBody Account newAccount) {
        Account account = accountManager.save(newAccount);
        URI location = ServletUriComponentsBuilder.fromCurrentRequestUri().path("/{childId}")
                .buildAndExpand(account.getEntityId()).toUri();
        return ResponseEntity.created(location).build();
    }
Enter fullscreen mode Exit fullscreen mode

In the previous example, we are building the URI. To create a URI you can use ServletUriComponentsBuilder or UriComponentsBuilder (for hard-coded URLs).

Spring MVC provides a Spring REST Client called RestTemplate (Spring Framework 5 introduced a new HTTP client called WebClient. See Reactive Spring Applications). RestTemplate provides access to RESTful services and supports all the HTTP methods. See RestTemplate documentation

  • DELETE: delete method
  • GET: getForObject and getForEntity (for ResponseEntity) methods
  • HEAD: headForHeaders method
  • OPTIONS: optionsForAllow method
  • POST: postForLocation, postForObject and exchange (for RequestEntity) methods
  • PUT: put method
    @Test
    public void listAccounts() {
        RestTemplate restTemplate = new RestTemplate();
        String url = "http://localhost:8080/accounts";
        Account[] accounts = restTemplate.getForObject(url, Account[].class);
        assertNotNull(accounts);
    }
Enter fullscreen mode Exit fullscreen mode

Finally, Spring HATEOAS provides an API for generating links in MVC Controller responses. Use Link class and @EnableHypermediaSupport annotation.

@Controller
@EnableHypermediaSupport(type = { HypermediaType.HAL })
public class EmployeeController {

    @GetMapping(value = "/{employeeId}")
    public Employee getEmployeeById(@PathVariable long employeeId) {
        Employee employeeById = ControllerLinkBuilder.methodOn(EmployeeController.class).getEmployeeById(employeeId);
        Link selfLink = ControllerLinkBuilder.linkTo(employeeById).withSelfRel();
        Employee employee = employeeService.getEmployee(employeeId);
        employee.add(selfLink);
        return employee;
    }
}
Enter fullscreen mode Exit fullscreen mode

Speedy emails, satisfied customers

Postmark Image

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Engage with a sea of insights in this enlightening article, highly esteemed within the encouraging DEV Community. Programmers of every skill level are invited to participate and enrich our shared knowledge.

A simple "thank you" can uplift someone's spirits. Express your appreciation in the comments section!

On DEV, sharing knowledge smooths our journey and strengthens our community bonds. Found this useful? A brief thank you to the author can mean a lot.

Okay