Como manejar ambientes de desarrollo para un API profesional en AWS

Una vez que ya sabemos como utilizar API Gateway vale la pena aprender como manejarlo en un entorno de desarrollo profesional. Un API existe para que un cliente haga peticiones y por lo general los clientes de una API suelen ser aplicaciones a las que tiene acceso el usuario final.

Si se esta iniciando el desarrollo de un API, es muy probable que se este haciendo alguna aplicación al mismo tiempo. Tal vez una app web o una app móvil. Las aplicaciones cliente necesitan de la mayor certeza posible al momento de realizar peticiones en el API, ya que encontrarse con errores o cambios inesperados en los parámetros de entrada o de salida, puede terminar afectando sus tiempos de desarrollo.

Para evitar estos problemas comúnmente se utiliza el concepto de ambientes de desarrollo (development environments). El punto de los ambientes de desarrollo es tener diferentes versiones de todo el ambiente en el que trabaja el aplicativo. De esta manera podemos tener separada una versión publicada para que las aplicaciones puedan hacer uso de ella y una versión de desarrollo que se puede utilizar para implementar nuevas funcionalidades.

¿Cómo se logra esto para un API en AWS?

Veamos un ejemplo.


Escenario

Pongamos un ejemplo complejo.

Tenemos un proyecto para una app web de recomendaciones de películas y series.

El proyecto será desarrollado por 2 equipos: uno de Front-End y uno para su respectivo Back-End (compuesto de un API y una base de datos).

Así mismo hay varios equipos de QA (Quality Assurance) encargados de probar tanto la parte técnica del API como la lógica de negocio (validar los datos contenidos en la base de datos).

El proyecto se lanzará a producción para el público como MVP (Minimum Viable Product) Producto Mínimo Viable. Esto simplemente quiere decir que será accesible a los usuarios finales sin necesariamente tener todas las características planeadas terminadas, sólo las esenciales.

El primer equipo en incorporarse al proyecto es el equipo de Back-End y se define que lo primero para desarrollar es un par de servicios: una lista de sugerencias y un objeto con el detalle de una película.

Suponiendo que estés utilizando API Gateway y Lambda lo más recomendable es qué utilices los Stages y Deployments del servicio de API Gateway y los Alias y Versions de Lambda.

*Nota: Si estas utilizando otro servicio como alguna base de datos, también sería ideal crear una instancia diferente para cada ambiente de desarrollo que necesites.

Con esto en mente lo ideal es tener un proceso de despliegue con 4 ambientes de desarrollo:

dev

El ambiente dónde los desarrolladores trabajarán la mayor parte del tiempo. Aquí es dónde se prueban e implementan nuevas funcionalidades y librerías. Otros equipos pueden hacer peticiones a esta versión, pero no se les garantiza que funcionará de manera consistente.

qa

El ambiente dónde se tendrá el código con las nuevas funcionalidades. Este ambiente es el que deberán utilizar los equipos de QA para realizar sus pruebas y documentar y reportar incidencias. Ya sean de la lógica del negocio (cómo algun dato que no haga sentido) o técnicas (cómo errores o inconsistencia en los parámetros de entrada o salida).

staging

El ambiente dónde se tendrá el código listo y aprobado por QA para lanzarse a producción. Debe estar garantizado que el código de esta versión funciona correctamente, ya que es a dónde otros equipos de desarrollo (como el web y el móvil) realizarán peticiones para integrar sus propios aplicativos con el API. Puedes ver este ambiente como el ambiente de pre-producción.

prod

El ambiente de producción tendrá el código con la funcionalidad que estén utilizando los usuarios actualmente. Dado que cualquier error en este ambiente podría afectar gravemente el negocio, nunca se debe publicar código directamente en este ambiente sin haber pasado por las fases anteriores y siempre se debe tener la versión funcional a la mano para poder restaurar el ambiente en caso de que se necesite.

Proceso para nuevos requerimientos

Despliegue en dev

El ambiente dev es el que mas simple de todos los ambientes.

Para empezar crea un par de funciones lambda:

  • movie-suggestions-dev
  • movie-detail-dev

Nota: Te recomiendo que le agregues alguna clase de indicador a estas lambdas para que se diferencien de los otros ambientes. En mi caso le agregó el sufijo dependiendo del ambiente.

Ahora agrega un Stage (Etapa) en API Gateway llamado dev con las rutas de los APIs llamando a sus respectivas lambdas.

  • GET /movie => movie-detail-dev
  • GET /movie/suggestions => movie-suggestions-dev

Esto no es nada nuevo. Es solo lo que harías para cualquier API Gateway con Lambda.

Diagrama mostrando que los desarrolladores tienen acceso al ambiente de dev.

Despliegue en QA

Una vez todo esta funcionando en dev es momento de subir estos cambios al ambiente de qa donde se harán pruebas y se validará que todo funcione de acuerdo a lo planeado.

Para ello necesitas crear otro par de funciones lambdas:

  • movie-suggestions-qa
  • movie-detail-qa

Hasta ahora es lo mismo que hiciste para dev, pero para qa (y para los demás ambientes) necesitamos un par de cosas extra, antes de configurar API Gateway.


Crea una Versión para cada lambda:

  • movie-suggestions-qa-1
  • movie-detail-qa-1

Nota: AWS asigna automáticamente el número de la versión. Si por alguna razón necesitas reemplazar una versión (ya sea por un error o una actualización AWS incrementará el número de la versión por si mismo.

Crea un Alias para cada lambda:

  • movie-suggestions-qa-api
  • movie-detail-qa-api

El propósito de esto es que nos permitirá controlar fácilmente que versión de nuestro código va a ser accedida por nuestro API.

Un API puede correr ya sea una función lambda directamente, una versión o un alias.

A su vez un alias puede tener asignada cualquier versión de la lambda.

Nuestro API en qa mandará a llamar a los alias de las lambdas con sufijos -qa-api.

Esto permitirá que cuando tengamos diferentes versiones en una lambda podremos simplemente asignarsela a un Alias cuando queramos actualizarla o renovarla.

En el ambiente dev no hicimos esto ya que al ser el ambiente de trabajo, no necesitamos preservar versiones.


Finalmente agrega el stage qa en API Gateway con las rutas de los APIs llamando a sus respectivas lambdas.

  • GET /movie => movie-detail-qa-api
  • GET /movie/suggestions => movie-suggestions-qa-api

Con esto el equipo de QA ya tiene acceso a la nueva funcionalidad para validarla. Mientras tanto, si tienes nuevos servicios puedes trabajarlos en dev para así no cambiar lo qué esta probando QA.

Diagrama mostrando que los desarrolladores tienen acceso al ambiente de QA, pero también tiene acceso varios equipos de QA.

Caso especial: Detección de errores

Digamos que QA detectó un error al llamar al servicio GET /movie/suggestions.

El equipo sigue haciendo pruebas con GET /movie.

Para arreglar el error simplemente haz las correcciones necesarias en movie-suggestions-dev. Una vez hayas probado que todo este funcionando correctamente tienes que actualizar la versión del ambiente de qa.

Para ello crearás una nueva versión Lambda, en este caso: movie-suggestions-qa-2

Después solo tienes que actualizar el alias para que utilicé esta versión:

movie-suggestions-qa-api => movie-suggestions-qa-2

¡Listo! En esta ocasión no es necesario hacer cambios del lado de API Gateway.

Despliegue en Staging

Una vez que el código ha pasado las pruebas de QA es momento de subir el código al ambiente de staging.

Para este caso tenemos que hacer exactamente lo mismo que en staging : 2 lambdas con sus respectivas versiones y alias.

Versiones para cada lambda:

  • movie-suggestions-staging-1
  • movie-detail-staging-1

Alias para cada lambda:

  • movie-suggestions-staging-api
  • movie-detail-staging-api

Finalmente agrega el stage staging en API Gateway con las rutas de los APIs llamando a sus respectivas lambdas.

  • GET /movie => movie-detail-staging-api
  • GET /movie/suggestions => movie-suggestions-staging-api

El código en esta fase ya fue debidamente probado por lo que otros equipos, como el de front-end, ya pueden hacer uso de este ambiente para desarrollar la integración con el API. El código normalmente se acumulará aquí hasta que llegué la siguiente fecha de release a producción.

El código en staging es código que se garantiza que funciona correctamente, por lo qué nunca se le debe hacer un cambio sin antes avisar a quienes dependan de él. Los otros equipos harán sus propias pruebas en su propios ambientes utilizando nuestro staging.

Nota: Dependiendo del proyecto a veces se le da acceso a otros equipos desde el ambiente de qa. Esto se hace con la intención de agilizar su desarrollo permitiendoles preparar funcionalidad. Aún si ese es el caso, las garantías de funcionamiento permanecen igual. Sólo el código en staging en adelante se garantiza que funcione correctamente.

Diagrama mostrando que los desarrolladores y varios equipos de QA tienen acceso al ambiente de Staging, pero también tienen acceso algunos otros clientes.

Despliegue en Prod

Una vez que llegué la fecha de release (y que se haya completado la integración de las funcionalidades del API por otros equipos) es momento de subir el código al ambiente de prod.

Se hace lo mismo que en qa y staging : 2 lambdas con sus respectivas versiones y alias.

Versiones para cada lambda:

  • movie-suggestions-prod-1
  • movie-detail-prod-1

Alias para cada lambda:

  • movie-suggestions-prod-api
  • movie-detail-prod-api

Porsupuesto también se corren pruebas exhaustivas para este ambiente, dado que es el que será utilizado por la apps que utilice el usuario final. Sin embargo llegados a este punto las probabilidades de que la actualización tenga algun error son mínimas, ya que para eso nos ayudó validar en los ambientes anteriores.

Diagrama mostrando que los desarrolladores, varios equipos de QA y algunos clientes tienen acceso al ambiente de Prod. Pero también tienen acceso los usuarios finales.

¡Y con esto terminaste de hacer un flujo de deployment profesional!

Como ves el flujo para un proyecto real de desarrollo es mucho más laborioso ya que se tiene que cuidar más las versiones del código tanto para otros equipos cómo para el usuario final.

Frecuentemente termina dando más trabajo el hacer las actualizaciones entre ambientes que realmente implementar los nuevos requerimientos. Sin embargo es esencial saber como manejar este flujo de trabajo porque ayuda a reducir problemas de downtime significativamente.