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:
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-resourceTo prepare this configuration for production, a naive approach would be to override the URLs in profile configurations::
application-prod.yml:
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-resourceand application-uat.yml:
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-resourceHowever, 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:
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-resourceapplication-prod.yml:
1backend.url: http://cloud-prod:8081and application-uat.yml:
1backend.url: http://cloud-uat:80812. Use naming convention
application.yml:
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-resourceThe 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:
1backend.url: http://localhost:80813. 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:
1127.0.0.1 cloud-localIf 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.
