Suppose we want our controller methods to return a JSON response when the HTTP Accept header is set to application/json
and XML when the Accept header is set to application/xml
.
We can access the values of HTTP headers in our controller methods by adding an argument of type HttpHeaders
to our method definition and Micronaut will add all HTTP headers with their values as HttpHeaders
object when we run the application.
In our method we can check the value of the Accept header and return a different value based on the header value.
In the following example controller we have a sample
method with an argument of type HttpHeaders
.
We check the value of the Accept header using the method accept
and return either XML or JSON as response.
Continue reading →
When we add the io.micronaut:management
dependency to our Micronaut application we get, among other things, a /health
endpoint.
We must enable it in our application configuration where we can also configure how much information is shown and if we want to secure the endpoint.
Micronaut has some built-in health indicators, some of which are only available based on certain conditions.
For example there is a disk space health indicator that will return a status of DOWN when the free disk space is less than a (configurable) threshold.
If we would have one or more DataSource
beans for database access in our application context a health indicator is added as well to show if the database(s) are available or not.
We can also add our own health indicator that will show up in the /health
endpoint.
We must write a class that implements the HealthIndicator
interface and add it to the application context.
We could add some conditions to make sure the bean is loaded when needed.
Micronaut also has the abstract AbstractHealthIndicator
class that can be used as base class for writing custom health indicators.
Continue reading →
Micronaut has some built-in management endpoints to get information, a list of beans, health checks and more. To enable the endpoints we must add the dependency io.micronaut:management
to our application.
Then we can add configuration properties to enable the different endpoints.
The /info
endpoint gathers information from several sources with properties.
If we want to add build information we must create a file build-info.properties
with information and Micronaut will automatically add the properties from the file to the /info
endpoint.
We can choose how we want to create the build-info.properties
file.
The location is configurable via Micronaut application configuration properties, but the default location is on the classpath at META-INF/build-info.properties
.
To make life easy for us we reuse the BuildInfo
Gradle task from the Spring Boot Gradle plugin to create the build-info.properties
file.
Continue reading →
Micronaut uses Jackson to encode objects to JSON and decode JSON to objects.
Micronaut adds a Jackson ObjectMapper
bean to the application context with all configuration to work properly.
Jackson can by default populate an object with values from JSON as the class has a no argument constructor and the properties can be accessed.
But if our class doesn’t have a no argument constructor we need to use the @JsonCreator
and @JsonProperty
annotations to help Jackson.
We can use these annotation on the constructor with arguments that is used to create an object.
But we can even make it work without the extra annotations, so our classes are easier to read and better reusable.
We need to add the Jackson ParameterNamesModule
as module to the ObjectMapper
instance in our application.
And we need to compile our sources with the -parameter
argument, so the argument names are preserved in the compiled code.
Luckily the -parameter
option is already added to our Gradle build when we create a Micronaut application.
All we have to do is to add the ParameterNamesModule
in our application.
Continue reading →
Micronaut is reactive by nature and uses RxJava2 as implementation for the Reactive Streams API by default.
RxJava2 is on the compile classpath by default, but we can easily use Project Reactor as implementation of the Reactive Streams API.
This allows us to use the Reactor types Mono
and Flux
.
These types are also used by Spring’s Webflux framework and makes a transition from Webflux to Micronaut very easy.
How we do use Project Reactor in our Micronaut application? We only have to add the dependency the Project Reactory core library to our project.
In the following example we add it to our build.gradle
file as:
Continue reading →
The Node
class in Groovy has the methods depthFirst
and breadthFirst
to return a collection of Node
objects using either depth or breadth first traversal.
Since Groovy 2.5.0 we can specify if we want to use preorder (the default) or postorder traversal.
Also the methods now accept a Closure
that will be invoked for each visited node.
The Closure
has the current Node
as first argument, the second argument is the tree level of the current node.
In the following example we read some XML and then use depthFirst
in several ways to visit the tree of nodes:
Continue reading →
A tuple is an ordered, immutable list of elements.
Groovy supported tuples with one or two elements before Groovy 2.5.0.
Since Groovy 2.5.0 we can use tuples with maximal nine items.
Groovy added the classes Tuple3
up to Tuple9
.
The bonus we get compared to an unmodifiable list with elements is that we can use properties like first
, second
, third
, fourth
, fifth
, sixth
, seventh
, eighth
, ninth
to get items at the specified position.
In the following example we use different Tuple
classes:
Continue reading →
Groovy supports named arguments for methods.
Actually Groovy collects all named arguments (defined using the name followed by a :
and the value) into a Map
.
The Map
must be the first parameter of the method to make it all work.
Since Groovy 2.5.0 we can use the @NamedVariant
AST transformation annotation to let Groovy create a method where the first parameter is a Map
to support named arguments for an existing method.
The existing method is still available, but Groovy adds an extra method to our generated class.
By default Groovy will make the first parameters of the original method part of the new method supporting named arguments.
If the first parameters is a class type, then the properties of the class can be used as named arguments.
We can also explicitly define which parameters of our original method should be named arguments using the annotations @NamedParam
and @NamedDelegate
.
These annotations need to defined for each parameter. The newly created method by the AST transformation invokes the original method.
Continue reading →
When we wanted to create collections in Groovy that were unmodifiable we could use asImmutable.
Since Groovy 2.5.0 we can also use the asUnmodifiable
method on collections.
The method can be applied on all Collection
types including Map
.
In the following example we use asUnmodifiable
on a List
and Map
:
Continue reading →
Since the early days of Groovy we can create POGO (Plain Old Groovy Objects) classes that will have a constructor with a Map
argument.
Groovy adds the constructor automatically in the generated class.
We can use named arguments to create an instance of a POGO, because of the Map
argument constructor.
This only works if we don’t add our own constructor and the properties are not final.
Since Groovy 2.5.0 we can use the @MapConstrutor
AST transformation annotation to add a constructor with a Map
argument.
Using the annotation we can have more options to customize the generated constructor.
We can for example let Groovy generate the constructor with Map
argument and add our own constructor.
Also properties can be final and we can still use a constructor with Map
argument.
First we look at the default behaviour in Groovy when we create a POGO:
Continue reading →
A lot of new AST transformation annotations are added in Groovy 2.5.0. One of them is the @AutoImplement
annotation.
If we apply this annotation to our class dummy implementations for abstract methods in superclasses or methods in implemented interfaces are created.
This can be useful to have something in place and then gradually write real implementations for the abstract or interface methods.
The transformation will not alter any method that is already implemented by custom code.
When we apply the @AutoImplement
annotation the default implementation for an abstract method from a superclass or method from a interface is simple.
If the method has a return type the default value of that return type is returned.
For example false
for a boolean
and null
for an object type.
But the @AutoImplement
annotation has some attributes we can use to change the default implementation.
We can set the exception
attribute and assign a exception type.
The implementation of the methods is than to throw that exception when the method is invoked.
With the optional message
attribute we can set the exception message.
Finally we can use the code
attribute to define a Closure
with statements that will be called as the implementation of abstract and interface methods.
Continue reading →
Groovy 2.5.0 adds the possibility to customize JSON output via a JsonGenerator
instance.
The easiest way to turn an object into a JSON string value is via JsonOutput.toJson
.
This method uses a default JsonGenerator
with sensible defaults for JSON output.
But we can customize this generator and create JSON output using the custom generator.
To create a custom generator we use a builder accessible via JsonGenerator.Options
.
Via a fluent API we can for example ignore fields with null
values in the output, change the date format for dates and ignore fields by their name or type of the value.
And we can add a custom converter for types via either an implementation of the conversion as Closure
or implementation of the JsonGenerator.Converter
interface.
To get the JSON string we simple invoke the toJson
method of our generator.
In the following example Groovy code we have a Map
with data and we want to convert it to JSON.
First we use the default generator and then we create our own to customize the JSON output:
Continue reading →