JavaData & JavaExploring REST APIs with Spring MVC

Exploring REST APIs with Spring MVC

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Web-based application development is a common part of Java development. It is part and parcel of the enterprise domain wherein they share many common attributes of building a production-ready application. Spring uniquely addresses the concern for building a Web application through its MVC framework. It is called MVC because it is based upon the MVC (Model-View-Controller) pattern. Refer to Wikipedia: Model-view-controller for quick information about this. Web applications, in most cases, have a REST counterpart for resource sharing. This article builds up on both the idea and ends with a quick example to describe them in a terse manner.

Spring MVC

A Web application is inherently multi-layered because the intricacies between the user request and server response go through several in-between stages of information processing. Each stage is handled by a layer. For example, the Web interaction begins with user interaction with the browser, such as by triggering a request and getting a response from the server. The request response paradigm is nothing more than an exchange of certain arranged data, which can be anywhere from trivial to heavily loaded information gathered from, for example, a form submitted by the user. The URL encapsulates the request from the user and flutters into the network oblivion. Voilà! It is returned back with the digital PIZZA you have requested onto the platter called a browser. The request actually goes through a bunch of agents under the purview of the Spring MVC framework. Each of these agents performs specific functions, technically called request processing, before actually responding back to the requester. Here is an illustration to give you an idea.

The Spring framework
Figure 1: The Spring framework

  1. The journey begins with the HTTP request (sometimes with data payload; for example, due to form submission) in a URL. It first stations at DispatcherServlet. The DispatcherServlet is a class defined in the org.springframework.web.servlet package. It is the central dispatcher, a Java Servlet Component for the Spring MVC framework. This front controller receives all incoming HTTP client requests and delegates responsibilities to other components for further processing of the request payload.
  2. The handler mapping decides where the request’s next stop would be. It acts as a consultant to the central dispatcher (DispatcherServlet) for routing the request to the appropriate controller. The handler mapping parses the request URL to make decisions and the dispatcher then delegates the request to the controller.
  3. The controller‘s responsibility is to process the information payload received from the request. Typically, a controller is associated with one or more business service classes which, in turn, may have associated database services repository classes. The repository classes fetch database information according to the business service logic. It is the business service classes that contain the crux of processing. The controller class simply carries the information received from one or more service classes to the user. However, the response of the controller classes is still raw data referred to as the model and may not be user friendly (with indentation, bullets, tables, images, look-and-feel, and so forth).
  4. Therefore, the controller packages the model data along with model and view name back again to the central dispatcher, DispatcherServlet.
  5. The view layer can be designed using any third-party framework such as Node.js, Angular, JSP, and so on. The controller is decoupled from the view by passing the view name to the DispatcherServlet and is least interested in it. The DispatcherServlet simply carries the logical name and consults with the view resolver to map the logical view name with the actual implementation.
  6. Once the mapping between logical view name and the actual view implementation is made, the DispatcherServlet delegates the responsibility of rendering model data to the view implementation.
  7. The view implementation finally carries the response back to the client browser.

REST

REST is the acronym of Representational State Transfer. It is a term coined in Roy Thomas Fielding’s doctoral thesis where REST is a part that encompasses the architecture of transferring the state of resources. The REST architecture is made popular as an alternative to a SOAP implementation of Web services. Although REST has a much wider connotation than just Web services, here we’ll limit our discussion to dealing with REST resources only. The idea Web services are basically resource sharing in the Web architecture that forms the cornerstone of distributed machine-to-machine communication. The Spring MVC framework resides pretty well with REST and provides the necessary API support to implement it seamlessly, with little effort.

The URL and HTTP Methods

The REST resources are located on a remote host using URL. The idea is based on the foundation of the protocol called HTTP. For example, the URL http://www.payroll.com/employees may mean a list of employees to search and http://www.payroll.com/employees/101 may mean the detail of an employee with, say, ID 101. Hence, the URL/URI actually represents the actual location of a resource on the Web. The resource may be anything a Web page, an image, audio, video content, or the like. The HTTP protocol specifies several methods. If they are combined with the URL that points to the resource, we can get the following CRUD results as outlined below.

URL Method Outcome
http://www.payroll.com/employees POST Creates a list of employees
http://www.payroll.com/employees PUT or PATCH Updates a list of employees
http://www.payroll.com/employees DELETE Deletes a list of employees
http://www.payroll.com/employees GET Gets a list of employees
http://www.payroll.com/employees/101 POST Creates a employee with ID 101
http://www.payroll.com/employees/101 PUT or PATCH Updates employee with ID 101
http://www.payroll.com/employees/101 DELETE Deletes employee with ID 101
http://www.payroll.com/employees/101 GET Gets employee details with ID 101

Though the URL is associated with HTTP methods in REST, there are no strict rules to adhere to the outcome described above. The point is that RESTful URL structure should be able to locate a resource on the server. For instance, the PUT instruction can be used to create a new resource and POST can be used to update a resource.

REST in Spring

The REST API support was introduced in Spring from version 3.0 onwards; since then, it has steadily evolved to the present day. We can create REST resources in the following ways:

  • Using controllers which are used to handle HTTP requests such as GET, POST, PUT, and so forth. The PATCH command is supported by Spring 3.2 and higher versions.
  • Using the @PathVariable annotation. This annotation is used to handle parameterized URLs. This is usually associated with the @RequestMapping handler method in a Servlet environment.
  • There are multiple ways to represent a REST resource using Spring views and view resolvers with rendering model data as XML, JSON, Atom, and RSS.
  • The type of model data view suits the client can be resolved via ContentNegotiatingViewResolver. The ContentNegotiatingViewResolver, however, does not resolve views itself but delegates to other ViewResolvers. By default, these other view resolvers are picked up automatically from the application context, though they can also be set explicitly by using the viewResolver property.
  • Consuming REST resources using RestTemplate.

A Quick Example: Creating a Simple REST Endpoint

When working with REST services with Spring, we either publish application data as a REST service or access data in the application from third-party REST services. Here in this sample application, we combine Spring MVC to work with a REST endpoint in a controller named EmployeeController.

Firstly, we create a model class named Employee. This may be designated with JPA annotation to persist in the backend database. But, to keep it simple, we’ll not use JPA; instead, we’ll supply dummy data through the EmployeeService class. In a real situation, data is fetched from the backend database server and the data access methods are defined in a repository class. To give a hint, in our case, if we had used JPA with a back-end database, it may have been an interface that extends CrudRepository, something like this.

public interface EmployeeRepository extends
      CrudRepository<Employee, String>{
   // ...
}

Employee.java

package com.mano.spring_mvc_rest_example.spring_mvc_rest.employee;
public class Employee {
   private String id;
   private String name;
   private String address;
   public Employee() {
   }
   public Employee(String id, String name, String address) {
      this.id = id;
      this.name = name;
      this.address = address;
   }
   public String getId() {
      return id;
   }
   public void setId(String id) {
      this.id = id;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getAddress() {
      return address;
   }
   public void setAddress(String address) {
      this.address = address;
   }
}

EmployeeService.java

package com.mano.spring_mvc_rest_example.spring_
   mvc_rest.employee;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class EmployeeService {
   List<Employee> employeeList= Arrays.asList(
      new Employee("spiderman","Peter Parker",
         "New York"),
      new Employee("batman","Bruce Wayne",
         "Gotham City"),
      new Employee("superman","Clark Kent",
         "Metropolis"),
      new Employee("blackpanther","T'Challa",
         "Wakanda"),
      new Employee("ironman","Tony Stark",
         "New York")
   );
   public List<Employee> getEmployees(){
      return employeeList;
   }
   public Employee getEmployee(String id){
      return employeeList.stream().filter(e->e.getId()
         .equals(id)).findFirst().get();
   }
   public void addEmployee(Employee employee){
   }
   public void updateEmployee(Employee employee, String id){
      for(int i=0;i<employeeList.size();i++){
         Employee e=employeeList.get(i);
         if(e.getId().equals(id)) {
            employeeList.set(i, employee);
            break;
         }
      }
   }
   public void deleteEmployee(String id){
      employeeList.removeIf(e->e.getId().equals(id));
   }
}

EmployeeController.java

package com.mano.spring_mvc_rest_example.spring_mvc_rest.employee;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
public class EmployeeController {
   @Autowired
   private EmployeeService employeeService;
   @RequestMapping("/employees")
   public List<Employee> getEmployees(){
      return employeeService.getEmployees();
   }
   @RequestMapping("/employees/{empid}")
   public Employee getEmployee(@PathVariable("empid")
         String id){
      return employeeService.getEmployee(id);
   }
   @RequestMapping(method= RequestMethod.POST,
      value="/employees")
   public void addEmployee(@RequestBody Employee employee){
      employeeService.addEmployee(employee);
   }
   @RequestMapping(method = RequestMethod.PUT,
      value="/employees/{id}")
   public void updateEmployee(@RequestBody Employee employee,
         @PathVariable String id){
      employeeService.updateEmployee(employee, id);
   }
   @RequestMapping(method = RequestMethod.DELETE,
      value="/employees/{id}")
   public void deleteEmployee(@PathVariable String id){
      employeeService>.deleteEmployee(id);
   }
}

Observe that the Web controller class named EmployeeController is designated as a @RestController annotation. This is a convenience annotation that actually combines the @Controller and @ResponseBody annotations. The @Controller annotation designates a POJO as a Web controller and is a specialization of @Component. When we designate a POJO class with @Controller or @Component, or even a @RestController, Spring auto detects them by considering them as a candidate while class path scanning. The @ResponseBody annotation indicates that the method response value should be bound to the Web response body.

The valid URL requests for publishing REST resources for the above code are as follows:

Conclusion

For REST CRUD operations such as adding, updating, and deleting Employee, we need a HTTP client application that enables us to test Web services, such as postman; otherwise, we need to implement the view layer of the application with the help of JavaScript frameworks such as jQuery, AngularJS, and the like. To keep the write-up well within limits, we have not implemented them here. If possible, we’ll take them up in a separate write-up. By the way, we have only scratched the surface of Spring MVC and Spring REST support. Take this as a warm-up before the deep plunge you may want to take into the stream of Spring. As you swim across, you’ll find many interesting sight scenes. 🙂

References

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories