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.micronautguideusing 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/helloreturning the text “Hello World”and also at the address http://localhost:8080/booksreturning 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”.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *