0% encontró este documento útil (0 votos)
94 vistas

Creando Un API-Rest Con AWS Lambda y API-Gateway - Paradigma

El documento describe la creación de un API REST utilizando AWS Lambda y API Gateway con una arquitectura serverless. Explica que AWS Lambda permite ejecutar código sin servidores, API Gateway gestiona los endpoints y métodos HTTP, y otras herramientas de AWS como S3 y CloudWatch se usan también. La arquitectura serverless permite escalar automáticamente el código sin preocuparse por servidores.

Cargado por

Samuel Román
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
94 vistas

Creando Un API-Rest Con AWS Lambda y API-Gateway - Paradigma

El documento describe la creación de un API REST utilizando AWS Lambda y API Gateway con una arquitectura serverless. Explica que AWS Lambda permite ejecutar código sin servidores, API Gateway gestiona los endpoints y métodos HTTP, y otras herramientas de AWS como S3 y CloudWatch se usan también. La arquitectura serverless permite escalar automáticamente el código sin preocuparse por servidores.

Cargado por

Samuel Román
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 9

Creando un API-Rest con AWS Lambda y API-

Gateway - Paradigma
Clip source: Creando un API-Rest con AWS Lambda y API-Gateway - Paradigma

Creando un API-Rest con AWS Lambda y


API-Gateway
El último proyecto que he realizado me ha permitido sumergirme hasta las profundidades de una de
las tecnologías que están más en boga hoy en día: AWS Lambda.

En este post voy a contar cómo ha sido mi experiencia montando un API-Rest totalmente con
arquitectura ServerLess.

El proveedor cloud que hemos escogido para este proyecto es Amazon, que nos ofrece los siguientes
productos:

API-Gateway: servicio totalmente administrado que facilita a los desarrolladores la publicación,


el mantenimiento, la monitorización y la protección de API a cualquier escala con la que hemos
construido un API-Rest. Lo vemos en detalle más adelante.
Lambda: permite ejecutar código sin aprovisionar ni administrar servidores. Es la capa que actúa
como controladora de los endpoints definidos en el API-Gateway.
S3: es el responsable de, entre otras cosas, almacenar el código de las funciones Lambda, que
utilizamos para desplegar éstas gracias a nuestro proceso de CI/CD.
CloudWatch: es la pieza que nos proporciona los logs de aplicación.
También utilizamos un par de elementos externos a AWS: una instancia de MongoDB desplegada
en cloud y otra de SQL Serve****r (éste es legacy y por ello no la incluyo en el stack de AWS).

Vamos a ver un poco más en detalle todas las piezas que componen nuestro puzle:

Qué es ServerLess
ServerLess es un tipo de arquitectura que**, como su propio nombre indica, no precisa de un
servidor**. ¿Qué quiere decir esto?, ¿dónde se va a ejecutar nuestro código si no hay un servidor?

Tradicionalmente, cuando programamos, tenemos que ser muy conscientes de dónde se va a


desplegar nuestro código, qué memoria tiene, cómo escala... Las arquitecturas ServerLess tratan de
solventar esos problemas por nosotros, para que nos podamos centrar en lo realmente importante:
el código.

Las arquitecturas FaaS (Functions as a Server) nos proporcionan una infraestructura


autogestionada, que nos permite ejecutar directamente nuestro código reaccionando a eventos.

Estos eventos pueden ser tanto eventos web como eventos provenientes de otras partes de la
infraestructura.

Analicemos en este ejemplo cómo sería la subida de un fichero al servidor. Nuestra función se
ejecutaría de la siguiente forma:

Se despliega un contenedor gestionado por la propia infraestructura de AWS Lambda,


totalmente transparente para nosotros.
El escalado es automático en función del número de peticiones que tengamos, sin que nos
tengamos que preocupar por ello.
No es necesario dimensionado de máquinas, ni de nada que tenga que ver con la maquina
física.
Los gigantes de la computación en la nube están apostando muy fuerte por las arquitecturas
ServerLess. Amazon ha incorporado muchas novedades en su último AWS re:invent2017.

Google también está apostando fuerte con Google Cloud Functions y Azure con Azure Functions.
Qué es AWS Lambda
Como ya hemos visto en el punto anterior, las lambdas son funciones que se caracterizan por
desempeñar un objetivo muy concreto, como reaccionar ante la subida de un fichero o un evento
web.

En el caso de la plataforma de Amazon son multilenguaje, se pueden escribir en Java, Phyton, Node.js
y más recientemente han incorporado GO, del que dicen es el lenguaje con la mejor performance.

Vemos un ejemplo de función lamba en Node.js:

exports.handler = function(event, context) {


// Do your stuff
}
}

Como podemos ver, es muy simple. Solo necesitamos un handler, que es el que ejecutará nuestro
código. Esta función recibe dos parámetros event y context y, opcionalmente, callback.

El event es el evento que desencadena (trigger) la ejecución de una función lambda. El context nos da
información acerca de la lambda: tiempo de ejecución pendiente, alias de la función lambda
invocada...

Veamos algunos ejemplos de triggers. Una función lambda puede ser invocada entre otros triggers
por uno de estos:

Por una subida de un fichero a S3.


Una publicación de un topic en Amazon SNS.
Inserción en dynamoDB.
Llamada a un endpoint de un API, mediante APIGateway.
Una lambda es un contenedor que se levanta en la infraestructura de AWS y nos permite
ejecutar el código que hemos definido en la función.

Cada petición concurrente que llega, si hablamos de un API-Rest, levanta uno de estos contenedores.
Por defecto AWS ha determinado que el número de contenedores concurrentes es 1000 pudiendo
configurarse para aumentar este número.
Los contenedores se reutilizan, es decir, cuando la ejecución de una lambda finaliza no se destruye su
contenedor inmediatamente, sino que se queda levantado a la espera de nuevas peticiones, pero no
tenemos control sobre el ciclo de vida de este contenedor.

Cada función lambda se puede configurar para que disponga de más memoria. A más memoria más
coste y mejor será el contenedor sobre el que se despliegue.

En el caso de Node, el desplegable de una lambda es un zip que incluye el handler y los ficheros .js
necesarios que se requieran desde el handler y la carpeta node_modules con las dependencias
necesarias para ejecutar nuestra lambda.

Qué es el API Gateway


Es la capa de API-management de AWS. Para que nos entendamos, el API-Gateway es donde
creamos nuestro API, donde definimos los endpoints, métodos http y las integraciones que tienen
todos estos.

En nuestro caso, todas los endpoints integran con AWS Lambda.

Además en el API-Gateway gestionamos los entornos (stages), definimos variables por entorno,
nos permite documentar nuestros endpoints, mockearlos por ejemplo cuando la integración no
está lista, securizarlos...

Ejemplo de API, definido con API-Gateway.


Gestión y organización del código
Alguna de las preguntas que nos vienen a la cabeza a la hora de afrontar un proyecto basado en
microservicios son:

¿Cómo organizo el código?


¿Cómo gestiono las dependencias entre paquetes?
¿Repositorio único o repositorio por cada uno de los microservicios?
¿Gestión de la configuración?
Antes de nada, aclarar que decidimos usar NodeJS para construir nuestras funciones lambda y,
gracias a eso, cada función lambda es un paquete de NodeJS, que puede ser publicado en un registry
privado.

Después de bastantes días de investigación y diversas pruebas, optamos por el patrón mono-repo.
Este patrón, como su nombre indica, es un único repositorio que alberga todos los paquetes.

Para ello usamos una herramienta llamada Lerna, que nos facilita la vida a la hora de ejecutar
acciones como:

Build de todos nuestros paquetes con su comando lerna bootstrap.


Clean con lerna clean.
Lanzar todos los test con Lerna run test.
Ejecutar un script personalizado en cada uno de nuestros paquetes, con lerna run .
Y quizá lo más importante: nos informa qué paquetes se han modificado desde el último
commit. De esta forma podemos construir sólo los microservicios que hemos actualizado,
dejando al resto tal y como están gracias a la instrucción lerna updated.
Al final nos queda en nuestro repositorio principal un directorio denominado packages, del que
cuelgan todos los módulos npm que componen la aplicación, cada uno con su versión.

Gestión de la configuración
Comencemos por explicar qué información manejamos en la configuración de nuestro proyecto.
En nuestro caso, en el módulo config manejamos la información que nos conecta con las bases de
datos, configuraciones de seguridad, etc… que varían según el entorno en el que nos movamos.

Más adelante hablaremos de los entornos y cómo hemos resuelto este escollo en ServerLess, ya que
como hemos dicho anteriormente aquí no hay maquinas.
Para solucionar esta problemática típica de arquitecturas basadas en microservicios, optamos en
primera instancia por una función lambda, que sería invocada cada vez que se llamase a una de las
otras funciones.

Los beneficios fueron muchos, entre otros poder cambiar la configuración en caliente, sin afectar
al resto de funciones, ya que cada vez que una función fuese llamada, invocará a la lambda de
configuración para obtener la información que nos permite, entre otras cosas, conectar con la base
de datos correspondiente.

Este primer aproach lo descartamos, ya que nos dimos cuenta que muy pocas veces íbamos a
cambiar esa configuración. Por contra, estamos aumentando el coste, ya que por cada llamada a un
endpoint íbamos a realizar dos.

Finalmente optamos por una dependencia interna, creamos un módulo npm que sería inyectado
como una dependencia interna en nuestros paquetes. Así solventamos el problema del coste, pero
sin embargo, un cambio en este módulo nos obligó a re-desplegar todos los módulos que
dependían de él.

Gestión de las dependencias


Lerna nos facilita la gestión de las dependencias, todo son módulos npm que se construyen con npm
install. Además, nos facilita la instalación de todas ellas con lerna bootstrap.

Para nuestra integración continua, hemos definido diferentes niveles de modelos, con un sistema de
pesos que instala las dependencias siguiendo un orden establecido.

De esta forma tenemos el modulo config; paquetes denominados services, que se utilizan para
extraer código común y que pueda ser reutilizable entre lambdas; y, por último, muy recientemente
hemos introducido el concepto de controller.

Un controller es una lambda en la que manejamos un CRUD sobre un resource. Imaginad que
tenemos una entidad libros, como sabéis en un API Rest esta entidad se explota con los siguientes
endpoints:

[GET] /books obtiene la lista de libros.


[POST] /books da de alta un nuevo libro.
[PUT] /books/:bookid hace un update total del libro.
[PATCH] /books/:bookid hace una actualización parcial del libro.
[DELETE] /books/:bookid borra un libro.
Inicialmente creamos una lambda por cada endpoint y, con el paso del tiempo, nos dimos cuenta
que tanta granularidad iba haciendo que nuestro proyecto fuera creciendo en número de lambdas.

Esto hizo, entre otras cosas, que se incrementasen los tiempos de despliegue y fue por lo que
decidimos introducir el concepto de controller, que agrupa en una única lambda todas las
operaciones sobre una entidad en concreto, pasando de 5 funciones lambda a una única.

Como todo tiene su lado bueno y su lado malo. El lado bueno es evidente: menos paquetes. El
malo es que perdemos en independencia entre métodos, escalado de un método en concreto,
que tenga un uso más exhaustivo; y también perdemos la independencia de los logs.

En conclusión, con Lerna gestionamos todas las dependencias, definimos módulos que no son
lambdas, sino librerías npm locales, que nos permiten reutilizar código, y hacer menos código
repetido.

Gestión de Entornos
Hemos definido diferentes entornos para nuestro proyecto dev, pre y pro, pero la integración
continua queda fuera del ámbito de este artículo. Lo que quiero destacar es que se pueden generar
diferentes entornos partiendo del mismo código, os explico cómo a continuación.

En las lambdas tenemos alias y versiones. Una versión es cada actualización que hacemos de
nuestro código. En lambda son secuenciales 1,2,3… y no admite versionados custom. Por otro lado,
alias son punteros a versiones.

Vamos a poner un ejemplo. Tenemos una función lambda “myLambda” y el siguiente escenario:

Lo que nos indica este escenario es que dev apunta a la versión 10. que es un .zip con la versión más
reciente.

En pre hemos estado probando la versión 8 y, tras validarla, la hemos subido a pro. Tanto en pre
como en pro apuntamos a la misma versión, pero ¿cómo hacemos para que accedan a diferentes
bases de datos, por ejemplo?
Para solucionar este problema, lo que tenemos que hacer es parametrizar el API-Gateway. Es decir,
en nuestro API-Gateway lo que hacemos es una template de nuestros endpoint, de forma que en
lugar de apuntar a una lambda en concreto apuntamos a una plantilla que será de la forma
myLambda:${myStageVariable}.

Aquí vemos, los diferentes Stages (entornos) que hemos creado y como se definen variables para
ellos.
myStageVariable se define a nivel de cada uno de los diferentes stages. En el caso de la foto de arriba,
nuestra variable se define como lambdaAlias y su valor es acceptance.

Cuando invoquemos a un endpoint en nuestro API, nuestra integración sustituirá la stageVariable


definida en la template del endpoint por el valor de la función en el stage correspondiente.
En la imagen podemos ver, en el apartado Lambda Function, la función lambda que invocamos, junto
la variable que define su alias.
En consecuencia, invocamos a un alias de función en lugar de a la propia función.

Concluyendo...
Hemos creado un API-Rest definiendo nuestros endpoints con AWS API-Gateway y hemos
conseguido generar diferentes entornos en nuestro API.

Además, invocamos a las funciones lambda cuyo alias se corresponde con el entorno, permitiendo
tener diferentes configuraciones y diferentes versiones de código por entorno.

Estos son los pasos básicos que necesitas para crear un API-Rest con AWS Lambda y API-Gateway.
¿Te atreves a probar tú?

También podría gustarte