SlideShare una empresa de Scribd logo
IBERMATICA S.A
2018
Aprendiendo AWS Lambda
con API Gateway y
DynamoDB
Tutoriales – Explorando AWS con Java
Abimael Desales Lopez
@JavaDevelopersMexico
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
AprendiendoAWSLambdaconAPIGatewayyDynamoDB
1. Resumen
AWS Lambda es un servicio computacional serverless provisto por Amazon Web Services.
En este tutorial, discutiremos cómo publicar una función Lambda como endpoint REST,
usando la API Gateway de AWS.
Echaremos un vistazo con detalle a los siguientes temas:
 Conceptos básicos y terminos de la API Gateway
 Integración de funciones Lambda con API Gateway usando la integración de Lambda
Proxy
 Creación de una API, su estructura, y cómo mapear los recursos de la API sobre
funciones Lambda
 Deployment y prueba de la API
2. Bases y Términos
API Gateway es un servicio completamente administrado que permite a los desarrolladores
crear, publicar, mantener, monitorear, y asegurar APIs en cualquier escala.
Podemos implementar una interfaz de programación basada en HTTP consistente y escalable
(servicios RESTful) para accesar servicos de backend como funciones Lambda, además de
servicios AWS (p.e., EC2, S3, DynamoDB), y cualquier endpoint HTTP.
Las características incluyen, sin limitarse a:
 Gestión de tráfico
 Autorización y control de acceso
 Monitoreo
 Gestión de versionamiento de API
 Peticiones throttling para prevenir ataques
Al igual que AWS Lambda, API Gateway es automáticamente escalado y se factura por llamada
a la API.
Se puede encontrar información más detallada sobre el pricing en la documentación oficial.
2.1. Términos
API Gateway es un servicio AWS que soporta la creación, deploying, y gestión de una interfaz
de programación de aplicación RESTful para exponer endpoints de backend HTTP, funciones
Lambda AWS, y otros servicios AWS.
Una API Gateway es una colección de recursos y métodos que pueden ser integrados con
funciones Lambda, otros servicios AWS, o endpoints HTTP en el backend. La API consiste de
recursos que forman la estructura de la API. Cada recurso de la API puede exponer uno o más
métodos de API que deben tener verbos HTTP únicos.
Para publicar una API, tenemos que crear un API deployment y asociarlo con una stage. Una
stage es como una fotografía al momento de la API. Si redeployamos una API, podemos ya sea
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
actualizar una stage existente o crear una nueva. Por ello, son posibles diferentes versiones de
una API al mismo tiempo, por ejemplo una stage dev, una stage test/qa , y aún múltiples
versiones de producción, como v1, v2, etc.
Lambda Proxy integration es una configuración simplificada para la integración entre funciones
Lambda y la API Gateway.
La API Gateway envía la request completa como un input a una función Lambda de backend.
En cuanto a la response, la API Gateway transforma la salida de la función Lambda atrás a una
respuesta HTTP del frontend.
3. Generación del Proyecto e incluir dependencias Maven
Generamos un nuevo proyecto Maven y lo nombramos de la siguiente forma:
Necesitaremos agregar las siguientes dependencias al archivo pom.xml:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>1.3.0</version>
</dependency>
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Además de eso, también necesitamos las siguientes librerías json y gson de google:
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.5</version>
</dependency>
Se necesita agregar el plugin shade de Maven:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
4. Desarrollando y Deployando las Funciones Lambda
En esta sección, desarrollaremos y construriemos nuestras funciones Lambda en Java, las
deployaremos usando la Consola AWS, y correremos una prueba rápida.
Debido a que queremos demostrar las capacidades básicas de la integración de la API Gateway
con Lambda, crearemos dos funciones:
 Función 1: recibe un payload desde la API, usando un método PUT, para grabar en DB.
 Función 2: demuestra cómo usar un parámetro HTTP de ruta o un parámetro de cadena
de consulta HTTP que viene de la API
En cuanto a la implementación, crearemos una clase que implemente RequestHandler, que tiene
dos métodos — uno por cada función.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
4.1. Modelo
Antes de implementar el request handler real, echemos una mirada rápida a nuestro modelo de
datos:
public class Prestamo {
private int id;
private String tipo;
public Prestamo(String json) {
Gson gson = new Gson();
Prestamo request = gson.fromJson(json, Prestamo.class);
this.id = request.getId();
this.tipo = request.getTipo();
}
public String toString() {
Gson gson = new GsonBuilder().setPrettyPrinting().create();
return gson.toJson(this);
}
// getters y setters
}
Nuestro modelo consiste de una clase sencilla Prestamo, que tiene solo dos propiedades. La
única parte notable es el constructor Prestamo(String), que acepta una String JSON.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
4.2. Implementación de la clase RequestHandler
Crearemos una implementación de la interface RequestStreamHandler:
public class APIGatewayHandler implements RequestStreamHandler {
private static final String DYNAMODB_TABLE_NAME = System.getenv("TABLE_NAME");
private static final Regions REGION = Regions.US_WEST_2;
@SuppressWarnings("unchecked")
public void handleRequest(InputStream input, OutputStream output, Context
context) throws IOException {
// implementación
}
public void handleGetByParam(InputStream input, OutputStream output, Context
context) throws IOException {
// implementación
}
}
La interface RequestStreamHander define solo un método, handleRequest(). De cualquier forma
podemos definir algunas funciones en la misma clase, como lo hemos hecho aquí. Otra opción
sería crear una implementación de RequestStreamHandler para cada función, pero no la
abordaremos en este tutorial.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Por simplicidad, en nuestro caso específicamente hemos elegido el primero. Sin embargo, la
elección se debe hacer considerando cada caso, tomamos en consideración factores como
performance y mantenibilidad de código.
Además leeremos el nombre de una tabla DynamoDB desde la variable de entorno
TABLE_NAME. Definiremos esa variable más tarde durante el deployment.
4.3. Implementación de la Función 1
En nuestra primera función, queremos demostrar cómo obtener un payload (al igual que
desde una request PUT o POST) desde la API Gateway:
public void handleRequest(InputStream input, OutputStream output, Context context)
throws IOException {
JSONParser parser = new JSONParser();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
JSONObject responseJson = new JSONObject();
AmazonDynamoDBClient cliente = new AmazonDynamoDBClient();
cliente.setRegion(Region.getRegion(REGION));
DynamoDB dynamoDb = new DynamoDB(cliente);
try {
JSONObject event = (JSONObject) parser.parse(reader);
if (event.get("body") != null) {
Prestamo prestamo = new Prestamo((String) event.get("body"));
dynamoDb.getTable(DYNAMODB_TABLE_NAME).putItem(new PutItemSpec()
.withItem(
new Item().withNumber("id", prestamo.getId()).withString("tipo",
prestamo.getTipo())));
}
JSONObject responseBody = new JSONObject();
responseBody.put("mensaje", "Nuevo item creado");
JSONObject headerJson = new JSONObject();
headerJson.put("x-custom-header", "mi valor de header personalizado");
responseJson.put("statusCode", 200);
responseJson.put("headers", headerJson);
responseJson.put("body", responseBody.toString());
} catch (ParseException pex) {
responseJson.put("statusCode", 400);
responseJson.put("exception", pex);
}
OutputStreamWriter writer = new OutputStreamWriter(output, "UTF-8");
writer.write(responseJson.toString());
writer.close();
}
Como lo comentamos antes, más adelante configuraremos la API para que use la
integración del proxy de Lambda. Esperamos que la API Gateway pase la request
completa a la función Lambda en el parámetro InputStream.
Todo lo que tenemos que hacer es elegir los atributos relevantes de la estructura JSON
contenida.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Como podemos ver, el método básicamente consiste de tres pasos:
1. Ir a buscar el objeto body desde nuestro input stream y crear un objeto Prestamo de él.
2. Almacenar ese objeto Prestamo en una tabla DynamoDB.
3. Construir un objeto JSON, que pueda contener varios atributos, como un body para la
response, headers personalizados, así como un código de estatus HTTP.
Un punto que vale la pena mencionar aquí: la API Gateway espera que el body sea
una String (tanto para la request como para la response).
Ya que esperamos tener una String como body desde la API Gateway, casteamos el body a
String e inicializamos nuestro objeto Prestamo:
Prestamo prestamo = new Prestamo((String) event.get("body"));
La API Gateway además espera que la respuesta de body sea una String:
responseJson.put("body", responseBody.toString());
Este tema no se menciona explícitamente en la documentación oficial. Sin embargo, si
observamos de cerca, podemos ver que el atributo es una String en ambos snippets, tanto para la
request como para la response.
La ventaja debe ser clara: aún si el formato es JSON entre la API Gateway y la función Lambda,
el body real puede contener texto plano, JSON, XML, o cualquier otra cosa. Entonces es
responsabilidad de la función Lambda administrar el formato correctamente.
Posteriormente veremos cómo se ven el body de la request y response cuando probemos
nuestras funciones en la Console AWS.
Lo mismo también aplica a las siguientes dos funciones.
4.4. Implementación de la Función 2
En un segundo paso queremos demostrar cómo usar un parámetro path o un parámetro
query string para retomar un item Prestamo desde la base de datos usando sus ID:
public void handleGetByParam(InputStream input, OutputStream output, Context context)
throws IOException {
JSONParser parser = new JSONParser();
BufferedReader reader = new BufferedReader(new InputStreamReader(input));
JSONObject responseJson = new JSONObject();
AmazonDynamoDBClient client = new AmazonDynamoDBClient();
client.setRegion(Region.getRegion(REGION));
DynamoDB dynamoDb = new DynamoDB(client);
Item result = null;
try {
JSONObject event = (JSONObject) parser.parse(reader);
JSONObject responseBody = new JSONObject();
if (event.get("pathParameters") != null) {
JSONObject pps = (JSONObject) event.get("pathParameters");
if (pps.get("id") != null) {
int id = Integer.parseInt((String) pps.get("id"));
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id);
}
} else{
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
if (event.get("queryStringParameters") != null) {
JSONObject qsp = (JSONObject) event.get("queryStringParameters");
if (qsp.get("id") != null) {
int id = Integer.parseInt((String) qsp.get("id"));
result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id);
}
}
}
if (result != null) {
Prestamo prestamo = new Prestamo(result.toJSON());
responseBody.put("Prestamo", prestamo);
responseJson.put("statusCode", 200);
} else {
responseBody.put("mensaje", "Item no encontrado");
responseJson.put("statusCode", 404);
}
JSONObject headerJson = new JSONObject();
headerJson.put("x-custom-header", "mi valor de header personalizado");
responseJson.put("headers", headerJson);
responseJson.put("body", responseBody.toString());
} catch (ParseException pex) {
responseJson.put("statusCode", 400);
responseJson.put("exception", pex);
}
OutputStreamWriter writer = new OutputStreamWriter(output, "UTF-8");
writer.write(responseJson.toString());
writer.close();
}
Nuevamente, los tres pasos relevantes:
1. Checamos si están presentes un pathParameters o un array queryStringParameters con
un atributo id.
2. Si es true, usamos el valor correspondiente para solicitar un item Prestamo con ese ID
desde la base de datos.
3. Agregamos una representación JSON del item recibido a la response.
La documentación oficial provee una explicación más detallada del formato de input y formato
de output para Proxy Integration.
4.5. Construyendo el código
Nuevamente, podemos simplemente construir nuestro código usando Maven:
mvn clean package shade:shade
El archivo JAR será creado bajo la carpeta target.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
4.6. Creando la tabla en DynamoDB
Podemos crear la tabla como se explicó en AWS Lambda Usando DynamoDB con Java.
Vamos a elegir Prestamo como nombre de la tabla, id como nombre de la llave primaria, y
Number como el tipo para la llave primaria.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
4.7. Deployando el código vía la Consola AWS
Después de construir nuestro código y crear la tabla, ahora podemos crear las funciones y cargar
el código.
Esto se puede hacer repitiendo los pasos 1-5 del artículo AWS Lambda con Java, una vez por
cada uno de nuestros métodos.
Vamos a usar los siguiente nombres de funciones:
 StorePrestamosFunction para el método handleRequest (función 1)
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
 GetPrestamoByHTTPParamFunction para el método handleGetByParam (función 2)
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
También hemos definido una variable de entorno TABLE_NAME con el valor de “Prestamo”.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
4.8. Probando las Funciones
Antes de continuar con la parte real de la API Gateway, podeos correr una prueba rápida en la
Consola AWS, solo para checar que nuestras funciones Lambda estén corriendo de forma
correcta y puedan manejar el formato de Proxy Integration.
Probar una función Lambda desde la Consola AWS se hace como se describe en el artículo
AWS Lambda con Java.
Sin embarho, cuando creamos un evento de prueba, tenemos que considerar el formato
especial de Proxy Integration, que están esperando nuestras funciones. Podemos ya sea usar la
plantilla API Gateway AWS Proxy y personalizarla de acuerdo a nuestras necesidades, o
podemos copiar y pegar los siguientes eventos:
Para la función StorePrestamoFunction, debemos usar este:
{
"body": "{"id": 1, "tipo": "Fiduciario"}"
}
Como lo discutimos antes, el body debe tener el tipo String, aún si contiene una estructura
JSON. La razón es que el API Gateway enviará sus requests en el mismo formato.
Debería retornar la siguiente respuesta:
{
"isBase64Encoded": false,
"headers": {
"x-custom-header": "mi valor de header personalizado"
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
},
"body": "{"mensaje":"Nuevo item creado"}",
"statusCode": 200
}
Aquí, podemos ver que el body de nuestra response es una String, aunque contiene una
estructura JSON.
Vamos a ver la input para la función GetPrestamoByHTTPParamFunction.
Para probar la funcionalidad de parámetro path, el input se vería como esto:
{
"pathParameters": {
"id": "1"
}
}
Y el input para enviar un parámetro de query string sería:
{
"queryStringParameters": {
"id": "1"
}
}
Como una response, deberíamos tener lo siguiente para los métodos de ambos casos:
{
"headers": {
"x-custom-header": "Mi valor de header personalizado"
},
"body": "{"Prestamo":{n "id": 1,n "tipo": "Fiduciario"n}}",
"statusCode": 200
}
Nuevamente, el body es una String.
Consultando la tabla de DynamoDB podemos darnos cuenta de que realmente el valor se
encuentra persistido:
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
5. Creando y Probando la API
Después que hemos creado y desplegado las funciones Lambda en la sección anterior, ahora
podemos crear la API real usando la Consola AWS.
Vamos a ver el flujo básico a seguir:
1. Crear una API en nuestra cuenta AWS.
2. Agregar un recurso a la jerarquía de recursos de la API.
3. Crear uno o más métodos para el recurso.
4. Configurar la integración entre un método y la función Lambda perteneciente.
Repetiremos los pasos 2-4 por cada una de nuestra fos funciones en las siguientes
secciones.
5.1. Creando la API
Para crear la API, tendremos que:
1. Firmarnos a la consola de la API Gateway en
https://console.aws.amazon.com/apigateway
2. Hacer click en “Get Started” y seleccionar “New API”
3. Escribir el nombre de nuestra API (APIPrestamosLambdaDynamoDB) y confirmar
haciendo click en “Create API”
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Habiendo creado la API, ahora ya podemos crear la estructura de la API y ligarla a nuestra
funciones Lambda.
5.2. Estructura de la API para la funcción 1
Se necesitan los siguientes pasos para nuestra función StorePrestamosFunction:
1. Elige el elemento recurso padre bajo el árbol de “Resources” y luego selecciona “Create
Resource” del menú desplegable “Actions”. Luego, tenemos que hacer lo siguiente en el
pánel “New Child Resource”:
 Escribe “Prestamos” como el nombre en el campo de texto “Resource Name”
 Deja el valor default en el campo de texto “Resource Path”
 Selecciona “Create Resource”
2. Elige el recurso recién creado, selecciona “Create Method” del menú desplegable
“Actions”, y lleva a cabo los siguientes pasos:
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
 Elige PUT de la lista desplegable de métodos HTTP y luego chequea el ícono
de marca para guardar la elección.
 Deja “Lambda Function” como tipo de integración, y selecciona la opción
“Use Lambda Proxy integration”
 Selecciona la región de “Lambda Region”, donde deployamos nuestras
funciones Lambda anteriormente
 Escribe “StorePrestamosFunction” en “Lambda Function”
3. Elige “Save” y confirma con “OK” cuando te pregunte con “Add Permission to Lambda
Function”
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
5.3. Estructura de la API para la Función 2 – Path Parameters
Los pasos para nuestros parámetros path de recuperación son similares:
1. Elige el item de recurso /prestamos bajo el árbol de “Resources” y luego selecciona
“Create Resource” del menú desplegable Actions”. Luego, tenemos que hacer lo
siguiente en el panel New Child Resource:
 Escribe “Prestamo” como nombre en el campo de texto “Resource Name”
 Cambia el campo de texto “Resource Path” a “{id}”
 Elige “Create Resource”
2. Elige el recurso recién creado, selecciona “Create Method” del menú
desplegable “Actions”, y lleva a cabo los siguientes pasos:
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
 Elige GET de la lista desplegable de métodos HTTP y luego elige el ícono de
marca (check) para guardar la elección
 Deja “Lambda Function” como el tipo de integración, y selecciona la opción
“Use Lambda Proxy integration”
 Elige la región de “Lambda Region”, donde deployamos nuestras funciones
Lambda anteriormente
 Escribe “GetPrestamosByHTTPParamFunction” en “Lambda Function”
3. Elige “Save” y confirma con “OK” cuando se te solicite con “Add Permission to
Lambda Function”
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Nota: es importante aquí asignar el parámetro “Resource Path” a “{id}”, ya que nuestra función
GetPrestamosByPathParamFunction espera que este parámetro sea nombrado de esta forma.
5.4. Estructura de la API para la función 2 – Query String Parameters
Los pasos para recibir parámetros query string son un poco diferentes, ya que no tenemos que
crear un recurso, en vez de eso tenemos que crear un parámetro query para el parámetro
id:
1. Elige el recurso /prestamos bajo el árbol de “Resources”, selecciona “Create Method”
del menú desplegable “Actions”, y lleva a cabo los siguientes pasos:
 Elige GET desde la lista desplegable de métodos HTTP y luego selecciona el
ícono de marca para guardar la elección.
 Deja “Lambda Function” como tipo de integración, y selecciona la opción “Use
Lambda Proxy integration”
 Elige la región de “Lambda Region”, donde antes deployamos nuestras
funciones Lambda
 Escribe “GetPrestamosByHTTPParamFunction” en “Lambda Function”.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
2. Elige “Save” y confirma con “OK” cuando se te solicite con “Add Permission to
Lambda Function”
3. Elige “Method Request” en la derecha y lleva a cabo los siguientes pasos:
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
 Expande la lista de URL Query String Parameters.
 Haz click en “Add Query String”.
 Escribe “id” en el campo nombre, y elige el ícono de marca para guardar.
 Selecciona la marca de “Required”
 Haz click en el símbolo de lápiz a continuación de “Request validator” en lo
alto del pánel, selecciona “Validate query string parameters and headers”, y
selecciona el ícono de marca.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Nota: Es importante asignar el parámetro “Query String” a “id”, ya que nuestra función
GetPrestamosByHTTPParamFunction espera este parámetro para que sea nombrado
exactamente como este.
5.5. Probando la API
Nuestra API ahora está lista, pero aún no es pública. Antes de publicarla, primero queremos
correr una prueba rápida desde la Consola.
Para eso, podemos seleccionar el método respectivo a probar en el árbol de “Resources” y hacer
click en el botón “Test”. En la siguiente pantalla, podemos escribir nuestro input, como lo
enviaríamos con un cliente vía HTTP.
For StorePrestamosFunction, tenemos ue ingresar la siguiente estructura en el campo “Request
Body”:
{
"id": 2,
"tipo": "Nómina"
}
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Se obtiene como resultado lo siguiente:
Para la GetPrestamosByHTTPParamFunction con parámetros de path, tenemos que ingresar 2
como un valor en el campo “{id}” bajo “Path”.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Se obtiene el siguiente resultado al pulsar el botón Test:
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
Para la GetPrestamoByHTTPParamFunction con parámetros de query string, tenemos que
ingresar a tipo id=2 como valor en el campo “{prestamos}” bajo “Query Strings”.
Al hacer click sobre el botón Test nos da como resultado lo siguiente:
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
5.6. Deployando la API
Hasta ahora, nuestra API no era pública y por lo tanto solo estaba disponible desde la Consola
AWS.
Como lo discutimos antes, cuando deployamos una API, tenemos que asociarlo con una
stage, que es como un snapshot de la API al momento. Si redeployamos una API, podemos
ya sea actualizar una stage existente o crear una nueva.
Vamos a ver cómo se verá el esquema URL para nuestra API:
https://{restapi-id}.execute-api.{region}.amazonaws.com/{stageName}
Se requieren los siguientes pasos para deployment:
1. Elige la API particular en el pánel de navegación “APIs”
2. Elige “Actions” en el pánel de navegación Resources y selecciona “Deploy API” desde
el menú desplegable “Actions”
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
3. Elige “[New Stage]” desde la stage desplegable “Deployment stage”,
ingresa “QA” en “Stage name”, y opcionalmente proporciona una descripción de la
stage y deployment.
4. Dispara el deployment eligiendo “Deploy”
Después del último paso, la consola proveerá la URL raíz de la API, por ejemplo,
https://0skaqfgdw4.execute-api.eu-central-1.amazonaws.com/test.
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
5.7. Invocando el Endpoint
Ya que la API es ahora pública, podemos llamarla usando cualquier cliente HTTP que
queramos.
Con cURL, las llamadas serían como sigue.
StorePrestamosFunction:
curl -X PUT 'https://0skaqfgdw4.execute-api.eu-central-
1.amazonaws.com/qa/prestamos' 
-H 'content-type: application/json' 
-d '{"id": 3, "tipo": "Personal"}'
GetPrestamosByHTTPParamFunction para parámetros path:
curl -X GET 'https://0skaqfgdw4.execute-api.eu-central-
1.amazonaws.com/qa/prestamos/3' 
-H 'content-type: application/json'
GetPrestamosByHTTPParamFunction para parámetros query string:
curl -X GET 'https://0skaqfgdw4.execute-api.eu-central-
1.amazonaws.com/QA/prestamos?id=3' 
-H 'content-type: application/json'
Mismos casos de prueba pueden realizarse con un buen cliente REST como lo es la extensión
RESTClient de Mozzila Firefox, de la cual por simplicidad no profundizo en ello. A continuación
adjunto todos los screenshoots que espero puedas comprenderlos y seguirlos para replicar las
pruebas de este modo:
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
JavaDevelopersMexico
@Copyright 2018 Abimael Desales López
6. Conclusión
En este artículo, vimos cómo hacer funciones AWS Lambda disponibles como endpoints REST,
usando la API Gateway de AWS.
Exploramos los conceptos básicos y terminología de la API Gateway, y aprendimos cómo
integrar funciones Lambda usando Lambda Proxy Integration.
Finalmente, vimos cómo crear, deployar, y probar una API.
Como de costumbre. todo el código para este artículo está disponible en GitHub.
Este documento está basado en la documentación oficial de AWS y en consulta de algunos
otros sitios de internet:
https://docs.aws.amazon.com/index.html#lang/es_es
https://aws.amazon.com/es/serverless/developer-tools/
https://www.baeldung.com/aws-lambda-api-gateway
https://www.paradigmadigital.com/dev/distintas-maneras-trabajar-aws-lambda/
https://www.paradigmadigital.com/dev/creando-api-rest-aws-lambda-api-gateway/

Más contenido relacionado

PPTX
Pleased to meet you, Laravel
PDF
Servicios web
PDF
Laravel vc
PPTX
Definición de apis con swagger
KEY
Rails intro
PDF
Ruby on Rails - ETyC 2011
PDF
SG 09 Patrones de Integración Empresarial Apache Camel
PDF
Tutorial de cakePHP itst
Pleased to meet you, Laravel
Servicios web
Laravel vc
Definición de apis con swagger
Rails intro
Ruby on Rails - ETyC 2011
SG 09 Patrones de Integración Empresarial Apache Camel
Tutorial de cakePHP itst

La actualidad más candente (20)

PPT
Curso Java Avanzado 1 IntroduccióN Al Desarrollo Web
PDF
PPTX
Introducción a Laravel 5 - Un Framework para Artesanos Web
PPTX
MVC en CakePHP 2.0
PDF
SG 09 Patrones de Integración Empresarial Apache Camel (Draft)
PDF
Symfony en Drupal 8 - DrupalCamp Spain
PDF
2. Java Servlets (J2EE) - Curso 2005-2006
PPT
Desarrollando Una Mejor Experiencia De Usuario Con Ajax
ODP
Desarrollo de Aplicaciones con Ruby on Rails y PostgreSQL
PPT
Curso TIC de PHP y MSQL
PDF
Consumiendo servicios Restful en Xamarin.Forms
PDF
Estructura de Directorio de KumbiaPHP Framework versión 1.0 Spirit
PDF
Capacitacion Kumbia PHP Framework
PDF
Rails Plugins. Javier Ramirez
PDF
Programa en Rails como si Jugases con Lego. Javier Ramirez
PDF
Javier Ramirez Rails Plugins Pdf
PPTX
Servlets exposicion
Curso Java Avanzado 1 IntroduccióN Al Desarrollo Web
Introducción a Laravel 5 - Un Framework para Artesanos Web
MVC en CakePHP 2.0
SG 09 Patrones de Integración Empresarial Apache Camel (Draft)
Symfony en Drupal 8 - DrupalCamp Spain
2. Java Servlets (J2EE) - Curso 2005-2006
Desarrollando Una Mejor Experiencia De Usuario Con Ajax
Desarrollo de Aplicaciones con Ruby on Rails y PostgreSQL
Curso TIC de PHP y MSQL
Consumiendo servicios Restful en Xamarin.Forms
Estructura de Directorio de KumbiaPHP Framework versión 1.0 Spirit
Capacitacion Kumbia PHP Framework
Rails Plugins. Javier Ramirez
Programa en Rails como si Jugases con Lego. Javier Ramirez
Javier Ramirez Rails Plugins Pdf
Servlets exposicion
Publicidad

Similar a Aprendiendo AWS Lambda con API Gateway y DynamoDB (20)

PDF
GWT - Una introducción
PDF
Servicios web
PDF
Ejemplosencillocon rmi
ODP
Desarrollo de Apps Web en Ruby on Rails
PDF
Empezando con Play y reactive mongo (Segundo meetup Scala Perú Dec 2015)
PDF
Servicios web Extendido_error perl
PDF
Hands-on Spring 3: The next generation
PDF
Servicios web
PDF
Servicios web
PPTX
APIREST LARAVEL Y PHP.pptx
PPT
Corp. In. Tec. S.A. - Capacitaciones en Informática - Programación con CodeIg...
PPTX
Desarrollo Back-end Con React y node.pptx
PDF
POOABD (POO Aplicada a B Datos) - API JDBC - Parte 2
PDF
API REST conceptos (Rails-api)
PPTX
Charla
PDF
App engine
PDF
Servicios web
PDF
Tutorial de ReactJS.pdf completo para principiantes
PDF
App todo gas: WordPress no es solo para web
PPTX
Framework .NET 3.5 06 Operativa básica del framework .net
GWT - Una introducción
Servicios web
Ejemplosencillocon rmi
Desarrollo de Apps Web en Ruby on Rails
Empezando con Play y reactive mongo (Segundo meetup Scala Perú Dec 2015)
Servicios web Extendido_error perl
Hands-on Spring 3: The next generation
Servicios web
Servicios web
APIREST LARAVEL Y PHP.pptx
Corp. In. Tec. S.A. - Capacitaciones en Informática - Programación con CodeIg...
Desarrollo Back-end Con React y node.pptx
POOABD (POO Aplicada a B Datos) - API JDBC - Parte 2
API REST conceptos (Rails-api)
Charla
App engine
Servicios web
Tutorial de ReactJS.pdf completo para principiantes
App todo gas: WordPress no es solo para web
Framework .NET 3.5 06 Operativa básica del framework .net
Publicidad

Más de Abimael Desales López (17)

DOCX
Tutorial - Ordenar listas Java
PPTX
Tareas Programadas de Oracle con Toad 10
PDF
File Processing - Batch Process Execution
PDF
File Processing - Process Execution Solution
PDF
Tutorial - REST con java (JAX-RS 2.0)
PDF
Patrones de Integración Empresariales
PDF
Jpa modelos de componentes
PDF
Integrando sonar
PDF
Apache Camel - Parte II
PDF
Patrones de diseño
DOCX
Integración de Aplicaciones
DOCX
El mejor enfoque para una arquitectura orientada a servicios
DOCX
Orquestación de Servicios y SOA
PPTX
SOA: Principios de Diseño de Servicios - Parte II
PPTX
Orquestación o coreografía
DOCX
Analisis ¿No es eso para personas poco inteligentes?
PPTX
Conceptos introductorios al diseño de Servicios SOA
Tutorial - Ordenar listas Java
Tareas Programadas de Oracle con Toad 10
File Processing - Batch Process Execution
File Processing - Process Execution Solution
Tutorial - REST con java (JAX-RS 2.0)
Patrones de Integración Empresariales
Jpa modelos de componentes
Integrando sonar
Apache Camel - Parte II
Patrones de diseño
Integración de Aplicaciones
El mejor enfoque para una arquitectura orientada a servicios
Orquestación de Servicios y SOA
SOA: Principios de Diseño de Servicios - Parte II
Orquestación o coreografía
Analisis ¿No es eso para personas poco inteligentes?
Conceptos introductorios al diseño de Servicios SOA

Último (6)

DOCX
trabajo programacion.docxxdxxxddxdxxdxdxxxdxxdxdxd
PDF
Su punto de partida en la IA: Microsoft 365 Copilot Chat
PPTX
Derechos_de_Autor_y_Creative_Commons.pptx
PPTX
sistemas de informacion.................
PDF
AutoCAD Herramientas para el futuro, Juan Fandiño
PPTX
Conceptos basicos de Base de Datos y sus propiedades
trabajo programacion.docxxdxxxddxdxxdxdxxxdxxdxdxd
Su punto de partida en la IA: Microsoft 365 Copilot Chat
Derechos_de_Autor_y_Creative_Commons.pptx
sistemas de informacion.................
AutoCAD Herramientas para el futuro, Juan Fandiño
Conceptos basicos de Base de Datos y sus propiedades

Aprendiendo AWS Lambda con API Gateway y DynamoDB

  • 1. IBERMATICA S.A 2018 Aprendiendo AWS Lambda con API Gateway y DynamoDB Tutoriales – Explorando AWS con Java Abimael Desales Lopez @JavaDevelopersMexico
  • 2. JavaDevelopersMexico @Copyright 2018 Abimael Desales López AprendiendoAWSLambdaconAPIGatewayyDynamoDB 1. Resumen AWS Lambda es un servicio computacional serverless provisto por Amazon Web Services. En este tutorial, discutiremos cómo publicar una función Lambda como endpoint REST, usando la API Gateway de AWS. Echaremos un vistazo con detalle a los siguientes temas:  Conceptos básicos y terminos de la API Gateway  Integración de funciones Lambda con API Gateway usando la integración de Lambda Proxy  Creación de una API, su estructura, y cómo mapear los recursos de la API sobre funciones Lambda  Deployment y prueba de la API 2. Bases y Términos API Gateway es un servicio completamente administrado que permite a los desarrolladores crear, publicar, mantener, monitorear, y asegurar APIs en cualquier escala. Podemos implementar una interfaz de programación basada en HTTP consistente y escalable (servicios RESTful) para accesar servicos de backend como funciones Lambda, además de servicios AWS (p.e., EC2, S3, DynamoDB), y cualquier endpoint HTTP. Las características incluyen, sin limitarse a:  Gestión de tráfico  Autorización y control de acceso  Monitoreo  Gestión de versionamiento de API  Peticiones throttling para prevenir ataques Al igual que AWS Lambda, API Gateway es automáticamente escalado y se factura por llamada a la API. Se puede encontrar información más detallada sobre el pricing en la documentación oficial. 2.1. Términos API Gateway es un servicio AWS que soporta la creación, deploying, y gestión de una interfaz de programación de aplicación RESTful para exponer endpoints de backend HTTP, funciones Lambda AWS, y otros servicios AWS. Una API Gateway es una colección de recursos y métodos que pueden ser integrados con funciones Lambda, otros servicios AWS, o endpoints HTTP en el backend. La API consiste de recursos que forman la estructura de la API. Cada recurso de la API puede exponer uno o más métodos de API que deben tener verbos HTTP únicos. Para publicar una API, tenemos que crear un API deployment y asociarlo con una stage. Una stage es como una fotografía al momento de la API. Si redeployamos una API, podemos ya sea
  • 3. JavaDevelopersMexico @Copyright 2018 Abimael Desales López actualizar una stage existente o crear una nueva. Por ello, son posibles diferentes versiones de una API al mismo tiempo, por ejemplo una stage dev, una stage test/qa , y aún múltiples versiones de producción, como v1, v2, etc. Lambda Proxy integration es una configuración simplificada para la integración entre funciones Lambda y la API Gateway. La API Gateway envía la request completa como un input a una función Lambda de backend. En cuanto a la response, la API Gateway transforma la salida de la función Lambda atrás a una respuesta HTTP del frontend. 3. Generación del Proyecto e incluir dependencias Maven Generamos un nuevo proyecto Maven y lo nombramos de la siguiente forma: Necesitaremos agregar las siguientes dependencias al archivo pom.xml: <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.1.0</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>1.3.0</version> </dependency>
  • 4. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Además de eso, también necesitamos las siguientes librerías json y gson de google: <dependency> <groupId>com.googlecode.json-simple</groupId> <artifactId>json-simple</artifactId> <version>1.1.1</version> </dependency> <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> Se necesita agregar el plugin shade de Maven: <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>2.4.3</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 4. Desarrollando y Deployando las Funciones Lambda En esta sección, desarrollaremos y construriemos nuestras funciones Lambda en Java, las deployaremos usando la Consola AWS, y correremos una prueba rápida. Debido a que queremos demostrar las capacidades básicas de la integración de la API Gateway con Lambda, crearemos dos funciones:  Función 1: recibe un payload desde la API, usando un método PUT, para grabar en DB.  Función 2: demuestra cómo usar un parámetro HTTP de ruta o un parámetro de cadena de consulta HTTP que viene de la API En cuanto a la implementación, crearemos una clase que implemente RequestHandler, que tiene dos métodos — uno por cada función.
  • 5. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 4.1. Modelo Antes de implementar el request handler real, echemos una mirada rápida a nuestro modelo de datos: public class Prestamo { private int id; private String tipo; public Prestamo(String json) { Gson gson = new Gson(); Prestamo request = gson.fromJson(json, Prestamo.class); this.id = request.getId(); this.tipo = request.getTipo(); } public String toString() { Gson gson = new GsonBuilder().setPrettyPrinting().create(); return gson.toJson(this); } // getters y setters } Nuestro modelo consiste de una clase sencilla Prestamo, que tiene solo dos propiedades. La única parte notable es el constructor Prestamo(String), que acepta una String JSON.
  • 6. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 4.2. Implementación de la clase RequestHandler Crearemos una implementación de la interface RequestStreamHandler: public class APIGatewayHandler implements RequestStreamHandler { private static final String DYNAMODB_TABLE_NAME = System.getenv("TABLE_NAME"); private static final Regions REGION = Regions.US_WEST_2; @SuppressWarnings("unchecked") public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { // implementación } public void handleGetByParam(InputStream input, OutputStream output, Context context) throws IOException { // implementación } } La interface RequestStreamHander define solo un método, handleRequest(). De cualquier forma podemos definir algunas funciones en la misma clase, como lo hemos hecho aquí. Otra opción sería crear una implementación de RequestStreamHandler para cada función, pero no la abordaremos en este tutorial.
  • 7. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Por simplicidad, en nuestro caso específicamente hemos elegido el primero. Sin embargo, la elección se debe hacer considerando cada caso, tomamos en consideración factores como performance y mantenibilidad de código. Además leeremos el nombre de una tabla DynamoDB desde la variable de entorno TABLE_NAME. Definiremos esa variable más tarde durante el deployment. 4.3. Implementación de la Función 1 En nuestra primera función, queremos demostrar cómo obtener un payload (al igual que desde una request PUT o POST) desde la API Gateway: public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException { JSONParser parser = new JSONParser(); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); JSONObject responseJson = new JSONObject(); AmazonDynamoDBClient cliente = new AmazonDynamoDBClient(); cliente.setRegion(Region.getRegion(REGION)); DynamoDB dynamoDb = new DynamoDB(cliente); try { JSONObject event = (JSONObject) parser.parse(reader); if (event.get("body") != null) { Prestamo prestamo = new Prestamo((String) event.get("body")); dynamoDb.getTable(DYNAMODB_TABLE_NAME).putItem(new PutItemSpec() .withItem( new Item().withNumber("id", prestamo.getId()).withString("tipo", prestamo.getTipo()))); } JSONObject responseBody = new JSONObject(); responseBody.put("mensaje", "Nuevo item creado"); JSONObject headerJson = new JSONObject(); headerJson.put("x-custom-header", "mi valor de header personalizado"); responseJson.put("statusCode", 200); responseJson.put("headers", headerJson); responseJson.put("body", responseBody.toString()); } catch (ParseException pex) { responseJson.put("statusCode", 400); responseJson.put("exception", pex); } OutputStreamWriter writer = new OutputStreamWriter(output, "UTF-8"); writer.write(responseJson.toString()); writer.close(); } Como lo comentamos antes, más adelante configuraremos la API para que use la integración del proxy de Lambda. Esperamos que la API Gateway pase la request completa a la función Lambda en el parámetro InputStream. Todo lo que tenemos que hacer es elegir los atributos relevantes de la estructura JSON contenida.
  • 8. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Como podemos ver, el método básicamente consiste de tres pasos: 1. Ir a buscar el objeto body desde nuestro input stream y crear un objeto Prestamo de él. 2. Almacenar ese objeto Prestamo en una tabla DynamoDB. 3. Construir un objeto JSON, que pueda contener varios atributos, como un body para la response, headers personalizados, así como un código de estatus HTTP. Un punto que vale la pena mencionar aquí: la API Gateway espera que el body sea una String (tanto para la request como para la response). Ya que esperamos tener una String como body desde la API Gateway, casteamos el body a String e inicializamos nuestro objeto Prestamo: Prestamo prestamo = new Prestamo((String) event.get("body")); La API Gateway además espera que la respuesta de body sea una String: responseJson.put("body", responseBody.toString()); Este tema no se menciona explícitamente en la documentación oficial. Sin embargo, si observamos de cerca, podemos ver que el atributo es una String en ambos snippets, tanto para la request como para la response. La ventaja debe ser clara: aún si el formato es JSON entre la API Gateway y la función Lambda, el body real puede contener texto plano, JSON, XML, o cualquier otra cosa. Entonces es responsabilidad de la función Lambda administrar el formato correctamente. Posteriormente veremos cómo se ven el body de la request y response cuando probemos nuestras funciones en la Console AWS. Lo mismo también aplica a las siguientes dos funciones. 4.4. Implementación de la Función 2 En un segundo paso queremos demostrar cómo usar un parámetro path o un parámetro query string para retomar un item Prestamo desde la base de datos usando sus ID: public void handleGetByParam(InputStream input, OutputStream output, Context context) throws IOException { JSONParser parser = new JSONParser(); BufferedReader reader = new BufferedReader(new InputStreamReader(input)); JSONObject responseJson = new JSONObject(); AmazonDynamoDBClient client = new AmazonDynamoDBClient(); client.setRegion(Region.getRegion(REGION)); DynamoDB dynamoDb = new DynamoDB(client); Item result = null; try { JSONObject event = (JSONObject) parser.parse(reader); JSONObject responseBody = new JSONObject(); if (event.get("pathParameters") != null) { JSONObject pps = (JSONObject) event.get("pathParameters"); if (pps.get("id") != null) { int id = Integer.parseInt((String) pps.get("id")); result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id); } } else{
  • 9. JavaDevelopersMexico @Copyright 2018 Abimael Desales López if (event.get("queryStringParameters") != null) { JSONObject qsp = (JSONObject) event.get("queryStringParameters"); if (qsp.get("id") != null) { int id = Integer.parseInt((String) qsp.get("id")); result = dynamoDb.getTable(DYNAMODB_TABLE_NAME).getItem("id", id); } } } if (result != null) { Prestamo prestamo = new Prestamo(result.toJSON()); responseBody.put("Prestamo", prestamo); responseJson.put("statusCode", 200); } else { responseBody.put("mensaje", "Item no encontrado"); responseJson.put("statusCode", 404); } JSONObject headerJson = new JSONObject(); headerJson.put("x-custom-header", "mi valor de header personalizado"); responseJson.put("headers", headerJson); responseJson.put("body", responseBody.toString()); } catch (ParseException pex) { responseJson.put("statusCode", 400); responseJson.put("exception", pex); } OutputStreamWriter writer = new OutputStreamWriter(output, "UTF-8"); writer.write(responseJson.toString()); writer.close(); } Nuevamente, los tres pasos relevantes: 1. Checamos si están presentes un pathParameters o un array queryStringParameters con un atributo id. 2. Si es true, usamos el valor correspondiente para solicitar un item Prestamo con ese ID desde la base de datos. 3. Agregamos una representación JSON del item recibido a la response. La documentación oficial provee una explicación más detallada del formato de input y formato de output para Proxy Integration. 4.5. Construyendo el código Nuevamente, podemos simplemente construir nuestro código usando Maven: mvn clean package shade:shade El archivo JAR será creado bajo la carpeta target.
  • 10. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 4.6. Creando la tabla en DynamoDB Podemos crear la tabla como se explicó en AWS Lambda Usando DynamoDB con Java. Vamos a elegir Prestamo como nombre de la tabla, id como nombre de la llave primaria, y Number como el tipo para la llave primaria.
  • 11. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 4.7. Deployando el código vía la Consola AWS Después de construir nuestro código y crear la tabla, ahora podemos crear las funciones y cargar el código. Esto se puede hacer repitiendo los pasos 1-5 del artículo AWS Lambda con Java, una vez por cada uno de nuestros métodos. Vamos a usar los siguiente nombres de funciones:  StorePrestamosFunction para el método handleRequest (función 1)
  • 13. JavaDevelopersMexico @Copyright 2018 Abimael Desales López  GetPrestamoByHTTPParamFunction para el método handleGetByParam (función 2)
  • 14. JavaDevelopersMexico @Copyright 2018 Abimael Desales López También hemos definido una variable de entorno TABLE_NAME con el valor de “Prestamo”.
  • 15. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 4.8. Probando las Funciones Antes de continuar con la parte real de la API Gateway, podeos correr una prueba rápida en la Consola AWS, solo para checar que nuestras funciones Lambda estén corriendo de forma correcta y puedan manejar el formato de Proxy Integration. Probar una función Lambda desde la Consola AWS se hace como se describe en el artículo AWS Lambda con Java. Sin embarho, cuando creamos un evento de prueba, tenemos que considerar el formato especial de Proxy Integration, que están esperando nuestras funciones. Podemos ya sea usar la plantilla API Gateway AWS Proxy y personalizarla de acuerdo a nuestras necesidades, o podemos copiar y pegar los siguientes eventos: Para la función StorePrestamoFunction, debemos usar este: { "body": "{"id": 1, "tipo": "Fiduciario"}" } Como lo discutimos antes, el body debe tener el tipo String, aún si contiene una estructura JSON. La razón es que el API Gateway enviará sus requests en el mismo formato. Debería retornar la siguiente respuesta: { "isBase64Encoded": false, "headers": { "x-custom-header": "mi valor de header personalizado"
  • 16. JavaDevelopersMexico @Copyright 2018 Abimael Desales López }, "body": "{"mensaje":"Nuevo item creado"}", "statusCode": 200 } Aquí, podemos ver que el body de nuestra response es una String, aunque contiene una estructura JSON. Vamos a ver la input para la función GetPrestamoByHTTPParamFunction. Para probar la funcionalidad de parámetro path, el input se vería como esto: { "pathParameters": { "id": "1" } } Y el input para enviar un parámetro de query string sería: { "queryStringParameters": { "id": "1" } } Como una response, deberíamos tener lo siguiente para los métodos de ambos casos: { "headers": { "x-custom-header": "Mi valor de header personalizado" }, "body": "{"Prestamo":{n "id": 1,n "tipo": "Fiduciario"n}}", "statusCode": 200 } Nuevamente, el body es una String. Consultando la tabla de DynamoDB podemos darnos cuenta de que realmente el valor se encuentra persistido:
  • 17. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 5. Creando y Probando la API Después que hemos creado y desplegado las funciones Lambda en la sección anterior, ahora podemos crear la API real usando la Consola AWS. Vamos a ver el flujo básico a seguir: 1. Crear una API en nuestra cuenta AWS. 2. Agregar un recurso a la jerarquía de recursos de la API. 3. Crear uno o más métodos para el recurso. 4. Configurar la integración entre un método y la función Lambda perteneciente. Repetiremos los pasos 2-4 por cada una de nuestra fos funciones en las siguientes secciones. 5.1. Creando la API Para crear la API, tendremos que: 1. Firmarnos a la consola de la API Gateway en https://console.aws.amazon.com/apigateway 2. Hacer click en “Get Started” y seleccionar “New API” 3. Escribir el nombre de nuestra API (APIPrestamosLambdaDynamoDB) y confirmar haciendo click en “Create API”
  • 18. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Habiendo creado la API, ahora ya podemos crear la estructura de la API y ligarla a nuestra funciones Lambda. 5.2. Estructura de la API para la funcción 1 Se necesitan los siguientes pasos para nuestra función StorePrestamosFunction: 1. Elige el elemento recurso padre bajo el árbol de “Resources” y luego selecciona “Create Resource” del menú desplegable “Actions”. Luego, tenemos que hacer lo siguiente en el pánel “New Child Resource”:  Escribe “Prestamos” como el nombre en el campo de texto “Resource Name”  Deja el valor default en el campo de texto “Resource Path”  Selecciona “Create Resource” 2. Elige el recurso recién creado, selecciona “Create Method” del menú desplegable “Actions”, y lleva a cabo los siguientes pasos:
  • 19. JavaDevelopersMexico @Copyright 2018 Abimael Desales López  Elige PUT de la lista desplegable de métodos HTTP y luego chequea el ícono de marca para guardar la elección.  Deja “Lambda Function” como tipo de integración, y selecciona la opción “Use Lambda Proxy integration”  Selecciona la región de “Lambda Region”, donde deployamos nuestras funciones Lambda anteriormente  Escribe “StorePrestamosFunction” en “Lambda Function” 3. Elige “Save” y confirma con “OK” cuando te pregunte con “Add Permission to Lambda Function”
  • 20. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 5.3. Estructura de la API para la Función 2 – Path Parameters Los pasos para nuestros parámetros path de recuperación son similares: 1. Elige el item de recurso /prestamos bajo el árbol de “Resources” y luego selecciona “Create Resource” del menú desplegable Actions”. Luego, tenemos que hacer lo siguiente en el panel New Child Resource:  Escribe “Prestamo” como nombre en el campo de texto “Resource Name”  Cambia el campo de texto “Resource Path” a “{id}”  Elige “Create Resource” 2. Elige el recurso recién creado, selecciona “Create Method” del menú desplegable “Actions”, y lleva a cabo los siguientes pasos:
  • 21. JavaDevelopersMexico @Copyright 2018 Abimael Desales López  Elige GET de la lista desplegable de métodos HTTP y luego elige el ícono de marca (check) para guardar la elección  Deja “Lambda Function” como el tipo de integración, y selecciona la opción “Use Lambda Proxy integration”  Elige la región de “Lambda Region”, donde deployamos nuestras funciones Lambda anteriormente  Escribe “GetPrestamosByHTTPParamFunction” en “Lambda Function” 3. Elige “Save” y confirma con “OK” cuando se te solicite con “Add Permission to Lambda Function”
  • 22. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Nota: es importante aquí asignar el parámetro “Resource Path” a “{id}”, ya que nuestra función GetPrestamosByPathParamFunction espera que este parámetro sea nombrado de esta forma. 5.4. Estructura de la API para la función 2 – Query String Parameters Los pasos para recibir parámetros query string son un poco diferentes, ya que no tenemos que crear un recurso, en vez de eso tenemos que crear un parámetro query para el parámetro id: 1. Elige el recurso /prestamos bajo el árbol de “Resources”, selecciona “Create Method” del menú desplegable “Actions”, y lleva a cabo los siguientes pasos:  Elige GET desde la lista desplegable de métodos HTTP y luego selecciona el ícono de marca para guardar la elección.  Deja “Lambda Function” como tipo de integración, y selecciona la opción “Use Lambda Proxy integration”  Elige la región de “Lambda Region”, donde antes deployamos nuestras funciones Lambda  Escribe “GetPrestamosByHTTPParamFunction” en “Lambda Function”.
  • 23. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 2. Elige “Save” y confirma con “OK” cuando se te solicite con “Add Permission to Lambda Function” 3. Elige “Method Request” en la derecha y lleva a cabo los siguientes pasos:
  • 24. JavaDevelopersMexico @Copyright 2018 Abimael Desales López  Expande la lista de URL Query String Parameters.  Haz click en “Add Query String”.  Escribe “id” en el campo nombre, y elige el ícono de marca para guardar.  Selecciona la marca de “Required”  Haz click en el símbolo de lápiz a continuación de “Request validator” en lo alto del pánel, selecciona “Validate query string parameters and headers”, y selecciona el ícono de marca.
  • 25. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Nota: Es importante asignar el parámetro “Query String” a “id”, ya que nuestra función GetPrestamosByHTTPParamFunction espera este parámetro para que sea nombrado exactamente como este. 5.5. Probando la API Nuestra API ahora está lista, pero aún no es pública. Antes de publicarla, primero queremos correr una prueba rápida desde la Consola. Para eso, podemos seleccionar el método respectivo a probar en el árbol de “Resources” y hacer click en el botón “Test”. En la siguiente pantalla, podemos escribir nuestro input, como lo enviaríamos con un cliente vía HTTP. For StorePrestamosFunction, tenemos ue ingresar la siguiente estructura en el campo “Request Body”: { "id": 2, "tipo": "Nómina" }
  • 26. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Se obtiene como resultado lo siguiente: Para la GetPrestamosByHTTPParamFunction con parámetros de path, tenemos que ingresar 2 como un valor en el campo “{id}” bajo “Path”.
  • 27. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Se obtiene el siguiente resultado al pulsar el botón Test:
  • 28. JavaDevelopersMexico @Copyright 2018 Abimael Desales López Para la GetPrestamoByHTTPParamFunction con parámetros de query string, tenemos que ingresar a tipo id=2 como valor en el campo “{prestamos}” bajo “Query Strings”. Al hacer click sobre el botón Test nos da como resultado lo siguiente:
  • 29. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 5.6. Deployando la API Hasta ahora, nuestra API no era pública y por lo tanto solo estaba disponible desde la Consola AWS. Como lo discutimos antes, cuando deployamos una API, tenemos que asociarlo con una stage, que es como un snapshot de la API al momento. Si redeployamos una API, podemos ya sea actualizar una stage existente o crear una nueva. Vamos a ver cómo se verá el esquema URL para nuestra API: https://{restapi-id}.execute-api.{region}.amazonaws.com/{stageName} Se requieren los siguientes pasos para deployment: 1. Elige la API particular en el pánel de navegación “APIs” 2. Elige “Actions” en el pánel de navegación Resources y selecciona “Deploy API” desde el menú desplegable “Actions”
  • 30. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 3. Elige “[New Stage]” desde la stage desplegable “Deployment stage”, ingresa “QA” en “Stage name”, y opcionalmente proporciona una descripción de la stage y deployment. 4. Dispara el deployment eligiendo “Deploy” Después del último paso, la consola proveerá la URL raíz de la API, por ejemplo, https://0skaqfgdw4.execute-api.eu-central-1.amazonaws.com/test.
  • 31. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 5.7. Invocando el Endpoint Ya que la API es ahora pública, podemos llamarla usando cualquier cliente HTTP que queramos. Con cURL, las llamadas serían como sigue. StorePrestamosFunction: curl -X PUT 'https://0skaqfgdw4.execute-api.eu-central- 1.amazonaws.com/qa/prestamos' -H 'content-type: application/json' -d '{"id": 3, "tipo": "Personal"}' GetPrestamosByHTTPParamFunction para parámetros path: curl -X GET 'https://0skaqfgdw4.execute-api.eu-central- 1.amazonaws.com/qa/prestamos/3' -H 'content-type: application/json' GetPrestamosByHTTPParamFunction para parámetros query string: curl -X GET 'https://0skaqfgdw4.execute-api.eu-central- 1.amazonaws.com/QA/prestamos?id=3' -H 'content-type: application/json' Mismos casos de prueba pueden realizarse con un buen cliente REST como lo es la extensión RESTClient de Mozzila Firefox, de la cual por simplicidad no profundizo en ello. A continuación adjunto todos los screenshoots que espero puedas comprenderlos y seguirlos para replicar las pruebas de este modo:
  • 36. JavaDevelopersMexico @Copyright 2018 Abimael Desales López 6. Conclusión En este artículo, vimos cómo hacer funciones AWS Lambda disponibles como endpoints REST, usando la API Gateway de AWS. Exploramos los conceptos básicos y terminología de la API Gateway, y aprendimos cómo integrar funciones Lambda usando Lambda Proxy Integration. Finalmente, vimos cómo crear, deployar, y probar una API. Como de costumbre. todo el código para este artículo está disponible en GitHub. Este documento está basado en la documentación oficial de AWS y en consulta de algunos otros sitios de internet: https://docs.aws.amazon.com/index.html#lang/es_es https://aws.amazon.com/es/serverless/developer-tools/ https://www.baeldung.com/aws-lambda-api-gateway https://www.paradigmadigital.com/dev/distintas-maneras-trabajar-aws-lambda/ https://www.paradigmadigital.com/dev/creando-api-rest-aws-lambda-api-gateway/