Building a RESTful Web Service :: Learn how to create a RESTful web service with Spring. :: spring-boot http://spring.io/guides/gs/rest-service/

Getting Started: Building a RESTful Web Service

What you'll build

This guide will take you through creating a "hello world" RESTful web service with Spring—literally, we'll build a service that accepts an HTTP GET request:

$ curl http://localhost:8080/hello-world

and responds with the following JSON:

{"id":1,"content":"Hello, World!"}

What you'll need

  • About 15 minutes
  • A favorite text editor or IDE
  • JDK 7 or later
  • Your choice of Maven (3.0+) or Gradle (1.5+)

[macro:how-to-complete-this-guide]

Set up the project

[macro:build-system-intro]

Create a Maven POM

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.springframework</groupId>
    <artifactId>gs-rest-service</artifactId>
    <version>1.0</version>

    <parent>
        <groupId>org.springframework.bootstrap</groupId>
        <artifactId>spring-bootstrap-starters</artifactId>
        <version>0.5.0.BUILD-SNAPSHOT</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.bootstrap</groupId>
            <artifactId>spring-bootstrap-web-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
    </dependencies>

    <!-- TODO: remove once bootstrap goes GA -->
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <url>http://repo.springsource.org/snapshot</url>
            <snapshots><enabled>true</enabled></snapshots>
        </repository>
    </repositories>
    <pluginRepositories>
        <pluginRepository>
            <id>spring-snapshots</id>
            <url>http://repo.springsource.org/snapshot</url>
            <snapshots><enabled>true</enabled></snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

[macro:bootstrap-starter-pom-disclaimer]

Create a Gradle build script

build.gradle

TODO: paste complete build.gradle.
compile "org.springframework.bootstrap:spring-bootstrap-web-starter:0.0.1-SNAPSHOT"
compile "com.fasterxml.jackson.core:jackson-databind:2.2.0-"

Create a configuration class

The first step is to set up a simple Spring configuration class. It'll look like this:

src/main/java/hello/HelloWorldConfiguration.java

package hello;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan
public class HelloWorldConfiguration {
}

This class is concise, but there's plenty going on under the hood. @EnableWebMvc handles the registration of a number of components that enable Spring's support for annotation-based controllers—you'll build one of those in an upcoming step. And we've also annotated the configuration class with @ComponentScan which tells Spring to scan the hello package for those controllers (along with any other annotated component classes).

Create a resource representation class

With the essential Spring MVC configuration out of the way, it's time to get to the nuts and bolts of our REST service by creating a resource representation class and an endpoint controller.

Before we get too carried away with building the endpoint controller, we need to give some thought to what our API will look like.

What we want is to handle GET requests for /hello-world, optionally with a name query parameter. In response to such a request, we'd like to send back JSON, representing a greeting, that looks something like this:

{
    "id": 1,
    "content": "Hello, World!"
}

The id field is a unique identifier for the greeting, and content is the textual representation of the greeting.

To model the greeting representation, create a representation class:

src/main/java/hello/Greeting.java

package hello;

public class Greeting {

    private final long id;
    private final String content;

    public Greeting(long id, String content) {
        this.id = id;
        this.content = content;
    }

    public long getId() {
        return id;
    }

    public String getContent() {
        return content;
    }
}

Now that we've got our representation class, let's create the endpoint controller that will serve it.

Create a resource controller

In Spring, REST endpoints are just Spring MVC controllers. The following Spring MVC controller handles a GET request for /hello-world and returns our Greeting resource:

src/main/java/hello/HelloWorldController.java

package hello;
import java.util.concurrent.atomic.AtomicLong;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/hello-world")
public class HelloWorldController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

    @RequestMapping(method=RequestMethod.GET)
    public @ResponseBody Greeting sayHello(
            @RequestParam(value="name", required=false, defaultValue="World") String name) {
        return new Greeting(counter.incrementAndGet(), String.format(template, name));
    }
}

The key difference between a human-facing controller and a REST endpoint controller is in how the response is created. Rather than rely on a view (such as a JSP) to render model data in HTML, an endpoint controller simply returns the data to be written directly to the body of the response.

The magic is in the @ResponseBody annotation. @ResponseBody tells Spring MVC to not render a model into a view, but rather to write the returned object into the response body. It does this by using one of Spring's message converters. Because Jackson 2 is on the classpath, Spring's MappingJackson2HttpMessageConverter is automatically chosen to convert the Greeting instance to JSON.

Create an executable main class

We can launch the application from a custom main class, or we can do that directly from one of the configuration classes. The easiest way is to use the SpringApplication helper class:

src/main/java/hello/HelloWorldConfiguration.java

package hello;

import org.springframework.bootstrap.SpringApplication;
import org.springframework.bootstrap.context.annotation.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableAutoConfiguration
@EnableWebMvc
@ComponentScan
public class HelloWorldConfiguration {
    public static void main(String[] args) {
        SpringApplication.run(HelloWorldConfiguration.class, args);
    }
}

The @EnableAutoConfiguration annotation has also been added: it provides a load of defaults (like the embedded servlet container) depending on the contents of your classpath, and other things.

Build an executable JAR

Add the following to your pom.xml file (keeping any existing properties or plugins intact):

pom.xml

<properties>
    <start-class>hello.HelloWorldConfiguration</start-class>
</properties>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-shade-plugin</artifactId>
        </plugin>
    </plugins>
</build>

TODO: gradle syntax

The following will produce a single executable JAR file containing all necessary dependency classes:

$ mvn package

$ gradle build

Run the service

Now you can run it from the jar as well, and distribute that as an executable artifact:

$ java -jar target/gs-rest-service-1.0.jar

Test the service

Once the service starts, you can test it by pointing your web browser at http://localhost:8080/hello-world. Or you can consume it from the command line using curl:

$ curl http://localhost:8080/hello-world

Either way, the response should look like this:

{"id":1,"content":"Hello, World!"}

Now try providing a name query string parameter: http://localhost:8080/hello-world?name=User

$ curl http://localhost:8080/hello-world?name=User

And notice how the content changes:

{"id":1,"content":"Hello, User"}

Congratulations! You have just developed a simple RESTful service using Spring. This is a basic foundation for building a complete REST API in Spring.