【AWS SAM 入門④】API Gateway で REST API を作成する

 AWS Serverless Application Model 入門ハンズオンシリーズ - log4ketancho の第4弾です。

 前回の記事では、Lambda Function と DynamoDB の連携を AWS SAM を使ってプログラマブルに構築する方法について紹介しました。今回は、SAM で API Gateway を利用する方法について紹介します。

SAM における API Gateway のふたつの利用形式

 ざっくり GitHub ページのドキュメントを読むと、下記のふたつの方法があるようです。

  • Lambda Function の Resources > Events > TypeApi とし、その中で API 定義する
  • AWS::Serverless::Api リソースとして定義し、Swagger 形式で API 定義する

この記事では前者の方法で簡単な API を作ってみます。後者の方式を使ったことがありませんが、規模の小さい API を作る場合は前者でサクッと、規模が大きくなることが想定される場合は後者なのですかね。後者の方式についてもそのうち利用し、まとめてみようと思います。

構築の流れ

 構築の流れは、

  1. template.yaml に新しい Lambda Function の情報を追加する
  2. ↑の Events に API 定義を行う
  3. Lambda Function の実装

となります。この記事では、下記のようなシンプルな API を構築してみます。

  • GET メソッドひとつ
  • クエリパラメータで DynamoDB の PK を渡す
  • Lambda Function は該当するレコードを取得し、JSON 形式にして返却する

テンプレートに API 情報を追加する

 新しい Lambda Function を追加し、Event Type を Api にします。

Resources:
  SamSampleLambda:
    Type: AWS::Serverless::Function
    Properties:
      (省略)
  SamGetFunction: # 新たに追加した Lambda Function 
    Type: AWS::Serverless::Function
    Properties:
      Handler: lambda_function.lambda_handler
      Role: arn:aws:iam::409247736963:role/lambda_dynamo
      CodeUri: 'functions/get_function/lambda_function.py'
      Events:
        Api:
          Type: Api
          Properties:
            Path: /sample
            Method: get
  SamSampleDynamoTable:
    Type: AWS::Serverless::SimpleTable
    Properties:
        (省略)

CodeUri が汚いですね。 'functions/get_function/get_function.py' とファイル名もユニークにするようにした方が良い気がしています。

Lambda Function の実装

 これまでの Lambda Function と似ていますが、下記が変更点となります。

  • DynamoDB から PK でデータを取得するロジックの追加
  • そのために Key パッケージをインポートしている
  • API GW 側に json 形式で返却する必要があるので json.dumps を噛ませて return
# -*- coding: utf-8 -*-
import os
import boto3
import json
import decimal
from boto3.dynamodb.conditions import Key

def lambda_handler(event, context):
    dynamo_tbl = boto3.resource('dynamodb').Table(os.environ['TABLE_NAME'])
    name = event["queryStringParameters"]["name"]

    data = dynamo_tbl.query(
        KeyConditionExpression=Key('name').eq(name)
    )['Items'][0]

    return {
        "statusCode": 200,
        "body": json.dumps({"name": data["name"], "price": str(data["price"])})
    };

これまで同様 package , deploy してみてください。

試し実行

 API GW の画面に移ると、API ができていると思います。下記の画面で、テスト実行してみてください。

f:id:ketancho_jp:20180107011824p:plain

クエリパラメータで渡した値に該当するレコードが取得できていることが分かります。

まとめと今後

 簡単ではありますが、SAM を用いて REST API を作ることができました。いったんここまでで、私が調べたかった SAM の機能について整理することができました。このあと試してみたい・調べたい・まとめてみたいこととして、

  • SAM Local を使ってみる
  • SAM のベストプラクティス
  • Serverless F/W などの他のフレームワークとの比較

がありますが、まずは実際にひとつサービスを SAM で作ってみた上で、これらの調査をしていこうと考えています。

 この記事は、AWS Serveless Application Model 入門シリーズの第4弾です。もしよろしければ1つ目の記事から手を動かしていただければと思います。不明点がございましたら何なりとご連絡ください。

www.ketancho.net