ããã«ã¡ã¯ãåºéã§ãã 以äžã®èšäºãšåãçç±ã§ãAWS Summit Japan 2024 ã®ã»ãã·ã§ã³ãèããŠã€ã³ã¹ããŒã¬ãŒã·ã§ã³ãåããŸããŠãAmazon API Gateway ãš Amazon DynamoDB ã AWS Lambda 颿°æãã§çŽæ¥é£æºããŸããã䌌ããããªèšäºã¯äžã®äžã«å€ãã®ã§ãããæ¬èšäºã§ã¯ AWS CloudFormation ã§ãããã€ããŠããŸãã Amazon API Gateway ãã Amazon SES API ãçŽæ¥å©ããŠã¡ãŒã«éä¿¡ãã (AWS Lambda äžäœ¿çš) AWS Summit Japan 2024 ã§ãšããã»ãã·ã§ã³ãèããŠã€ã³ã¹ãã¬ãŒã·ã§ã³ãåããŸããŠãAmazon API Gateway ãš Amazon SES ãçŽæ¥é£æºãããŠã¿ãŸããã blog.usize-tech.com 2024.07.04 ããããã㚠以äžã® Amazon DynamoDB ããŒãã«ãããGetItem API ã䜿çšããŠæå®ã®ããŒã¿ã 1ä»¶ååŸããŸããããŒãã£ã·ã§ã³ããŒã¯ pkeyããœãŒãããŒã¯ skey ã§ãã屿§ãšã㊠attr ããããŸãã Amazon API Gateway REST API ã䜿çšããŸããAWS Lambda 颿°ã¯äœ¿çšããŸããã AWS Lambda 颿°ã§è¡ã£ãŠãã Amazon DynamoDB API ã®åŒã³åºãã¯ãAmazon API Gateway ã®çµ±åãªã¯ãšã¹ããããã³ã°ãã³ãã¬ãŒãã§ä»£çšããŸããAmazon API Gateway ã®çµ±åã¿ã€ãã¯ãAWS ã«ãªããŸãã Amazon API Gateway ã®èªèšŒã¯ãããŸãããCORS èšå®ã¯ãããŸããæ¬èšäºã§ã¯ç°¡ç¥åã®ãã “*” ã䜿çšããŠèšå®ããŸãã ãã¹ãã§ã¯ã”pkey”: “test1”, “skey”: 1 ã®ãã©ã¡ãŒã¿ãæå®ããŠããŒã¿ååŸããŠã¿ãŸãã ãããã³ã°ãã³ãã¬ãŒããã©ãæžãã AWS Lambda 颿°ã§ãã£ãŠããããšã Amazon API Gateway ã®ãããã³ã°ãã³ãã¬ãŒãã«è©ä»£ãããããã®ã§ããããèã«ãªããŸããã€ã¡ãŒãžããŠãããããããããããAWS Lambda 颿°ãšå¯Ÿæ¯ããŠç޹ä»ããŸãã AWS Lambda 颿° æžãæ¹ã¯ããã€ããããŸããã以äžã®ãã㪠AWS Lambda 颿° (Python) ã§ Amazon DynamoDB GetItem API ãåŒã³åºããšæããŸãã import json import boto3 dynamodb = boto3.resource('dynamodb') table = dynamodb.Table('extable-xxxxxxxxxx-hirono') def lambda_handler(event, context): input = json.loads(event['body']) res = table.get_item( Key={ 'pkey': input['pkey'], 'skey': input['skey'] } ) return { "isBase64Encoded": False, "statusCode": 200, "body": json.dumps(res) } ãããã³ã°ãã³ãã¬ãŒã ãããã³ã°ãã³ãã¬ãŒãã ãšã以äžã®ããã« VTL ã䜿çšããŠæžããŸããçµ±åãªã¯ãšã¹ããããã³ã°ãã³ãã¬ãŒãã«å®çŸ©ããŸãã ## API Gateway ãåãåã£ãåŒæ°ã $inputRoot ã«æ ŒçŽãã #set($inputRoot = $input.path('$')) { "TableName": "extable-xxxxxxxxxx-hirono", "Key": { "pkey":{ "S": "$inputRoot.pkey" }, "skey":{ "N": "$inputRoot.skey" } }, "ConsistentRead" : false } Amazon DynamoDB GetItem API ã«æž¡ããã©ãŒãããã¯åãã ãšæããŸããã åé ã§ãAmazon API Gateway ãåãåã£ããã©ã¡ãŒã¿ã $inputRoot ãšãã倿°ã«æ ŒçŽããŠããŸããé¢åãªã®ã¯é
ç®ããšã« “N” ã “S” ãªã©ããŒã¿åãæç€ºçã«æžããªããšãããªãããšã§ãã Amazon DynamoDB ããŒãã«ã«æž¡ããã©ã¡ãŒã¿ã®ä»æ§ã¯ä»¥äžã®å
¬åŒãªãã¡ã¬ã³ã¹éãã ã£ãã®ã§ãAmazon DynamoDB ã®ä»ã® API ã§ãåæ§ã«å¿çšã§ãããã®ãšæ³åããŸãã GetItem - Amazon DynamoDB The GetItem operation returns a set of attributes for the item with the given primary key. If there is no matching item,... docs.aws.amazon.com å®éã®åäœ å®éã« API ãžã®ãªã¯ãšã¹ãã AWS CloudShell ããã³ãã³ããæã£ãŠè©ŠããŠã¿ãŸãã以äžã®ã³ãã³ããæã¡ãŸãã curl -X POST 'https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod/Dynamodb' -H 'Content-Type: application/json' -d '{"pkey": "test1", "skey": "1"}' 以äžã®çµæãè¿ã£ãŠããŸãã {"Item":{"attr":{"S":"attr1"},"pkey":{"S":"test1"},"skey":{"N":"1"}}} âæŽåœ¢ãããš { "Item": { "attr": { "S":"attr1" }, "pkey": { "S":"test1" }, "skey": { "N":"1" } } } ä»åãAmazon API Gateway REST API ã®çµ±åã¬ã¹ãã³ã¹ãããã³ã°ãã³ãã¬ãŒãããã¹ã¹ã«ãŒã«ããã®ã§ãAmazon DynamoDB ããè¿ã£ãŠããããŒã¿ããã®ãŸãŸè¡šç€ºãããŸããã ã¬ã¹ãã³ã¹ããäœèšãª “N” ã “S” ãæ¶ãããšæã£ãããçµ±åã¬ã¹ãã³ã¹ãããã³ã°ãã³ãã¬ãŒãã§æ»ããå å·¥ããå¿
èŠããããŸããã屿§ãåºå®ã§ã¯ãªãå Žåã¯é£ãããããããŸããã æ¬èšäºã®äŸã§ã¯ãœãŒãããŒã®ããŒã¿åã Number ã«ãªã£ãŠããŸãããã®ã±ãŒã¹ã§ã¯ãAPI ã«æ°å€ãæååãšããŠæž¡ããªããšãšã©ãŒã«ãªããŸããAmazon DynamoDB API ã®ä»æ§ã§ãã”skey”:{“N”:”1″} ãšãªã£ãŠããéšåã®ããšã§ãããŸããæ»ã£ãŠããå€ãæ°å€ã¯æååãšããŠè¿ãããŸãã ä»ã«ã Amazon API Gateway ã®èšå®ã¯ããã®ã§ãããã¡ã€ã³ã¯ãããã³ã°ãã³ãã¬ãŒãã§ããã®ã§ãAWS CloudFormation ãã³ãã¬ãŒãããèªã¿åããããããå®è¡ããŠãããã€ãããçŸç©ãã確èªé ããããšæããŸãã AWS CloudFormation ãã³ãã¬ãŒã æ¬èšäºã§ç޹ä»ãã Amazon DynamoDB ããŒãã«ãš Amazon API Gateway REST API ãäžåŒãããã€ãã AWS CloudFormation ã貌ãä»ããŸããå·çæç¹ã§åããããšã¯ç¢ºèªæžã¿ã§ãã AWSTemplateFormatVersion: 2010-09-09 Description: The CloudFormation template that creates a DynamoDB table and an API Gateway. # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: SubName: Type: String Description: System sub name. (e.g. example) Default: example MaxLength: 10 MinLength: 1 Resources: # ------------------------------------------------------------# # DynamoDB # ------------------------------------------------------------# DynamodbExample: Type: AWS::DynamoDB::Table Properties: TableName: !Sub extable-${AWS::AccountId}-${SubName} AttributeDefinitions: - AttributeName: pkey AttributeType: S - AttributeName: skey AttributeType: N BillingMode: PAY_PER_REQUEST KeySchema: - AttributeName: pkey KeyType: HASH - AttributeName: skey KeyType: RANGE PointInTimeRecoverySpecification: PointInTimeRecoveryEnabled: false Tags: - Key: Cost Value: !Ref SubName # ------------------------------------------------------------# # API Gateway # ------------------------------------------------------------# RestApiDynamodb: Type: AWS::ApiGateway::RestApi Properties: Name: !Sub dynamodb-${SubName} Description: !Sub REST API to call DynamoDB GetItem API for ${SubName} EndpointConfiguration: Types: - REGIONAL Tags: - Key: Cost Value: !Ref SubName RestApiDeploymentDynamodb: Type: AWS::ApiGateway::Deployment Properties: RestApiId: !Ref RestApiDynamodb DependsOn: - RestApiMethodDynamodbPost - RestApiMethodDynamodbOptions RestApiStageDynamodb: Type: AWS::ApiGateway::Stage Properties: StageName: prod Description: production stage RestApiId: !Ref RestApiDynamodb DeploymentId: !Ref RestApiDeploymentDynamodb MethodSettings: - ResourcePath: "/*" HttpMethod: "*" LoggingLevel: INFO DataTraceEnabled : true TracingEnabled: false Tags: - Key: Cost Value: !Ref SubName RestApiResourceDynamodb: Type: AWS::ApiGateway::Resource Properties: RestApiId: !Ref RestApiDynamodb ParentId: !GetAtt RestApiDynamodb.RootResourceId PathPart: Dynamodb RestApiMethodDynamodbPost: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref RestApiDynamodb ResourceId: !Ref RestApiResourceDynamodb HttpMethod: POST AuthorizationType: NONE Integration: Type: AWS IntegrationHttpMethod: POST Credentials: !GetAtt ApigDynamodbInvocationRole.Arn Uri: !Sub "arn:aws:apigateway:${AWS::Region}:dynamodb:action/GetItem" PassthroughBehavior: WHEN_NO_TEMPLATES RequestTemplates: application/json: !Sub | #set($inputRoot = $input.path('$')) { "TableName": "${DynamodbExample}", "Key": { "pkey":{ "S": "$inputRoot.pkey" }, "skey":{ "N": "$inputRoot.skey" } }, "ConsistentRead" : false } IntegrationResponses: - StatusCode: 200 ResponseParameters: method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'" method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'" - StatusCode: 400 ResponseParameters: method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'" method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'" - StatusCode: 403 ResponseParameters: method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'" method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'" - StatusCode: 404 ResponseParameters: method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'" method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'" - StatusCode: 500 ResponseParameters: method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'" method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'" - StatusCode: 503 ResponseParameters: method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'" method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'" MethodResponses: - StatusCode: 200 ResponseModels: application/json: Empty ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Headers: true method.response.header.Access-Control-Allow-Methods: true - StatusCode: 400 ResponseModels: application/json: Empty ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Headers: true method.response.header.Access-Control-Allow-Methods: true - StatusCode: 403 ResponseModels: application/json: Empty ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Headers: true method.response.header.Access-Control-Allow-Methods: true - StatusCode: 404 ResponseModels: application/json: Empty ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Headers: true method.response.header.Access-Control-Allow-Methods: true - StatusCode: 500 ResponseModels: application/json: Empty ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Headers: true method.response.header.Access-Control-Allow-Methods: true - StatusCode: 503 ResponseModels: application/json: Empty ResponseParameters: method.response.header.Access-Control-Allow-Origin: true method.response.header.Access-Control-Allow-Headers: true method.response.header.Access-Control-Allow-Methods: true DependsOn: - ApigDynamodbInvocationRole RestApiRequestModelDynamodb: Type: AWS::ApiGateway::Model Properties: ContentType: application/json RestApiId: !Ref RestApiDynamodb Schema: |- { "$schema": "http://json-schema.org/draft-04/schema#", "title": "Dynamodb", "type": "object", "properties": { "pkey": { "type": "string" }, "skey": { "type": "integer" } }, "required": ["pkey", "skey"] } RestApiMethodDynamodbOptions: Type: AWS::ApiGateway::Method Properties: RestApiId: !Ref RestApiDynamodb ResourceId: !Ref RestApiResourceDynamodb HttpMethod: OPTIONS AuthorizationType: NONE Integration: Type: MOCK Credentials: !GetAtt ApigDynamodbInvocationRole.Arn IntegrationResponses: - ResponseParameters: method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,Cache-Control'" method.response.header.Access-Control-Allow-Methods: "'POST,OPTIONS'" method.response.header.Access-Control-Allow-Origin: "'*'" ResponseTemplates: application/json: '' StatusCode: 200 PassthroughBehavior: WHEN_NO_MATCH RequestTemplates: application/json: '{"statusCode": 200}' MethodResponses: - ResponseModels: application/json: Empty ResponseParameters: method.response.header.Access-Control-Allow-Headers: true method.response.header.Access-Control-Allow-Methods: true method.response.header.Access-Control-Allow-Origin: true StatusCode: 200 # ------------------------------------------------------------# # API Gateway DynamoDB Invocation Role (IAM) # ------------------------------------------------------------# ApigDynamodbInvocationRole: Type: AWS::IAM::Role Properties: RoleName: !Sub ApigDynamodbInvocationRole-${SubName} Description: This role allows API Gateways to invoke DynamoDB GetItem API. AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: - apigateway.amazonaws.com Action: - sts:AssumeRole Path: / ManagedPolicyArns: - arn:aws:iam::aws:policy/AWSXRayDaemonWriteAccess Policies: - PolicyName: !Sub ApigDynamodbInvocationPolicy-${SubName} PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - "dynamodb:GetItem" Resource: - !GetAtt DynamodbExample.Arn DependsOn: - DynamodbExample # ------------------------------------------------------------# # Output Parameters # ------------------------------------------------------------# Outputs: APIGatewayEndpointDynamodb: Value: !Sub https://${RestApiDynamodb}.execute-api.${AWS::Region}.${AWS::URLSuffix}/${RestApiStageDynamodb}/Dynamodb æ¬ãã³ãã¬ãŒãã¯ãAmazon API Gateway ã®ãã°ã Amazon CloudWatch Logs ã« push ããããã«å¿
èŠãª IAM ããŒã«ãã¢ã«ãŠã³ãã«ç»é²æžã¿ã§ãªããšãšã©ãŒã«ãªããŸããããã«ã€ããŠã¯ä»¥äžã®èšäºãã確èªãã ããã Amazon API Gateway ã®ãã°ã Amazon CloudWatch Logs ã«æžã蟌ãããã® IAM ããŒã«ã¯ã¢ã«ãŠã³ãåäœã®èšå®ã§ã Amazon API Gateway ã®ãã°ã Amazon CloudWatch Logs ã«æžã蟌ãããã® IAM ããŒã«èšå®ã玹ä»ããŸãã blog.usize-tech.com 2024.07.01 ãŸãšã ãããã§ããã§ããããïŒ Amazon DynamoDB ã® API ããã®ãŸãŸäœ¿ãã ãã®èŠä»¶ã§ããã°ãååå®çšçã§ãããšæããŸãããVTL ã§ã¯å¯Ÿå¿ããããªãæååå å·¥ãããžãã¹ããžãã¯ãå¿
èŠã«ãªãå Žåã¯ããã¯ã AWS Lambda 颿°ãéã«æãå¿
èŠããããŸãã AWS AppSync ã®ãããã³ã°ãã³ãã¬ãŒãã§ã¯äŸ¿å©ãªç¬èªé¢æ°ãçšæãããŠããã®ã§ãããAmazon API Gateway ã§ã¯æšæº VTL ãçšæããŠãããã®ãã䜿ããªããããªã®ã§ (å
¬åŒããã¥ã¡ã³ããèŠãéãã§ã¯) ãAWS AppSync ã®æ¹ãããèéã¯å©ãããããšããå°è±¡ã§ããã æ¬èšäºãçæ§ã®ã圹ã«ç«ãŠãã°å¹žãã§ãã