Spring Boot configuration best practices

Spring Boot configuration best practices

The article discusses best practices for configuring Spring Boot applications. It highlights the usefulness of Spring Boot’s configuration mechanism and provides examples of common misuses of the mechanism.

Spring Boot provides a useful configuration mechanism that allows for a default application configuration defined in application.yml and a set of environment-specific configuration files (e.g. application-prod.yml, application-test.yml, application-local.yml). While it is possible to use expressions to evaluate parameter values based on other parameters, this mechanism is often misused.

Consider the following example configuration file for a Zuul proxy:

application.yml:

yaml
1zuul:
2  routes:
3    foos:
4      path: /foos/**
5      url: http://localhost:8081/spring-zuul-foos-resource
6    baas:
7      path: /baas/**
8      url: http://localhost:8081/spring-zuul-baas-resource

To prepare this configuration for production, a naive approach would be to override the URLs in profile configurations::

application-prod.yml:

yaml
1zuul:
2  routes:
3    foos:
4      url: http://cloud-prod:8081/spring-zuul-foos-resource
5    baas:
6      url: http://cloud-prod:8081/spring-zuul-baas-resource

and application-uat.yml:

yaml
1zuul:
2  routes:
3    foos:
4      url: http://cloud-uat:8081/spring-zuul-foos-resource
5    baas:
6      url: http://cloud-uat:8081/spring-zuul-baas-resource

However, this is a Copy&Paste approach that should be avoided. Instead, the configuration files can be refactored as follows:

1. Extract backend base url property

application.yml:

yaml
1backend.url: http://localhost:8081
2zuul:
3  routes:
4    foos:
5      path: /foos/**
6      url: ${backend.url}/spring-zuul-foos-resource
7    baas:
8      path: /baas/**
9      url: ${backend.url}/spring-zuul-baas-resource

application-prod.yml:

yaml
1backend.url: http://cloud-prod:8081

and application-uat.yml:

yaml
1backend.url: http://cloud-uat:8081

2. Use naming convention

application.yml:

yaml
1backend.url: http://cloud-${spring.profile.active}:8081
2zuul:
3  routes:
4    foos:
5      path: /foos/**
6      url: ${backend.url}/spring-zuul-foos-resource
7    baas:
8      path: /baas/**
9      url: ${backend.url}/spring-zuul-baas-resource

The environment-specific configuration files (application-prod.yml and application-uat.yml) are no longer needed and can be safely removed, and a local development configuration file (application-local.yml) can be used:

yaml
1backend.url: http://localhost:8081

3. Follow naming convention even in local environment

If you don’t have a lot of services to run, you may define an alias for your local machine in your /etcs/hosts file:

text
1127.0.0.1 cloud-local

If you’re developing a lot of interconnected services then docker-compose may be your way to go.

TL;DR: Extract host names or base urls and use naming conventions as much as possible

Next Steps

Instead of creating environment-specific files, use Spring Cloud Config. Use Spring Cloud Vault to access secrets. You may still need to define a configuration file to run the application locally and in a CI server. Use service discovery instead of static host names or utilize Kubernetes namespaces to unify naming.

Konstantin Pavlov

Konstantin Pavlov

Software Engineer working with Java, Kotlin, Swift, and AI. Focusing on software architecture and building AI-infused apps. Passionate about testing and Open-Source projects.