Building Microservices in Groovy with Micronaut
Beginning of work
To work with Micronaut you need JDK version 17 or higher. You can download the JDK from the official Oracle website or use one of the alternative distributions, such as OpenJDK.
After installing the JDK, it is advisable to check that the environment variable JAVA_HOME
configured correctly:
export JAVA_HOME=/path/to/your/jdk
export PATH=$JAVA_HOME/bin:$PATH
Micronaut CLI allows you to create and manage projects, let's install:
sdk install micronaut
For Windows users, it is also worth installing SDKMAN! and use it to install Micronaut CLI.
To create a new Micronaut project in Groovy, there is a command in the Micronaut CLI:
mn create-app example.micronaut.micronautguide --lang=groovy
The command will create a new project named example.micronaut.micronautguide
using Groovy as its main programming language.
After creating the project, there will be the following directory and files:
example.micronaut.micronautguide
├── build.gradle
├── src
│ ├── main
│ │ ├── groovy
│ │ │ └── example
│ │ │ └── micronaut
│ │ │ └── Application.groovy
│ │ └── resources
│ │ └── application.yml
│ └── test
│ ├── groovy
│ │ └── example
│ │ └── micronaut
│ │ └── ApplicationSpec.groovy
│ └── resources
├── gradle
│ └── wrapper
│ └── gradle-wrapper.properties
└── gradlew
└── gradlew.bat
build.gradle: The configuration file Gradlewhich defines the dependencies and build settings of the project.
src/main/groovy: the main directory for Groovy source code. The main class of the application is located here
Application.groovy
.src/main/resources: directory for application resources, including configuration file
application.yml
.src/test/groovy: directory for Groovy test code. The test class is located here
ApplicationSpec.groovy
.gradle And gradlew: scripts and configurations for building a project using Gradle.
Step-by-step creation of a microservice
Let's open the file build.gradle
and there we will make sure that dependencies for Groovy and Micronaut are added:
plugins {
id 'groovy'
id 'io.micronaut.application' version '3.0.0'
}
version '0.1'
group 'example.micronaut'
repositories {
mavenCentral()
}
dependencies {
implementation "io.micronaut:micronaut-runtime"
implementation "io.micronaut.groovy:micronaut-runtime-groovy"
testImplementation "io.micronaut.test:micronaut-test-spock"
testImplementation "org.spockframework:spock-core"
}
micronaut {
runtime "netty"
testRuntime "spock"
processing {
incremental true
annotations "example.micronaut.*"
}
}
Here we connect the necessary plugins and dependencies. Plugin groovy
allows you to use Groovy in your project, and io.micronaut.application
provides capabilities for working with Micronaut.
Creating the main application
Create a file src/main/groovy/example/micronaut/Application.groovy
:
package example.micronaut
import io.micronaut.runtime.Micronaut
import groovy.transform.CompileStatic
@CompileStatic
class Application {
static void main(String[] args) {
Micronaut.run(Application, args)
}
}
The file contains the main application class that runs Micronaut. Abstract @CompileStatic
Updates performance by statically compiling Groovy code.
Creating a controller
Create a controller src/main/groovy/example/micronaut/HelloController.groovy
:
package example.micronaut
import groovy.transform.CompileStatic
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
import io.micronaut.http.MediaType
@CompileStatic
@Controller("/hello")
class HelloController {
@Get
@Produces(MediaType.TEXT_PLAIN)
String index() {
"Hello World"
}
}
The controller processes GET requests on /hello
and returns the string “Hello World“. Annotation @Controller
indicates that this class is a controller, and the annotation @Get
indicates that the method index
processes GET requests.
Let's set up the application configuration
Open the file src/main/resources/application.yml
and add the configuration:
micronaut:
application:
name: micronautguide
The configuration file specifies the name of the application.
Creating a test for the controller
Create a file src/test/groovy/example/micronaut/HelloControllerSpec.groovy
:
package example.micronaut
import io.micronaut.http.HttpRequest
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import spock.lang.Specification
import jakarta.inject.Inject
@MicronautTest
class HelloControllerSpec extends Specification {
@Inject
@Client("/")
HttpClient client
void "test hello world response"() {
when:
HttpRequest request = HttpRequest.GET('/hello')
String rsp = client.toBlocking().retrieve(request)
then:
rsp == "Hello World"
}
}
Tst checks that the controller returns the string “Hello World” when GET request to /hello
. Annotation @MicronautTest
indicates that this is a test for the Micronaut application.
Let's add a new controller to work with books and expand the functionality of the microservice.
Create a file src/main/groovy/example/micronaut/BookController.groovy
:
package example.micronaut
import groovy.transform.CompileStatic
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
import io.micronaut.http.MediaType
@CompileStatic
@Controller("/books")
class BookController {
@Get
@Produces(MediaType.APPLICATION_JSON)
List<Book> listBooks() {
[
new Book("The Stand", "Stephen King"),
new Book("The Hobbit", "J.R.R. Tolkien")
]
}
}
@CompileStatic
class Book {
String title
String author
Book(String title, String author) {
this.title = title
this.author = author
}
}
The controller processes GET requests on /books
and returns a list of books in JSON format. Also created a class Book
to present the book.
Create a file src/test/groovy/example/micronaut/BookControllerSpec.groovy
:
package example.micronaut
import io.micronaut.http.HttpRequest
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import spock.lang.Specification
import jakarta.inject.Inject
@MicronautTest
class BookControllerSpec extends Specification {
@Inject
@Client("/")
HttpClient client
void "test list books response"() {
when:
HttpRequest request = HttpRequest.GET('/books')
List books = client.toBlocking().retrieve(request, List)
then:
books.size() == 2
books[0].title == "The Stand"
books[1].title == "The Hobbit"
}
}
The test verifies that the controller returns a list of two books.
Launching and testing the application
Building and running the application:
./gradlew run
Running tests:
./gradlew test
After completing all the steps, the application will be launched and accessible at http://localhost:8080/hello
returning the text “Hello World”and also at the address http://localhost:8080/books
returning a list of books. The tests will check that the controllers are working correctly.
Micronaut and Groovy are a powerful combination for building microservices. Learn more with the library You can read it here.
The material was prepared as part of an online course “Groovy Developer”.