Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Configuration and environments

The blog title, the page size or the database address should not be written straight into code: they differ on your computer and on the server. Such values live in the settings file src/main/resources/application.properties, and the code reads them. An environment is a named set of settings, for example dev for development and prod for the server.

Your own settings

Add lines to the file the generator created:

# src/main/resources/application.properties
micronaut.application.name=blog
blog.title=My blog
blog.author=Anna

The framework reads the micronaut.* keys itself; the blog.* keys are ours. The YAML format (application.yml) is supported too if you pick the yaml feature when creating the project.

A group of settings in a record

Several related values are best collected into one record with @ConfigurationProperties:

// src/main/java/com/example/BlogConfig.java
package com.example;
 
import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.core.bind.annotation.Bindable;
 
@ConfigurationProperties("blog")
public record BlogConfig(String title, @Bindable(defaultValue = "10") int pageSize) {
}

The blog prefix plus the component name give the key: title is read from blog.title, and pageSize from blog.page-size (files conventionally use hyphens). If a key is missing, the defaultValue applies. The record becomes a bean, and you inject it like a service.

A single value with @Value

For a single value there is @Value with a ${key} expression:

// src/main/java/com/example/AboutController.java
package com.example;
 
import io.micronaut.context.annotation.Value;
import io.micronaut.context.env.Environment;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
 
@Controller("/about")
public class AboutController {
 
    private final BlogConfig config;
    private final Environment environment;
    private final String author;
 
    public AboutController(BlogConfig config, Environment environment,
                           @Value("${blog.author}") String author) {
        this.config = config;
        this.environment = environment;
        this.author = author;
    }
 
    @Get
    public AboutInfo about() {
        return new AboutInfo(config.title(), config.pageSize(), author, environment.getActiveNames());
    }
}

AboutInfo is a @Serdeable record with the fields title, pageSize, author and environments (of type Set<String>). The request curl http://localhost:8080/about returns:

{"title":"My blog","pageSize":10,"author":"Anna"}

The list of environments is empty, so it is left out of the JSON.

Environments

Create a file next to it for the dev environment:

# src/main/resources/application-dev.properties
blog.title=My blog (dev)
blog.page-size=3

An environment is switched on with the MICRONAUT_ENVIRONMENTS variable or the -Dmicronaut.environments=dev property:

MICRONAUT_ENVIRONMENTS=dev ./mvnw mn:run

The log shows Established active environments: [dev], and /about answers {"title":"My blog (dev)","pageSize":3,"author":"Anna","environments":["dev"]}. Values from application-dev.properties override the common file.

OS environment variables

Any key can be overridden with an OS variable: dots and hyphens become underscores and letters become uppercase. blog.title turns into BLOG_TITLE:

BLOG_TITLE="Oleg's blog" ./mvnw mn:run

This is how passwords and addresses are set on a server without changing project files.

Common mistake

If no source has the key used in @Value, the first request to the controller returns 500, and the log says:

Message: Error resolving property value [${blog.author}]. Property doesn't exist
Path Taken:
new c.e.AboutController(BlogConfig config, Environment environment, @Value String author)

Add the key to application.properties or put a default value right in the expression: @Value("${blog.author:Anna}").

Thanks for reading!

Donate to the site — we work hard for you.