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を使ってテンプレートからサーバーレスな環境を構築する

SAMで API Gateway のリソースを作成

パッケージング & デプロイ

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/sam-specification-resources-and-properties.html

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
Lambda関数が追加されているのを確認

Lamdbaの構成に「API Gateway」が含まれている。コード内容も確認。

API Gateway 画面を開いて、API Gateway(translate-api-2)が出来ていることを確認
GETメソッドに対して、「translate-api-2」が呼び出される構成であると分かる
「ステージ」→「dev」→「GET」→ URLの呼び出し のリンククリック

エラーとなるが、
クエリストリングが指定されていないためなので、
指定して再実行する。

今日、大谷選手がMVPに輝きました。
を翻訳できた!!

SAM で DynamoDB TBL を作成し、Lambda 関数を連携させる

SAMを使ってテンプレートからサーバーレスな環境を構築する
Cloud9 で作業
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関数も変更されている

Lambda関数の「設定」タブから
リソースの概要で、
「Amazon DynamoDB」
が利用可能であることが分かる。

API Gateway のAPIの「ステージ」からURLの呼び出しのリンクをクリック

input_textにクエリストリング
を指定して、実行!!
ちゃんと翻訳されている!!

DynamoDB に 翻訳結果がログされている!!

これで、ほぼWebAPIの機能が出来上がりました!!
今回は、その3- API Gateway 追加、DynamoDBにログ出力を実装しました。
次回は、その4- SAM CLIを使ってみる!!最後にリソースを削除!!