Building a RESTFul Service with Spring MVC

A RESTful service is a way to expose your data through a URL. Let's use spring mvc to implement a RESTFul webservice to retrieve a listing of agencies.

Detailed Video Notes

Getting started

SOAP based web service while still serve a purpose are bloated, hard to consume directly from the client side and are bound by a hard contract. REST services on the other hand have been a go to choice for developing services consumed by web applications due to the lightweight JSON responses and soft contract. What I mean by soft contract is, REST services aren’t bound to a WSDL but still have a contract in which you need to abide by or have a versioning strategy in place. Using spring boot as a foundation lets build a simple REST web service.

What we will build

[0:37]

While not overly exciting lots of folks are familiar with insurance, agencies sell policies to policyholders. Lets say we want to get all the possible agencies we can purchase a policy from. We will make a request to http://localhost:8080/agencies which should return the following:

[
   {
      "id":1,
      "name":"All State",
      "ein":"123"
   },
   {
      "id":2,
      "name":"FCCI Insurance Group",
      "ein":"456"
   },
   {
      "id":3,
      "name":"Farmers",
      "ein":"789"
   },
   {
      "id":4,
      "name":"Met life",
      "ein":"167"
   }
]

Project set up

[0:54]

We will use spring STS to create project from a new spring starter project. We will select web project which will include the necessary starter projects in our pom.xml

Create resource representation class

[1:4]

Depending on your philosophy of building services, you could return domain object from your business logic layer or create a class that represents the resource a client is requesting. In our case lets create an agency resource object that contains a small subset of an agency object.

public class AgencyResource {

    private Integer id;
    private String name;
    private String EIN;

    public AgencyResource(Integer id, String name, String eIN) {
        super();
        this.id = id;
        this.name = name;
        EIN = eIN;
    }

    //...
}

Create resource controller

[1:21]

Next, we need something to handle the request and direct it to a method for processing. Within spring, HTTP requests are handled by a controller. These components are identified by the @Controller annotation. The @RequestMapping annotation ensures that HTTP requests to /agencies are mapped to the getAgencies() method.

A key difference between a traditional MVC controller and the RESTful web service controller is the way that the HTTP response is created. Rather than delegating to the view layer we want the object data written directly to the HTTP response as JSON. To accomplish this, the @ResponseBody annotation on the getAgencies() method tells Spring MVC that it does not need to look for a view and the list of agencies can be returned directly to the response.

Before the java object can be sent to the response it needs to be converted to JSON. This is done by an HttpMessageConverter specifically Jackson’s MappingJackson2HttpMessageConverter that it picks up on the class path. If you are not familiar with jackson, jackson is a java library to marshal and unmarshal json.

@Controller
public class AgencyController {

    @RequestMapping("/agencies")
    @ResponseBody
    public List<AgencyResource> getAgencies() {

        List<AgencyResource> agencies = getListing();

        return agencies;

    }

    //...
}

Spring 4 introduced a @RestController which is a @Controller and a @ResponseBody in one which eliminates the need to specify @ResponseBody on each method. Notice below that the @Controller has been changed to @RestController and the @ResponseBody has been removed.

@RestController
public class AgencyController {

    @RequestMapping("/agencies")
    public List<AgencyResource> getAgencies() {

        List<AgencyResource> agencies = getListing();

        return agencies;

    }
    //..
}

Creating mock data

Before we get to running the application, we will create some sample data that we can send in the response.

//...

private List<AgencyResource> getListing() {

    List<AgencyResource> resources = new ArrayList<>();
    resources.add(new AgencyResource(1, "All State", "123"));
    resources.add(new AgencyResource(2, "FCCI Insurance Group", "456"));
    resources.add(new AgencyResource(3, "Farmers", "789"));
    resources.add(new AgencyResource(4, "Met life", "167"));

    return resources;
}

//...

Running the application

[2:51]

Running the application the default starter project was nice enough to create an Application.java class. Lets break down what is happening in spring.

The main() method defers to the SpringApplication helper class, providing Application.class as an argument to its run() method. This tells Spring to read the annotation metadata from the Application and to manage it as a component in the Spring application context. In other words it is used to bootstrap and launch the Spring application from a java main method. This might look a bit different than the traditional way to deploy to an application server.

The @ComponentScan annotation is used to look and locate other spring beans within the demo package. This directive ensures that Spring finds and registers the AgencyController as it is marked with a with @Controller annotation which is a type of @Component.

The @EnableAutoConfiguration annotation is class that enables spring boots convention over configuration which enables default behaviors by scanning the classpath. For example, as we noted above a java object will be marshalled to json by jackson. This is because spring boot found jackson in the class path. In addition, since the project depends on Spring MVC (spring-webmvc.jar), a Spring MVC DispatcherServlet is configured and registered for you through the DispatcherServletAutoConfiguration class.

Right clicking on the project and running the class will start the application in a tomcat container. Navigating to localhost:8080/agencies we will perform a GET and the list of agencies is returned.

Thanks for joining in today’s level up lunch, have a great day!