Tutorial: crear una API CRUD con Lambda y DynamoDB - Amazon API Gateway

Tutorial: crear una API CRUD con Lambda y DynamoDB

En este tutorial, creará una API sin servidor para crear, leer, actualizar y eliminar elementos de una tabla de DynamoDB. DynamoDB es un servicio de bases de datos NoSQL totalmente administrado que proporciona un rendimiento rápido y predecible, así como una perfecta escalabilidad. Completar este tutorial lleva aproximadamente 30 minutos, y puede hacerse dentro del nivel gratuito de AWS.

En primer lugar, se crea una tabla DynamoDB utilizando la consola de DynamoDB. Luego, se crea una función de Lambda con la consola de AWS Lambda. A continuación, crea una API HTTP mediante la consola de API Gateway. Por último, se prueba la API.

Cuando invoca su API HTTP, API Gateway enruta la solicitud a su función de Lambda. La función Lambda interactúa con DynamoDB y devuelve una respuesta a API Gateway. API Gateway, a continuación, le devuelve una respuesta.

Información general de la API HTTP creada en este tutorial.

Para completar este ejercicio, necesita una cuenta de AWS y un usuario de AWS Identity and Access Management con acceso a la consola. Para obtener más información, consulte Requisitos previos para comenzar con API Gateway.

En este tutorial, se utiliza la AWS Management Console. Para obtener una plantilla de AWS SAM que cree esta API y todos los recursos relacionados, consulte template.yaml.

Paso 1: crear una tabla de DynamoDB

Se utiliza una tabla DynamoDB para almacenar datos para la API.

Cada elemento tiene un ID único, que usamos como clave de partición para la tabla.

Cree una tabla de DynamoDB
  1. Abra la consola de DynamoDB en https://console.aws.amazon.com/dynamodb/.

  2. Seleccione Create table.

  3. En Nombre de la tabla, introduzca http-crud-tutorial-items.

  4. En Partition key (Clave de partición), ingrese id.

  5. Elija Crear tabla.

Paso 2: crear una función Lambda

Se crea una función Lambda para el backend de la API. Esta función Lambda crea, lee, actualiza y elimina elementos de DynamoDB. La función utiliza eventos de API Gateway para determinar cómo interactuar con DynamoDB. Para simplificar el proceso, este tutorial utiliza una sola función Lambda. Como práctica recomendada, se deben crear funciones separadas para cada ruta.

Para crear una función Lambda, realice el siguiente procedimiento:
  1. Inicie sesión en la consola de Lambda en https://console.aws.amazon.com/lambda/.

  2. Elija Create function (Crear función).

  3. En Function name (Nombre de función), introduzca http-crud-tutorial-function.

  4. En Tiempo de ejecución, elija el último tiempo de ejecución de Node.js o Python compatible.

  5. En Permisos, seleccione Cambiar el rol de ejecución predeterminado.

  6. Seleccione Create a new role from AWS policy templates (Crear un nuevo rol en plantillas de políticas de AWS).

  7. En Nombre del rol, introduzca http-crud-tutorial-role.

  8. En Plantillas de políticas, seleccione Simple microservice permissions. Esta política concede a la función Lambda permiso para interactuar con DynamoDB.

    nota

    Para simplificar el proceso, este tutorial utiliza una política administrada. Como práctica recomendada, se deben crear políticas de IAM propias para otorgar los permisos mínimos requeridos.

  9. Elija Create function (Crear función).

  10. Abra la función de Lambda en el editor de código de la consola y sustituya su contenido con el siguiente código. Seleccione Implementar para actualizar la función.

Node.js
import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; import { DynamoDBDocumentClient, ScanCommand, PutCommand, GetCommand, DeleteCommand, } from "@aws-sdk/lib-dynamodb"; const client = new DynamoDBClient({}); const dynamo = DynamoDBDocumentClient.from(client); const tableName = "http-crud-tutorial-items"; export const handler = async (event, context) => { let body; let statusCode = 200; const headers = { "Content-Type": "application/json", }; try { switch (event.routeKey) { case "DELETE /items/{id}": await dynamo.send( new DeleteCommand({ TableName: tableName, Key: { id: event.pathParameters.id, }, }) ); body = `Deleted item ${event.pathParameters.id}`; break; case "GET /items/{id}": body = await dynamo.send( new GetCommand({ TableName: tableName, Key: { id: event.pathParameters.id, }, }) ); body = body.Item; break; case "GET /items": body = await dynamo.send( new ScanCommand({ TableName: tableName }) ); body = body.Items; break; case "PUT /items": let requestJSON = JSON.parse(event.body); await dynamo.send( new PutCommand({ TableName: tableName, Item: { id: requestJSON.id, price: requestJSON.price, name: requestJSON.name, }, }) ); body = `Put item ${requestJSON.id}`; break; default: throw new Error(`Unsupported route: "${event.routeKey}"`); } } catch (err) { statusCode = 400; body = err.message; } finally { body = JSON.stringify(body); } return { statusCode, body, headers, }; };
Python
import json import boto3 from decimal import Decimal client = boto3.client('dynamodb') dynamodb = boto3.resource("dynamodb") table = dynamodb.Table('http-crud-tutorial-items') tableName = 'http-crud-tutorial-items' def lambda_handler(event, context): print(event) body = {} statusCode = 200 headers = { "Content-Type": "application/json" } try: if event['routeKey'] == "DELETE /items/{id}": table.delete_item( Key={'id': event['pathParameters']['id']}) body = 'Deleted item ' + event['pathParameters']['id'] elif event['routeKey'] == "GET /items/{id}": body = table.get_item( Key={'id': event['pathParameters']['id']}) body = body["Item"] responseBody = [ {'price': float(body['price']), 'id': body['id'], 'name': body['name']}] body = responseBody elif event['routeKey'] == "GET /items": body = table.scan() body = body["Items"] print("ITEMS----") print(body) responseBody = [] for items in body: responseItems = [ {'price': float(items['price']), 'id': items['id'], 'name': items['name']}] responseBody.append(responseItems) body = responseBody elif event['routeKey'] == "PUT /items": requestJSON = json.loads(event['body']) table.put_item( Item={ 'id': requestJSON['id'], 'price': Decimal(str(requestJSON['price'])), 'name': requestJSON['name'] }) body = 'Put item ' + requestJSON['id'] except KeyError: statusCode = 400 body = 'Unsupported route: ' + event['routeKey'] body = json.dumps(body) res = { "statusCode": statusCode, "headers": { "Content-Type": "application/json" }, "body": body } return res

Paso 3: crear una API HTTP

La API HTTP proporciona un punto de enlace HTTP para su función de Lambda. En este paso, se crea una API vacía. En los siguientes pasos, se configuran rutas e integraciones para conectar la API y la función Lambda.

Para crear una API HTTP
  1. Inicie sesión en la consola de API Gateway en https://console.aws.amazon.com/apigateway.

  2. Seleccione Crear APIy, a continuación, para API HTTP, seleccione Crear.

  3. En API name (Nombre de la API), escribahttp-crud-tutorial-api.

  4. Elija Next (Siguiente).

  5. En Configurar rutas, seleccione Siguiente para omitir la creación de rutas. Se crearán rutas más adelante.

  6. Revise la etapa que API Gateway crea y, a continuación, seleccione Siguiente.

  7. Seleccione Create (Crear).

Paso 4: crear rutas

Las rutas son una manera de enviar solicitudes entrantes de API a los recursos de backend. Las rutas constan de dos partes: un método HTTP y una ruta de recurso, por ejempl, GET /items. Para este ejemplo de API, creamos cuatro rutas:

  • GET /items/{id}

  • GET /items

  • PUT /items

  • DELETE /items/{id}

Para crear rutas
  1. Inicie sesión en la consola de API Gateway en https://console.aws.amazon.com/apigateway.

  2. Elija la API.

  3. Elija Routes (Rutas).

  4. Seleccione Create (Crear).

  5. En Method (Método), seleccione GET.

  6. En la ruta de acceso, introduzca /items/{id}. El {id} al final de la ruta es un parámetro de ruta que API Gateway recupera de la ruta de solicitud cuando un cliente realiza una solicitud.

  7. Seleccione Create (Crear).

  8. Repita los pasos 4 a 7 para GET /items, DELETE /items/{id}, y PUT /items.

La API tiene rutas para GET /items, GET /items/{id}, DELETE /items/{id} y PUT /items.

Paso 5: crear una integración

Se crea una integración para conectar una ruta a los recursos de backend. Para este ejemplo de API, se crea una integración Lambda que se utiliza para todas las rutas.

Para crear una integración
  1. Inicie sesión en la consola de API Gateway en https://console.aws.amazon.com/apigateway.

  2. Elija la API.

  3. Seleccione Integraciones.

  4. Seleccione Administrar integraciones y, a continuación, seleccione Crear.

  5. Omitir Conectar esta integración a una ruta. Esta etapa se completará más adelante.

  6. En Tipo de integración, seleccione Función Lambda.

  7. En Función Lambda, introduzca http-crud-tutorial-function.

  8. Seleccione Create (Crear).

Paso 6: conectar la integración a las rutas

Para este ejemplo de API, se utiliza la misma integración Lambda para todas las rutas. Después de conectar la integración a todas las rutas de la API, la función Lambda se invoca cuando un cliente llama a cualquiera de sus rutas.

Para conectar integraciones a rutas
  1. Inicie sesión en la consola de API Gateway en https://console.aws.amazon.com/apigateway.

  2. Elija la API.

  3. Seleccione Integraciones.

  4. Seleccione una ruta.

  5. En Elegir una integración existente, seleccione http-crud-tutorial-function.

  6. Seleccione Conectar integración.

  7. Repita los pasos 4 a 6 para todas las rutas.

Todas las rutas muestran que se adjuntó una integración de AWS Lambda.

La consola muestra a AWS Lambda en todas las rutas para indicar que la integración se adjuntó.

Ahora que se tiene una API HTTP con rutas e integraciones, se puede probar la API.

Paso 7: probar la API

Para asegurarse de que la API está funcionando, se utiliza curl.

Para obtener la URL para invocar la API
  1. Inicie sesión en la consola de API Gateway en https://console.aws.amazon.com/apigateway.

  2. Elija la API.

  3. Tenga en cuenta la URL de invocación de la API. Aparece en Invocar URL en la página Detalles.

    Después de crear la API, la consola muestra la URL de invocación de la API.
  4. Copie la URL de invocación de la API.

    La totalidad de la URL se parece a https://abcdef123.execute-api.us-west-2.amazonaws.com.

Para crear o actualizar un elemento
  • Utilice el siguiente comando para crear o actualizar un artículo. El comando incluye un cuerpo de solicitud con el ID, el precio y el nombre del artículo.

    curl -X "PUT" -H "Content-Type: application/json" -d "{\"id\": \"123\", \"price\": 12345, \"name\": \"myitem\"}" https://abcdef123.execute-api.us-west-2.amazonaws.com/items
Para ver todos los artículos
  • Utilice el siguiente comando para enumerar todos los artículos.

    curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items
Para ver un artículo
  • Utilice el siguiente comando para ver un artículo por su ID.

    curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items/123
Para eliminar un elemento
  1. Utilice el siguiente comando para eliminar un artículo.

    curl -X "DELETE" https://abcdef123.execute-api.us-west-2.amazonaws.com/items/123
  2. Ver todos los artículos para verificar que el artículo se eliminó.

    curl https://abcdef123.execute-api.us-west-2.amazonaws.com/items

Paso 8: Eliminar

Para evitar costos innecesarios, elimine los recursos creados como parte de este ejercicio introductorio. Los siguientes pasos eliminan la API HTTP, la función de Lambda y los recursos asociados.

Para eliminar una tabla de DynamoDB
  1. Abra la consola de DynamoDB en https://console.aws.amazon.com/dynamodb/.

  2. Seleccionar la tabla.

  3. Elija Delete table (Eliminar tabla).

  4. Confirme la elección y seleccione Eliminar.

Para eliminar una API HTTP
  1. Inicie sesión en la consola de API Gateway en https://console.aws.amazon.com/apigateway.

  2. En la página API, seleccione una API. Seleccione Actions y, luego, Delete.

  3. Elija Eliminar.

Para eliminar una función de Lambda
  1. Inicie sesión en la consola de Lambda en https://console.aws.amazon.com/lambda/.

  2. En la página Functions (Funciones), seleccione una función. Seleccione Actions y, luego, Delete.

  3. Elija Eliminar.

Para eliminar el grupo de registro de una función de Lambda
  1. En la consola de Amazon CloudWatch, abra la página de grupos de registro.

  2. En la página Grupos de registro, seleccione el grupo de registro de la función (/aws/lambda/http-crud-tutorial-function). Elija Actions (Acciones) y, a continuación, elija Delete log group (Eliminar grupo de registro).

  3. Elija Eliminar.

Para eliminar el rol de ejecución de una función de Lambda
  1. En la consola de AWS Identity and Access Management, abra la página Roles (Roles).

  2. Seleccione el rol de la función, por ejempl, http-crud-tutorial-role.

  3. Elija Delete role (Eliminar rol).

  4. Elija Sí, eliminar.

Pasos siguientes: automatización con AWS SAM o AWS CloudFormation

Puede automatizar la creación y la limpieza de los recursos de AWS mediante el uso de AWS CloudFormation o AWS SAM. Para obtener un ejemplo de plantilla de AWS SAM para este tutorial, consulte template.yaml.

Para obtener plantillas de AWS CloudFormation de ejemplo, consulte las plantillas de AWS CloudFormation de ejemplo.