/gs-actuator-service

Building a RESTful Web Service with Spring Boot Actuator :: Learn how to create a RESTful Web service with Spring Boot Actuator.

Primary LanguageJava

Spring Boot Actuator is a sub-project of Spring Boot. It adds several production grade services to your application with little effort on your part. In this guide, you’ll build an application and then see how to add these services.

What you’ll build

This guide will take you through creating a "hello world" RESTful web service with Spring Boot Actuator. You’ll build a service that accepts an HTTP GET request:

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

It responds with the following JSON:

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

There are also many features added to your application out-of-the-box for managing the service in a production (or other) environment. The business functionality of the service you build is the same as in Building a RESTful Web Service. You don’t need to use that guide to take advantage of this one, although it might be interesting to compare the results.

Run the empty service

For starters, here’s an empty Spring MVC application.

src/main/java/hello/HelloWorldApplication.java

link:initial/src/main/java/hello/HelloWorldApplication.java[role=include]

The @SpringBootApplication annotation provides a load of defaults (like the embedded servlet container) depending on the contents of your classpath, and other things. It also turns on Spring MVC’s @EnableWebMvc annotation that activates web endpoints.

There aren’t any endpoints defined in this application, but there’s enough to launch things and see some of Actuator’s features. The SpringApplication.run() command knows how to launch the web application. All you need to do is run this command.

$ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar

You hardly written any code yet, so what’s happening? Wait for the server to start and go to another terminal to try it out:

$ curl localhost:8080
{"timestamp":1384788106983,"error":"Not Found","status":404,"message":""}

So the server is running, but you haven’t defined any business endpoints yet. Instead of a default container-generated HTML error response, you see a generic JSON response from the Actuator /error endpoint. You can see in the console logs from the server startup which endpoints are provided out of the box. Try a few out, for example

$ curl localhost:8080/actuator/health
{"status":"UP"}

You’re "UP", so that’s good.

Check out Spring Boot’s Actuator Project for more details.

Create a representation class

First, give some thought to what your API will look like.

You want to handle GET requests for /hello-world, optionally with a name query parameter. In response to such a request, you will 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

link:complete/src/main/java/hello/Greeting.java[role=include]

Now that you’ll create the endpoint controller that will serve the representation class.

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 the Greeting resource:

src/main/java/hello/HelloWorldController.java

link:complete/src/main/java/hello/HelloWorldController.java[role=include]

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 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 @ResponseBody annotation tells Spring MVC not to 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 in the classpath, this means that MappingJackson2HttpMessageConverter will handle the conversion of Greeting to JSON if the request’s Accept header specifies that JSON should be returned.

Note
How do you know Jackson 2 is on the classpath? Either run ` mvn dependency:tree` or ./gradlew dependencies and you’ll get a detailed tree of dependencies which shows Jackson 2.x. You can also see that it comes from /spring-boot-starter-json, itself imported by spring-boot-starter-web.

Create an executable main class

You 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/HelloWorldApplication.java

link:complete/src/main/java/hello/HelloWorldApplication.java[role=include]

In a conventional Spring MVC application, you would add @EnableWebMvc to turn on key behaviors including configuration of a DispatcherServlet. But Spring Boot turns on this annotation automatically when it detects spring-webmvc on your classpath. This sets you up to build a controller in an upcoming step.

The @SpringBootApplication also brings in a @ComponentScan, which tells Spring to scan the hello package for those controllers (along with any other annotated component classes).

... service comes up ...

Test it:

$ curl localhost:8080/hello-world
{"id":1,"content":"Hello, Stranger!"}

Switch to a different server port

Spring Boot Actuator defaults to run on port 8080. By adding an application.properties file, you can override that setting.

src/main/resources/application.properties

link:complete/src/main/resources/application.properties[role=include]

Run the server again:

$ ./gradlew clean build && java -jar build/libs/gs-actuator-service-0.1.0.jar

... service comes up on port 9000 ...

Test it:

$ curl localhost:8080/hello-world
curl: (52) Empty reply from server
$ curl localhost:9000/hello-world
{"id":1,"content":"Hello, Stranger!"}
$ curl localhost:9001/actuator/health
{"status":"UP"}

Test your application

In order to check if your application is functional you should write unit / integration tests of your application. Below you can find an example of such a test that checks:

  • if your controller is responsive

  • if your management endpoint is responsive

As you can see for tests we’re starting the application on a random port.

src/test/java/hello/HelloWorldApplicationTests.java

link:complete/src/test/java/hello/HelloWorldApplicationTests.java[role=include]

Summary

Congratulations! You have just developed a simple RESTful service using Spring. You added some useful built-in services thanks to Spring Boot Actuator.

See Also

The following guides may also be helpful: