Implementing Custom Endpoints
If you add a @Bean
annotated with @Endpoint
, any methods annotated with @ReadOperation
, @WriteOperation
, or @DeleteOperation
are automatically exposed over JMX and, in a web application, over HTTP as well.
Endpoints can be exposed over HTTP by using Jersey, Spring MVC, or Spring WebFlux.
If both Jersey and Spring MVC are available, Spring MVC is used.
The following example exposes a read operation that returns a custom object:
-
Java
-
Kotlin
@ReadOperation
public CustomData getData() {
return new CustomData("test", 5);
}
@ReadOperation
fun getData(): CustomData {
return CustomData("test", 5)
}
You can also write technology-specific endpoints by using @JmxEndpoint
or @WebEndpoint
.
These endpoints are restricted to their respective technologies.
For example, @WebEndpoint
is exposed only over HTTP and not over JMX.
You can write technology-specific extensions by using @EndpointWebExtension
and @EndpointJmxExtension
.
These annotations let you provide technology-specific operations to augment an existing endpoint.
Finally, if you need access to web-framework-specific functionality, you can implement servlet or Spring @Controller
and @RestController
endpoints at the cost of them not being available over JMX or when using a different web framework.
Receiving Input
Operations on an endpoint receive input through their parameters.
When exposed over the web, the values for these parameters are taken from the URL’s query parameters and from the JSON request body.
When exposed over JMX, the parameters are mapped to the parameters of the MBean’s operations.
Parameters are required by default.
They can be made optional by annotating them with either @javax.annotation.Nullable
or @org.springframework.lang.Nullable
.
You can map each root property in the JSON request body to a parameter of the endpoint. Consider the following JSON request body:
{
"name": "test",
"counter": 42
}
You can use this to invoke a write operation that takes String name
and int counter
parameters, as the following example shows:
-
Java
-
Kotlin
@WriteOperation
public void updateData(String name, int counter) {
// injects "test" and 42
}
@WriteOperation
fun updateData(name: String?, counter: Int) {
// injects "test" and 42
}
Because endpoints are technology agnostic, only simple types can be specified in the method signature.
In particular, declaring a single parameter with a CustomData type that defines a name and counter properties is not supported.
|
To let the input be mapped to the operation method’s parameters, Java code that implements an endpoint should be compiled with -parameters , and Kotlin code that implements an endpoint should be compiled with -java-parameters .
This will happen automatically if you use Spring Boot’s Gradle plugin or if you use Maven and spring-boot-starter-parent .
|
Input Type Conversion
The parameters passed to endpoint operation methods are, if necessary, automatically converted to the required type.
Before calling an operation method, the input received over JMX or HTTP is converted to the required types by using an instance of ApplicationConversionService
as well as any Converter
or GenericConverter
beans qualified with @EndpointConverter
.
Custom Web Endpoints
Operations on an @Endpoint
, @WebEndpoint
, or @EndpointWebExtension
are automatically exposed over HTTP using Jersey, Spring MVC, or Spring WebFlux.
If both Jersey and Spring MVC are available, Spring MVC is used.
Web Endpoint Request Predicates
A request predicate is automatically generated for each operation on a web-exposed endpoint.
Path
The path of the predicate is determined by the ID of the endpoint and the base path of the web-exposed endpoints.
The default base path is /actuator
.
For example, an endpoint with an ID of sessions
uses /actuator/sessions
as its path in the predicate.
You can further customize the path by annotating one or more parameters of the operation method with @Selector
.
Such a parameter is added to the path predicate as a path variable.
The variable’s value is passed into the operation method when the endpoint operation is invoked.
If you want to capture all remaining path elements, you can add @Selector(Match=ALL_REMAINING)
to the last parameter and make it a type that is conversion-compatible with a String[]
.
HTTP method
The HTTP method of the predicate is determined by the operation type, as shown in the following table:
Operation | HTTP method |
---|---|
|
|
|
|
|
|
Consumes
For a @WriteOperation
(HTTP POST
) that uses the request body, the consumes
clause of the predicate is application/vnd.spring-boot.actuator.v2+json, application/json
.
For all other operations, the consumes
clause is empty.
Produces
The produces
clause of the predicate can be determined by the produces
attribute of the @DeleteOperation
, @ReadOperation
, and @WriteOperation
annotations.
The attribute is optional.
If it is not used, the produces
clause is determined automatically.
If the operation method returns void
or Void
, the produces
clause is empty.
If the operation method returns a org.springframework.core.io.Resource
, the produces
clause is application/octet-stream
.
For all other operations, the produces
clause is application/vnd.spring-boot.actuator.v2+json, application/json
.
Web Endpoint Response Status
The default response status for an endpoint operation depends on the operation type (read, write, or delete) and what, if anything, the operation returns.
If a @ReadOperation
returns a value, the response status will be 200 (OK).
If it does not return a value, the response status will be 404 (Not Found).
If a @WriteOperation
or @DeleteOperation
returns a value, the response status will be 200 (OK).
If it does not return a value, the response status will be 204 (No Content).
If an operation is invoked without a required parameter or with a parameter that cannot be converted to the required type, the operation method is not called, and the response status will be 400 (Bad Request).
Web Endpoint Range Requests
You can use an HTTP range request to request part of an HTTP resource.
When using Spring MVC or Spring Web Flux, operations that return a org.springframework.core.io.Resource
automatically support range requests.
Range requests are not supported when using Jersey. |
Web Endpoint Security
An operation on a web endpoint or a web-specific endpoint extension can receive the current java.security.Principal
or org.springframework.boot.actuate.endpoint.SecurityContext
as a method parameter.
The former is typically used in conjunction with @Nullable
to provide different behavior for authenticated and unauthenticated users.
The latter is typically used to perform authorization checks by using its isUserInRole(String)
method.
Servlet Endpoints
A servlet can be exposed as an endpoint by implementing a class annotated with @ServletEndpoint
that also implements Supplier<EndpointServlet>
.
Servlet endpoints provide deeper integration with the servlet container but at the expense of portability.
They are intended to be used to expose an existing servlet as an endpoint.
For new endpoints, the @Endpoint
and @WebEndpoint
annotations should be preferred whenever possible.
Controller Endpoints
You can use @ControllerEndpoint
and @RestControllerEndpoint
to implement an endpoint that is exposed only by Spring MVC or Spring WebFlux.
Methods are mapped by using the standard annotations for Spring MVC and Spring WebFlux, such as @RequestMapping
and @GetMapping
, with the endpoint’s ID being used as a prefix for the path.
Controller endpoints provide deeper integration with Spring’s web frameworks but at the expense of portability.
The @Endpoint
and @WebEndpoint
annotations should be preferred whenever possible.