:toc:
:gs-rest-service: link:/guides/gs/rest-service
:spring_version: current
:icons: font
:source-highlighter: prettify
:project_id: gs-actuator-service

https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#production-ready[Spring Boot Actuator]
is a subproject of Spring Boot. It adds several production grade services to your
application with little effort on your part. In this guide, you will build an application
and then see how to add these services.

== What You Will Build

This guide takes you through creating a "`Hello, world`" RESTful web service with Spring
Boot Actuator. You will build a service that accepts the following HTTP GET request:

====
[source,sh]
----
$ curl http://localhost:9000/hello-world
----
====

It responds with the following JSON:

====
[source,json]
----
{"id":1,"content":"Hello, World!"}
----
====

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

=== What You need

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/prereq_editor_jdk_buildtools.adoc[]

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/how_to_complete_this_guide.adoc[]

[[scratch]]
== Starting with Spring Initializr

You can use this https://start.spring.io/#!type=maven-project&groupId=com.example&artifactId=actuator-service&name=actuator-service&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.actuatorservice&dependencies=web,actuator[pre-initialized project] and click Generate to download a ZIP file. This project is configured to fit the examples in this tutorial.

To manually initialize the project:

. Navigate to https://start.spring.io.
This service pulls in all the dependencies you need for an application and does most of the setup for you.
. Choose either Gradle or Maven and the language you want to use. This guide assumes that you chose Java.
. Click *Dependencies* and select *Spring Web* and *Spring Boot Actuator*.
. Click *Generate*.
. Download the resulting ZIP file, which is an archive of a web application that is configured with your choices.

NOTE: If your IDE has the Spring Initializr integration, you can complete this process from your IDE.

NOTE: You can also fork the project from Github and open it in your IDE or other editor.

== Run the Empty Service

The Spring Initializr creates an empty application that you can use to get started. The
following shows the class created by the Spring Initializr:

====
[source,java,tabsize=2]
----
include::initial/src/main/java/com/example/actuatorservice/ActuatorServiceApplication.java[]
----
====

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, which activates web endpoints.

There are no endpoints defined in this application, but there is 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 the following command:

====
[source,bash,subs="attributes"]
----
$ ./gradlew clean build && java -jar build/libs/{project_id}-0.0.1-SNAPSHOT.jar
----
====

You have yet to write any code, so what is happening? To see the answer, wait for the
server to start, open another terminal, and try the following command (shown with its
output):

====
[source,bash]
----
$ curl localhost:8080
{"timestamp":1384788106983,"error":"Not Found","status":404,"message":""}
----
====

The output of the preceding command indicates that the server is running but that you have
not 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. You can try a few of those endpoints, including the `/health` endpoint. The
following example shows how to do so:

====
[source,bash]
----
$ curl localhost:8080/actuator/health
{"status":"UP"}
----
====

The status is `UP`, so the actuator service is running.

See Spring Boot's
https://github.com/spring-projects/spring-boot/tree/main/spring-boot-project/spring-boot-actuator[Actuator Project]
for more details.

[[initial]]
== Create a Representation Class

First, you need to 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 want to send back JSON, representing a
greeting, that looks something like the following:

====
[source,json]
----
{
    "id": 1,
    "content": "Hello, World!"
}
----
====

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

To model the greeting representation, create a representation class. The following listing
(from `src/main/java/com/example/actuatorservice/Greeting.java`) shows the `Greeting`
class:

====
[source,java,tabsize=2]
----
include::complete/src/main/java/com/example/actuatorservice/Greeting.java[]
----
====

Now that you need to create the endpoint controller that will serve the representation
class.

== Create a Resource Controller

In Spring, REST endpoints are Spring MVC controllers. The following Spring MVC controller
(from `src/main/java/com/example/actuatorservice/HelloWorldController.java`) handles a GET
request for the `/hello-world` endpoint and returns the `Greeting` resource:

====
[source,java,tabsize=2]
----
include::complete/src/main/java/com/example/actuatorservice/HelloWorldController.java[]
----
====

The key difference between a human-facing controller (`Controller`) and a REST endpoint
controller (`RestController`) 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 returns the data
to be written directly to the body of the response.

The response is written using one of Spring's message converters. Because Jackson is in the classpath,
https://docs.spring.io/spring/docs/{spring_version}/javadoc-api/org/springframework/http/converter/json/JacksonJsonHttpMessageConverter.html[`JacksonJsonHttpMessageConverter`]
will handle the conversion of a `Greeting` object to JSON if the request's `Accept` header
specifies that JSON should be returned.

NOTE: How do you know Jackson is on the classpath? Either run `mvn dependency:tree` or
`./gradlew dependencies`, and you get a detailed tree of dependencies that includes
Jackson. You can also see that it comes from
https://github.com/spring-projects/spring-boot/tree/main/starter/spring-boot-starter-json[/spring-boot-starter-json],
 itself imported by
 https://github.com/spring-projects/spring-boot/tree/main/starter/spring-boot-starter-webmvc[spring-boot-starter-webmvc].

== Run the Application

You can run the application from a custom main class or directly from one of the
configuration classes. For this simple example, you can use the `SpringApplication` helper
class. Note that this is the application class that the Spring Initializr created for you,
and you need not even modify it for it to work for this simple application. The following
listing (from `src/main/java/com/example/actuatorservice/HelloWorldApplication.java`)
shows the application class:

====
[source,java,tabsize=2]
----
include::complete/src/main/java/com/example/actuatorservice/HelloWorldApplication.java[]
----
====

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` annotation also brings in a
https://docs.spring.io/spring/docs/{spring_version}/javadoc-api/org/springframework/context/annotation/ComponentScan.html[`@ComponentScan`]
annotation, which tells Spring to scan the `com.example.actuatorservice` package for those
controllers (along with any other annotated component classes).

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/build_an_executable_jar_mainhead.adoc[]

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/build_an_executable_jar_with_both.adoc[]

Once the service is running (because you ran `spring-boot:run` in a terminal), you can test it by running the following command in a separate terminal:

====
[source,bash]
----
$ curl localhost:8080/hello-world
{"id":1,"content":"Hello, Stranger!"}
----
====

== Switch to a Different Server Port

Spring Boot Actuator defaults to running on port 8080. By adding an
`application.properties` file, you can override that setting. The following listing (from
`src/main/resources/application.properties`)shows that file with the necessary changes:

====
[source,properties]
----
include::complete/src/main/resources/application.properties[]
----
====

Run the server again by running the following command in a terminal:

====
[subs="attributes"]
----
$ ./gradlew clean build && java -jar build/libs/{project_id}-0.0.1-SNAPSHOT.jar
----
====

The service now starts on port 9000 and actuator endpoints on port 9001.

You can test that it is working on port 9000 by running the following commands in a
terminal:

====
[source,bash]
----
$ 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

To check whether your application works, you should write unit and integration tests for
your application.
The test class in
`src/test/java/com/example/actuatorservice/HelloWorldApplicationTests.java`
ensures that

* Your controller is responsive.
* Your management endpoint is responsive.

Note that the tests start the application on a random port.
The following listing shows the test class:

====
[source,java,tabsize=2]
----
include::complete/src/test/java/com/example/actuatorservice/ActuatorServiceApplicationTests.java[]
----
====

== Summary

Congratulations! You have just developed a simple RESTful service by using Spring, and you
added some useful built-in services with Spring Boot Actuator.

== See Also

The following guides may also be helpful:

* https://spring.io/guides/gs/spring-boot/[Building an Application with Spring Boot]
* https://spring.io/guides/gs/serving-web-content/[Serving Web Content with Spring MVC]

include::https://raw.githubusercontent.com/spring-guides/getting-started-macros/main/footer.adoc[]
S
Description
No description provided
Readme
96 KiB
Languages
Java 87%
Shell 8.8%
Dockerfile 4.2%