初めてのサーバーレスアプリケーション開発 ~API GatewayからLambdaを呼び出す~

前回はDynamoDBから項目を取得するLambdaを作成しました。今回は第3回ということでバックエンドでLambdaを実行するAPI Gatewayを作成していきます。

↓追加しました。

対象読者

  • サーバーレスアプリケーション開発未経験の方
  • サーバーレスに縁のないインフラエンジニアの方

本記事を実践して、API Gateway、Lambda、DynamoDBと仲良くなりましょう!!

それでは本題に入っていきます。

サーバーレスアプリケーション超入門

今回構築するアプリケーションの全体構成はこちら。

今回は前回作成したLambda関数をインターネットから呼び出すための入り口(API Gateway)を作成していきます。

API Gateway

API Gatewayとは何なのか。公式ドキュメントよりAPI Gatewayの概要を抜粋します。

Amazon API Gateway は全面的に管理されたサービスで、開発者はこれを利用することにより、どのようなスケールであっても、簡単に API の作成、配布、保守、監視、保護が行えます。AWS マネジメントコンソールで数回クリックするだけで、Amazon Elastic Compute Cloud (Amazon EC2) で稼働中のワークロードや、AWS Lambda で稼働中のコード、または任意のウェブアプリケーションといった、バックエンドからのデータ、ビジネスロジック、機能にアクセスする、アプリケーションの玄関として振る舞う API を作成できます。

Amazon API Gateway では、トラフィック管理、認可とアクセスコントロール、モニタリング、API バージョン管理など、最大数十万個の同時 API 呼び出しの受け入れと処理に伴うすべてのタスクを取り扱います。Amazon API Gateway に最低料金や初期費用は発生しません。受信した API 呼び出しと、送出したデータ量に対してのみ料金が発生します。

もう少し詳しく知りたい方は、Black Beltの資料もご覧ください。※資料は最新のものではないため適宜公式ドキュメントを参照してください。

冒頭でも記載しましたが、今回は前回作成したLambda関数をインターネットから呼び出すための入り口(API Gateway)作成していきます。

API Gatewayを作ってみよう

では、早速作ってみましょう。

1.1.API Gateway作成

AWSマネジメントコンソールよりAPI Gatewayを選択します。

「APIの作成」をクリックします。

API名にdemo-apiと入力し「APIの作成」をクリックします。

1.2.メソッドの作成

API Gatewayがリクエストを受け付けるhttpのメソッドを定義します。今回は特定のURLでGetリクエストを受けた時にバックエンドのLambdaを起動するように設定します。

「アクション」より「メソッドの作成」をクリックします。

Getを選択し、チェックボタンをクリックします。

バックエンドのLambdaを選択します。ここでは前回作成したdemo-get-personを指定します。

API GatewayからのLambda関数呼び出しを許可します。

1.3.テスト実施

この時点ではまだインターネットに公開されていませんが、簡単なテストを実施することは可能です。「テスト」ボタンをクリックします。

「テスト」ボタンをクリックします。

Lambda関数が実行されperson情報がレスポンスとして返却されていることが確認できます。

1.4.本文マッピングテンプレート追加

現状、Lambdaを実行時にはレスポンスとして常にperson_id:001が返却されます。これではちょっとつまらないですよね。

ということで、まずAPI Gateway側からLambdaに変数を引き渡す設定を追加します。

「統合リクエスト」をクリックします。

「マッピングテンプレートの追加」をクリックします。

Content-Typeにapplication/jsonを入力し、チェックマークをクリックします。

「はい、この統合を保護します」をクリックします。

テンプレートの内容に以下を入力し、「保存」をクリックします。

{
    "person_id" : "$input.params('person_id')"
}

1.5.Lambda修正

API Gatewayからperson_idを受け取り、その値を元にDynamoDBから情報を取得するようコードを修正します。以下のように変更し、「保存」ボタンをクリックします。

import boto3
 
dynamodb = boto3.resource('dynamodb')
table    = dynamodb.Table('demo-person')
 
def get_person(id):
    response = table.get_item(
            Key={
                 'person_id': id
            }
        )
    return response['Item']
         
def lambda_handler(event, context):
    person = get_person(event['person_id'])
    return person

1.6.APIのデプロイ

APIをインターネットに公開します。「アクション」より「APIのデプロイ」をクリックします。

ステージ名をdemoとし、「デプロイ」ボタンをクリックします。

URLが表示されます。

このURLの後ろにperson_id=001を付与しブラウザからリクエストを送ってみます。

このURLの後ろにperson_id=002を付与しブラウザからリクエストを送ってみます。

想定通りの値が取得できています。

ただ、現状ではURLの後ろにperson_idを指定しないとエラーになってしまいます。せっかくなのでperson_idの指定がなかったら全てのpersonを返却するようLambdaを変更してみましょう。

1.7.Lambda修正

import boto3
 
dynamodb = boto3.resource('dynamodb')
table    = dynamodb.Table('demo-person')
 
def get_person(id):
    response = table.get_item(
            Key={
                 'person_id': id
            }
        )
    return response['Item']

def get_persons():
    response = table.scan()
    return response['Items']
    
def lambda_handler(event, context):
    return get_persons() if event['person_id'] == '' else get_person(event['person_id'])

14行目に全てのperson情報を取得する関数を追加し、person_idが空だった場合にはこの関数を実行するよう修正しました。

person_idの指定がない場合は、全てのperson情報が取得できています!!

さいごに

API Gateway、Lambda、DynamoDBを使って簡単なアプリケーションを作成しました。今までこれらのサービスがよくわからなかった方も処理のイメージができるようになったのではないでしょうか。