Get Started with Spring Boot REST Service

This is a quick tutorial on building a REST service using Spring Boot.

Create the Project

Head over to https://start.spring.io/.

Choose a version of Spring. For a real project you probably want a release version and not a SNAPSHOT.

Under Dependencies search for Web and select it.

That is the only dependency we will need.

Click Generate Project. This will generate a Maven project and download it as demo.zip.

Extract demo.zip.

Open Project in IntelliJ Community Edition

In IntelliJ choose Open and select the demo folder where the ZIP file was extracted. IntelliJ will automatically recognize it as a Maven project and open it.

Wait for all dependencies to be downloaded.

Expand demo->src->main->java->com.example.demo. You will notice the DemoApplication class. This is used to start the server. We will get back to this later.

Create a REST Controller

In the com.example.demo package create a class called GreetingController.

Annotate the class with @RestController.

@RestController
public class GreetingController {
}

Within this class create an inner class called Greeting like this.

@RestController
public class GreetingController {
    class Greeting {
        public String planet;
        public String message;

        public Greeting(String planet, String message) {
            this.planet = planet;
            this.message = message;
        }
    }
}

Now add a controller method called sayHello() like this.

@RestController
public class GreetingController {
    class Greeting {...}

    @RequestMapping("/hello")
    public Greeting sayHello() {
        return new Greeting("World", "Hello");
    }
}

make sure all the packages are imported correctly. They will be like this.

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

That’s it. We are done with coding.

Run Server and Test

Right click the DemoApplication class and choose Run DemoApplication.main().

Wait for the server to start.

From command line run:

curl http://localhost:8080/hello

Make sure that you see:

{"planet":"World","message":"Hello"}

Write an Asynchronous REST Method

In real life you should try to make your services reactive. We will now add an asynchronous method to the controller.

Add a method to the controller class like this.

@RequestMapping("/hello-async")
public CompletableFuture<Greeting> sayHelloLater() {
    return CompletableFuture.supplyAsync(
            () -> new Greeting("World", "Hello"));
}

Restart the server.

From command line run:

curl http://localhost:8080/hello-async

You should see the same result.

Enable Auto-reload

Internet is full of discussions on how to enable auto-reload Spring Boot classes. Spring’s own solution of using the spring-boot-devtools dependency doesn’t work well in IntelliJ (it works better in Eclipse) and additional steps are needed. In the end I found IntelliJ’s own hot reload works just fine for me. So let’s get started with that.

Hot reload of Java classes only works in debug mode. So first kill the server if it is running. Then right click the DemoApplication class and choose Debug DemoApplication.main().

Wait for the server to start.

Run the service using curl to make sure it’s working.

Change the Java code in some fashion. For example:

@RequestMapping("/hello")
public Greeting sayHello() {
    return new Greeting("Moon", "Hello");
}

From the menu choose Build -> Build project.

IntelliJ will do an incremental compilation (which should be pretty quick) and then offer to reload the classes.

Click Yes.

This time when you execute the service using curl you should see the changes.

Write Unit Test

Expand demo->src->test->java->com.example.demo. Locate DemoApplicationTests class where we will add test scripts.

Open DemoApplicationTests. Set its content as follows.

public class DemoApplicationTests {
    private GreetingController controller;
    private MockMvc mockMvc;

    @Before
    public void setUp() {
        controller = new GreetingController();
        mockMvc = MockMvcBuilders
                .standaloneSetup(controller)
                .build();
    }

    @Test
    public void shouldGreet() throws Exception {
        MvcResult result = mockMvc.perform(get("/hello-async"))
            .andReturn();

        mockMvc.perform(asyncDispatch(result))
            .andExpect(status().isOk())
            .andExpect(jsonPath("message").value("Hello"));
    }
}

Resolve all the package names. Here they are for reference:

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

Run Unit Test

Right click DemoApplicationTests and select Run DemoApplicationTests.main(). Make sure that the test passes.