[Cloud DA] Serverless Framework with AWS - Part 1: DynamoDB & ApiGateway
Part 1 Of Serverless Framework with AWS
DynamoDB & ApiGateway
Build a Lambda function get data from DynamoDB:
src/lambda/http/getGroups.ts
import * as AWS from "aws-sdk"; import { APIGatewayProxyEvent, APIGatewayProxyHandler, APIGatewayProxyResult, } from "aws-lambda"; const docClient = new AWS.DynamoDB.DocumentClient(); const groupTables = process.env.GROUPS_TABLE; export const handler: APIGatewayProxyHandler = async ( event: APIGatewayProxyEvent ): Promise<APIGatewayProxyResult> => { const result = await docClient .scan({ TableName: groupTables, }) .promise(); const items = result.Items; return { statusCode: 200, headers: { "Access-Control-Allow-Origin": "*", }, body: JSON.stringify({ items, }), }; };
serverless.yml:
service: name: serverless-udagram-app plugins: - serverless-webpack provider: name: aws runtime: nodejs14.x stage: ${opt:stage, 'dev'} region: ${opt:region, 'us-east-1'} environment: GROUPS_TABLE: Groups-${self:provider.stage} iamRoleStatements: - Effect: Allow Action: - dynamodb:Scan Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.GROUPS_TABLE} functions: GetGroups: handler: src/lambda/http/getGroups.handler events: - http: method: get path: groups cors: true resources: Resources: GroupsDynamoDBTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: id AttributeType: S KeySchema: - AttributeName: id KeyType: HASH BillingMode: PAY_PER_REQUEST TableName: ${self:provider.environment.GROUPS_TABLE}
Validate request in ApiGateway
Refer to: https://www.cnblogs.com/Answer1215/p/14774552.html
Query in Node.js
const docClient = new AWS.DynamoDB.DocumentClient() const result = await docClient.query({ TableName: 'GameScore', KeyConditionExpression: 'GameId = :gameId', ExpressionAttributeValues: { ':gameId': '10' } }).promise() const items = result.Items
Path parameter
functions: GetOrders: handler: src/images.handler events: - http: method: get path: /groups/{groupId}/images
export.handler = async (event) => { const grouId = event.pathParameters.groupId; ... }
Add indexes
serverless.yml
service: name: serverless-udagram-app plugins: - serverless-webpack provider: name: aws runtime: nodejs14.x stage: ${opt:stage, 'dev'} region: ${opt:region, 'us-east-1'} environment: GROUPS_TABLE: Groups-${self:provider.stage} IMAGES_TABLE: Images-${self:provider.stage} IMAGE_ID_INDEX: ImageIdIndex iamRoleStatements: - Effect: Allow Action: - dynamodb:Query Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.IMAGES_TABLE}/index/${self:provider.environment.IMAGE_ID_INDEX} - Effect: Allow Action: - dynamodb:Query - dynamodb:PutItem Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.IMAGES_TABLE} - Effect: Allow Action: - dynamodb:Scan - dynamodb:PutItem - dynamodb:GetItem Resource: arn:aws:dynamodb:${self:provider.region}:*:table/${self:provider.environment.GROUPS_TABLE} functions: CreateImage: handler: src/lambda/http/createImage.handler events: - http: method: post path: groups/{groupId}/images cors: true reqValidatorName: RequestBodyValidator request: schema: application/json: ${file(models/create-image-request.json)} GetImage: handler: src/lambda/http/getImage.handler events: - http: method: get path: images/{imageId} cors: true GetImages: handler: src/lambda/http/getImages.handler events: - http: method: get path: group/{groupId}/images cors: true GetGroups: handler: src/lambda/http/getGroups.handler events: - http: method: get path: groups cors: true CreateGroup: handler: src/lambda/http/createGroup.handler events: - http: method: post path: groups cors: true ## do the validation in api gateway reqValidatorName: RequestBodyValidator request: schema: application/json: ${file(models/create-group-request.json)} resources: Resources: ImagesDynamoDBTable: Type: AWS::DynamoDB::Table Properties: TableName: ${self:provider.environment.IMAGES_TABLE} BillingMode: PAY_PER_REQUEST KeySchema: - AttributeName: groupId KeyType: HASH - AttributeName: timestamp KeyType: RANGE AttributeDefinitions: - AttributeName: groupId AttributeType: S - AttributeName: timestamp AttributeType: S - AttributeName: imageId AttributeType: S GlobalSecondaryIndexes: - IndexName: ${self:provider.environment.IMAGE_ID_INDEX} KeySchema: - AttributeName: imageId KeyType: HASH ## Copy all the attrs to the new GSI table Projection: ProjectionType: ALL GroupsDynamoDBTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: id AttributeType: S KeySchema: - AttributeName: id KeyType: HASH BillingMode: PAY_PER_REQUEST TableName: ${self:provider.environment.GROUPS_TABLE}
const docClient = new AWS.DynamoDB.DocumentClient(); const imagesTable = process.env.IMAGES_TABLE; const imageIdIndex = process.env.IMAGE_ID_INDEX; export const handler: APIGatewayProxyHandler = async ( event: APIGatewayProxyEvent ): Promise<APIGatewayProxyResult> => { const imageId = event.pathParameters.imageId; const result = await docClient .query({ TableName: imagesTable, IndexName: imageIdIndex, KeyConditionExpression: "imageId= :imageId", ExpressionAttributeValues: { ":imageId": imageId, }, }) .promise();