DEV Community

Artem Ptushkin
Artem Ptushkin

Posted on

Kotlin Spring Boot Configuration properties best practices

Jump to the example if you're quite advanced in Spring already

What do we have

Working in Spring Boot stack one of the first features that every developer is taking the advantage of is Configuration Properties

Which could be configured as:

  • class level beans
  • method based beans

Basically method level beans are the same as class level but you can create N properties beans from a single class.

The properties itself can be propagated in different ways but the most common is through application properties / yaml files.

What's important about the properties that they can be:

  • null
  • defaulted

Naming

Spring follows the next conventions as for the configuration (class with beans) and configuration properties classes:

  • @Configuration - *Configuration.kt
  • @ConfigurationProperties - *Properties.kt

It's good to follow the standards from the ecosystem you use to prevent confusions as:

Properties class is not a configuration

Anti-patterns

Difference between configuration and properties

  • Configuration - is a class that defines beans
  • Properties - is a class that defines data structure to describe the application properties, e.g. to map the properties to an object

The next example is anti-pattern because spring works differently with these concepts:

@Configuration
@ConfigurationProperties
class MyProperties {
  String value;
}
Enter fullscreen mode Exit fullscreen mode

Configuration properties bean must be initialised by Spring not manually

The next example is anti-pattern because configuration properties is a bean can be initialised much more naturally when it's loosely coupled with it's configuration, for instance it's a problem if you use @ConstructorBinding:

@Component
@ConfigurationProperties
class MyProperties {
  String value;
}
Enter fullscreen mode Exit fullscreen mode

Standards, code consistency

The goal of the best practices is to find the golden mean. Where we expect that the data-structure represents in a neat way the mapping between the properties and the class.

  • default value should be located as close as possible to the field so developer can immediately see it
  • nullability should represent the actual necessity of the property
  • it should be simple
  • composite children fields are designed in the same way

Having all the requirements we have the next example:

Demo

Let's say we have this set of properties defined:

io.github.artemptushkin.example:
  defaultOverriddenProperty: overridden
  requiredStringProperty: required-value
  notNullListProperty: ["foo", "baz"]
Enter fullscreen mode Exit fullscreen mode

it will give us the next runtime properties:

io.github.artemptushkin.example.defaultedStringProperty=default
io.github.artemptushkin.example.defaultOverriddenProperty=overridden
io.github.artemptushkin.example.requiredStringProperty=required-value
io.github.artemptushkin.example.optionalStringProperty=null
io.github.artemptushkin.example.notNullListProperty[0]=foo
io.github.artemptushkin.example.notNullListProperty[1]=baz
Enter fullscreen mode Exit fullscreen mode

Key points are:

  • @ConstructorBinding let's us use create immutable objects
  • Kotlin default constructor values let us use to have default values right in place in one single line
  • Always initialise collections as empty by default to prevent nullable field

Summary

It's possible to write clean classes and keep them concise from one project to another and within your company.

I hope this noted helped you.

Top comments (0)