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();