Skip to main content
  1. Posts/

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:

zuul:
  routes:
    foos:
      path: /foos/**
      url: http://localhost:8081/spring-zuul-foos-resource
    baas:
      path: /baas/**
      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:

zuul:
  routes:
    foos:
      url: http://cloud-prod:8081/spring-zuul-foos-resource
    baas:
      url: http://cloud-prod:8081/spring-zuul-baas-resource

and application-uat.yml:

zuul:
  routes:
    foos:
      url: http://cloud-uat:8081/spring-zuul-foos-resource
    baas:
      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:

backend.url: http://localhost:8081
zuul:
  routes:
    foos:
      path: /foos/**
      url: ${backend.url}/spring-zuul-foos-resource
    baas:
      path: /baas/**
      url: ${backend.url}/spring-zuul-baas-resource

application-prod.yml:

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

and application-uat.yml:

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

2. Use naming convention #

application.yml:

backend.url: http://cloud-${spring.profile.active}:8081
zuul:
  routes:
    foos:
      path: /foos/**
      url: ${backend.url}/spring-zuul-foos-resource
    baas:
      path: /baas/**
      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:

backend.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:

127.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.