API Gateway が「Lambda プロキシ統合」でさらに使いやすくなっててびっくりした話

2019.05.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

こんにちは、みかみです。データインテグレーション(DI)部に所属しています。

分析基盤などのデータまわりを主に扱う部署なので、ふだん業務で API Gateway を使うことはあまりないのですが、以前、勉強会のセッション内容に啓発されて触ってみたことがありました。

当時でも、初めて触る API Gateway の環境構築の簡単さに驚きましたが、ひさしぶり(2年以上ぶりでした。。)に触ってみたら、さらに使いやすくなっててびっくりしました!

前回つまずいたのが、API Gateway の、リクエストとレスポンスのマッピング設定。 マッピングテンプレートを登録する必要があり、テンプレートの書き方とかよく分からず。。

それが「Lambda プロキシ統合」を使うと、API Gateway がよしなにマッピングしてくれちゃうそうな!v

やりたいこと

API Gateway + Lambda 構成で、Lambda の処理結果次第で別の画面にリダイレクトしたい。

やってみた

Lambda関数を作成する

まずは、API Gateway から call される実処理部の Lambda 関数を作成します。

AWS管理コンソールの「サービス」から「Lambda」を選択し、「関数の作成」ボタンをクリック。

「一から作成」で「関数名」に任意の関数名を入力。 今回、コードは「Python 3.7」で作成します。

「関数コード」を書き換えます。

API Gateway から渡されたパラメータを取得して、何か処理して、リダイレクトのステータス(301)と url を返します。 エラー(exception)の場合は、リダイレクト先をエラー画面に変えました。

import json

def lambda_handler(event, context):
    try:
        id = event.get('queryStringParameters').get('id')
        print(id)   # 実際はここで何か処理
        url_redirect = 'https://classmethod.jp/'
        body = 'id = {} --> OK!'.format(id)
    except Exception as e:
        print(e)    # 実際はここで何かエラー処理
        url_redirect = 'https://classmethod.jp/error/'
        body = 'ERROR.....'

    return {
        'statusCode': 301,
        'headers': {
            'Location': '{}'.format(url_redirect)
        },
        'body': json.dumps(body),
        'isBase64Encoded': False
    }

レスポンスのフォーマットに注意。

API を作成する

次は API の作成です。

「サービス」>「API Gateway」から、「APIの作成」ボタンをクリック。

「REST」と「新しいAPI」チェックはデフォルトのままで、「API 名」(必要ならば「説明」にも)に任意のAPI名を入力し、「API の作成」ボタンをクリック。

「アクション」プルダウンから「メソッドの作成」を選択。

さらにプルダウンから「GET」を選択し、横のチェックマークをクリック。

「セットアップ」画面、「統合タイプ」は「Lambda 関数」のままにして、「Lambda プロキシ統合の使用」チェックボックスをチェックします。 「Lambda 関数名」に先ほど作成した Lambda 関数名を入力したら、「保存」ボタンをクリック。

「Lambda 関数に権限を追加する」ポップアップが表示されるので、「OK」ボタンをクリックしたら、API の作成完了です。

API のリクエストとレスポンスを設定する

「メソッドリクエスト」から、リクエスト URL の?以降で指定するパラメータ名を設定します。

「URL クエリ文字列パラメータ」部分の「クエリ文字列の追加」をクリック。

パラメータ名を入力して、横のチェックマークをクリック。

これでリクエストの設定は完了。 続いてレスポンスの設定です。

「メソッドレスポンス」をクリックしたら、「HTTP のステータス」にある200は消して(今回は別画面にリダイレクトしたいため)、「レスポンスの追加」をクリックします。

リダイレクトのStatusCode、301を入力して横のチェックマークをクリック。

さらに「ヘッダーの追加」をクリックして、「名前」に「Location」と入力します。 これで、Lambda からのレスポンス内の Location が、API Gateway が返すヘッダの Location にマッピングされます。

テスト&デプロイ

テスト画面で「クエリ文字列」にパラメータを指定して「テスト」します。

実行結果、StatusCode 301で、レスポンスヘッダーのLocationに Lambda 側で指定したリダイレクト先 URL が入っているのが確認できました。

ちゃんと動いているようなので、デプロイします。

「アクション」プルダウンから「API のデプロイ」を選択。

「新しいステージ」を選択して、任意のステージ名を入力。 「デプロイ」ボタンをクリックしたら、デプロイ完了です。

画面上部の「URL の呼び出し」部分に表示されているのが、今デプロイした API の URL です。

APIをたたいてみる

ブラウザにAPI の URL を入力して、ちゃんとリダイレクトするかどうか、確認してみます!

あれ? エラー画面? とりあえず、リダイレクトはしたけども。。。

→URL にパラメータ指定し忘れてたので、Lambda 関数で exception になっちゃってましたw

改めて、URL の最後に ?id=1234 を付け足して・・・

正常ルートの期待画面にも、無事リダイレクトできました!

まとめ(所感)

個人的に、ここのところ沖縄だよりを言い訳にしてしばらく書いていなかった「技術ブログ」を久しぶりに書きたいと思うくらい、API Gateway の「Lambda プロキシ統合」すごく使いやすいと思いました!><w

Lambda の処理時間制限も緩和されたことですし(古い話ですみません。。)、これはますますサーバレスの機運でしょうか?!@@v