Uno de los problemas más comunes cuando se desarrollan aplicaciones en cualquier lenguaje es utilizar un solo código que este se ejecute en múltiples entornos (dev, qa y prod). En todos los entornos se utilizarán las mismas configuraciones, lo que cambiará de uno a otro serán los valores asignados a las mismas.
Para soportar esto Spring boot provee perfiles que son diferentes a los perfiles normales de Maven, para saber más sobre ellos re recomendamos el post Perfiles Maven en Español !.
Primeros pasos
Antes de adentrarnos a cómo configurar los perfiles primero existen algunos conceptos que debemos entender:
- Un perfil se asignará a un entorno de tal modo que si tenemos los entornos, Desarrollo, QA y Producción se deberán crear 3 perfiles.
- A diferencia de los perfiles normales de Maven, en Spring boot los perfiles se utilizarán en tiempo de ejecución, de este modo no es necesario compilar los proyectos con la bandera -P.
- Existen diferentes formas de definir un perfil en Maven, en este post se explicarán las 2 principales utilizando archivos properties y utilizando archivos yaml.
- Para estos ejemplos se tomará como base el proyecto creado en el post Spring Boot + REST Jersey Parte 1.
Definiendo perfiles utilizando archivos properties
Para configurar los perfiles maven utilizando archivos properties es necesario hacer lo siguiente.
1. Agregar un archivo properties por cada perfil que se desea soportar
El primer paso será crear un archivo properties en el folder src/main/resources por cada uno de los entornos a soportar siguiendo la siguiente estructura:
application-${profile}.properties
${profile} Será el nombre de nuestro entorno. Para este ejemplo se crearán los siguientes 3 archivos:
- application-dev.properties
com.raidentrance.app.name=Spring boot dev
- application-qa.properties
com.raidentrance.app.name=Spring boot qa
- application-prod.properties
com.raidentrance.app.name=Spring boot prod
2. Crear un nuevo servicio para mostrar el valor de la propiedad
Una vez definida la nueva propiedad llamada com.raidentrance.app.name el siguiente paso será exponerla en un servicio. Para esto se creará el siguiente servicio:
/** * */ package com.raidentrance.resource; import javax.ws.rs.Consumes; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @author maagapi * */ @Component @Path("/configs") @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) public class ProjectConfigurationResource { @Value("${com.raidentrance.app.name}") private String appName; private static final Logger log = LoggerFactory.getLogger(UserResource.class); @GET @Path("/appName") public Response getAppName() { log.info("Getting project configuration"); return Response.ok(appName).build(); } }
El servicio anterior mostrará en la respuesta del endpoint GET /configs/appName el nombre definido en nuestro archivo de configuración.
3. Registrar el servicio en Jersey
Recordemos que siempre que se crea un servicio nuevo en Jersey lo debemos agregar en nuestra clase JerseyConfig como se muestra a continuación:
/** * */ package com.raidentrance.config; import org.glassfish.jersey.server.ResourceConfig; import org.springframework.stereotype.Component; import com.raidentrance.resource.ProjectConfigurationResource; import com.raidentrance.resource.UserResource; /** * @author raidentrance * */ @Component public class JerseyConfig extends ResourceConfig { public JerseyConfig() { register(UserResource.class); register(ProjectConfigurationResource.class); } }
Recordemos que el servicio UserResource fue el que ya existía en el ejemplo y no es necesario para la explicación de perfiles.
4. Probado todo junto
Una vez que ya se configuró todo lo anterior lo único que resta es probarlo, para esto solo es necesario compilar nuestra aplicación como siempre con un simple mvn clean install, lo único que será diferente será al momento de ejecutarlo, para esto se utilizará el siguiente comando:
mvn -Dspring.profiles.active=qa spring-boot:run
Como se puede ver en el comando se ejecutará la aplicación utilizando las configuraciones definidas en el perfil de qa.
Si ejecutamos el endpoint GET /configs/appName la salida será la siguiente:
Spring boot qa
Definiendo perfiles utilizando archivos yaml
Una vez que ya sabemos como definir los perfiles utilizando multiples archivos .properties, el siguiente paso será entender como hacerlo utilizando archivos yaml.
Paso 1 Definir las configuraciones
A diferencia de la configuración utilizando archivos properties, para definir multiples perfiles utilizando archivos yaml solo es necesario crear un solo archivo para todos los perfiles de la aplicación veamos el ejemplo mencionado anteriormente pero utilizando archivos yaml.
spring: profiles: active: dev --- spring: profiles: dev com: raidentrance: app: name: Spring boot dev --- spring: profiles: qa com: raidentrance: app: name: Spring boot qa --- spring: profiles: prod com: raidentrance: app: name: Spring boot prod
Como se puede observar a diferencia de la definición con archivos properties es posible definir en un solo archivo yaml el perfil por defecto a utilizar y las propiedades para los diferentes entornos.
Los demás componentes del código serán iguales para ambas formas.
Puedes encontrar el código completo en el siguiente enlace https://github.com/raidentrance/spring-boot-example/tree/part7-profiles .
Si te gusta el contenido o tienes preguntas síguenos en nuestras redes sociales: https://twitter.com/geeks_mx y https://www.facebook.com/geeksJavaMexico/.
Autor: Alejandro Agapito Bautista
Twitter: @raidentrance
Contacto:raidentrance@gmail.com