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

Image of Docusign

Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

AWS Security LIVE!

Tune in for AWS Security LIVE!

Join AWS Security LIVE! for expert insights and actionable tips to protect your organization and keep security teams prepared.

Learn More

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

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

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay