SAMを使ってテンプレートからサーバーレスな環境を構築する(その③-API Gatewayを構成に追加後、DynamoDBにログ出力のLambda関数を連携させる)
AWSのホームページの初心者ハンズオンにある「SAMを使ってテンプレートからサーバーレスな環境を構築する 」の内容を自分のAWSアカウントでやってみました。
ハンズオンではAWSホームページで、10本の Youtube-video でもって、翻訳 Web API を AWS Serverless Application Model (AWS SAM) を用いてテンプレートからシステムを構築します。
( 翻訳 Web API はハンズオンシリーズの前回取り扱い分 )
- SAMの概説とCloud9を使った準備作業
- 小手調べでSAMを使って、「Hello Hands on world!」Lambdaを作った後、SAMでTranslate機能をLambda関数として追加して、IAMも許可する
- API Gateway を構成に追加後、DynamoDBにログを書き込むようにLambda関数を連携させる
- SAM CLIも使ってみる。最後にリソースを削除する。
今回の投稿は3パート目で、以下の感じでまず API Gateway を構成 に追加します。
SAMで API Gateway のリソースを作成
AWSドキュメントから「AWS::Serverless::Api」を調べると
「Name」は必須ではない。
「StageName」は必須で、前回ハンズオンで使用した「dev」を使用することにした。
「EndpointConfiguration」は必須ではないが、省略すると「EDGE」になる。
「EndpointConfiguration」は前回、REGIONALを指定しており、合わせるために指定した。
(実際はエンドポイントの最適解を考える)
import json
import boto3
translate = boto3.client(service_name='translate')
def lambda_handler(event, context):
input_text = event['queryStringParameters']['input_text'] ← クエリストリングを受け取るロジックに変更
response = translate.translate_text(
Text=input_text,
SourceLanguageCode="ja",
TargetLanguageCode="en"
)
output_text = response.get('TranslatedText')
↓ 「apigateway統合レスポンス」でAWSドキュメントを検索すると、Lambdaプロキシ統合の出力形式に合わせなければならない
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.9
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess ← Translate機能へのアクセスを追加
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
Lamdbaの構成に「API Gateway」が含まれている。コード内容も確認。
エラーとなるが、
クエリストリングが指定されていないためなので、
指定して再実行する。
今日、大谷選手がMVPに輝きました。
を翻訳できた!!
SAM で DynamoDB TBL を作成し、Lambda 関数を連携させる
import json
import boto3
import datetime
translate = boto3.client(service_name='translate')
(DynamoDBのテーブルを扱う)
dynamodb_translate_history_tbl = boto3.resource('dynamodb').Table('translate-history-2')
def lambda_handler(event, context):
input_text = event['queryStringParameters']['input_text']
response = translate.translate_text(
Text=input_text,
SourceLanguageCode="ja",
TargetLanguageCode="en"
)
output_text = response.get('TranslatedText')
(DynamoDBにログを書き込む)
dynamodb_translate_history_tbl.put_item(
Item = {
"timestamp": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
"input": input_text,
"output": output_text
}
)
return {
'statusCode': 200,
'body': json.dumps({
'output_text': output_text
}),
'isBase64Encoded': False,
'headers': {}
}
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: AWS Hands-on for Beginners - Serverless 2
Resources:
TranslateLambda:
Type: AWS::Serverless::Function
Properties:
FunctionName: translate-function-2
CodeUri: ./translate-function
Handler: translate-function.lambda_handler
Runtime: python3.9
Timeout: 5
MemorySize: 256
Policies:
- TranslateFullAccess
- AmazonDynamoDBFullAccess (DynamoDB機能へのアクセスを追加)
Events:
GetApi:
Type: Api
Properties:
Path: /translate
Method: get
RestApiId: !Ref TranslateAPI
TranslateAPI:
Type: AWS::Serverless::Api
Properties:
Name: translate-api-2
StageName: dev
EndpointConfiguration: REGIONAL
TranslateDynamoDbTbl:
Type: AWS::Serverless::SimpleTable (「SimpleTable」はAWSドキュメント参照)
Properties: (簡易にテーブルを扱うオブジェクト)
TableName: translate-history-2 (Tablenameは前回ハンズオンとバッティングしないように命名)
PrimaryKey: (プライオリティキーは)
Name: timestamp (timestamp)
Type: String (String)
ProvisionedThroughput: (両キャパシティ「1」)
ReadCapacityUnits: 1
WriteCapacityUnits: 1
「translate-history-2」テーブルが出来ている
Lambda関数の「設定」タブから
リソースの概要で、
「Amazon DynamoDB」
が利用可能であることが分かる。
input_textにクエリストリング
を指定して、実行!!
ちゃんと翻訳されている!!
これで、ほぼWebAPIの機能が出来上がりました!!
今回は、その3- API Gateway 追加、DynamoDBにログ出力を実装しました。
次回は、その4- SAM CLIを使ってみる!!最後にリソースを削除!!