API Gateway で統合レスポンスのマッピングテンプレートを使って特定条件時にリダイレクトさせる

2022.06.27

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

いわさです。

API Gateway でHTTPバックエンドと統合しているときに、特定APIあるいは特定の統合レスポンスの結果に応じて、クライアントに対してリダイレクト処理を行いたいシーンがありました。
統合バックエンドでリダイレクトヘッダーを生成してAPI Gatewayでは単純にパススルーだけする方法ももちろん出来ますが、何らかの理由でAPI Gateway側で制御したい場合を考えて試してみます。

設定

ここでは、統合バックエンドにHTTPエンドポイントを指定し、レスポンスに特定の要素が含まれているときはクライアントへのレスポンスステータスの変更とレスポンスヘッダーの追加を行ってみたいと思います。

まず、マッピングテンプレートを使う場合は統合リクエストのプロキシ統合は無効化することでカスタム統合を有効化します。
プロキシ統合とカスタム統合の違いは以下を参照してください。

あとは統合レスポンスでマッピングテンプレートを設定してます。

マッピングテンプレートでは、Velocity Template Language (VTL) エンジンを使用しています。

Apache Velocity Engine VTL Reference

また、AppSyncのりゾルパーマッピングテンプレートでもVTLが必要になるので、そちらのプログラミングガイドで基本構文を学ぶことも出来ます。

ここでは以下のように、Bodyのlocation要素があればHTTPステータスを302に変更し、ヘッダーに値をマッピングします。
特定要素が含まれていない場合は、そのままBodyを出力します。

#if(!$input.path('$.location').isEmpty())
    #set($context.responseOverride.status = 302)
    #set($context.responseOverride.header.location = $input.path('$.location'))
#else
$input.json('$')
#end

ちなみに、メソッドレスポンスでヘッダーを定義して、統合レスポンスのヘッダーマッピングで統合レスポンスを出力することも出来ますが、今回は分岐処理などを入れたかったのでマッピングテンプレートを使います。
統合レスポンスデータをメソッドレスポンスヘッダーにマッピングしたい場合は以下を参照してください。

統合レスポンスデータをメソッドレスポンスヘッダーにマッピングする - Amazon API Gateway

確認

今回はバックエンドにLambdaの関数URLを指定していますので、Lambdaを変更して統合レスポンス内容を変更しています。

Bodyに特定要素が設定されている場合

lambda_function.py

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        "body": json.dumps({
            'location': 'https://classmethod.jp/'
        })
    }
$ curl https://0a6ikgwbsi.execute-api.ap-northeast-1.amazonaws.com/hoge -i
HTTP/2 302 
date: Sun, 26 Jun 2022 22:00:30 GMT
content-type: application/json
content-length: 0
location: https://classmethod.jp/
x-amzn-requestid: cb3bdcea-5f88-4b3f-ac2b-75de214d123c
x-amz-apigw-id: UWaHyHX_tjMFTwA=
x-amzn-trace-id: Root=1-62b8d6fe-10ddda081fa7266305bd45ae;Sampled=0

マッピングテンプレートで指定したとおり、ステータスコードが302になり、locationヘッダーが設定されています。

Bodyに特定要素が設定されていない場合

lambda_function.py

import json

def lambda_handler(event, context):
    return {
        'statusCode': 200,
        "body": json.dumps({
            'location2': 'https://classmethod.jp/'
        })
    }
$ curl https://0a6ikgwbsi.execute-api.ap-northeast-1.amazonaws.com/hoge -i
HTTP/2 200 
date: Sun, 26 Jun 2022 22:04:03 GMT
content-type: application/json
content-length: 40
x-amzn-requestid: 927f3d92-d3ee-47cd-878d-f87c5ba3a90d
x-amz-apigw-id: UWapHG9cNjMF0Yw=
x-amzn-trace-id: Root=1-62b8d7d3-4be1ca8f668da38636228e39;Sampled=0

{"location2":"https://classmethod.jp/"}

こちらはリダイレクトのための加工がされずにパススルーされています。

さいごに

本日は、カスタム統合とマッピングテンプレートを使って、API Gatewayの統合レスポンスでデータの変更を行ってみました。
特定ケースでリダイレクトさせたい、データを加工したいというシーンは結構多いので、使い方が覚えておきたいです。

お手軽なので私はプロキシ統合を使いがちなのですが、マッピングテンプレートが使える、ゲートウェイとバックエンドの責務を分担しやすくなるので、使いこなせるようになっておきたいです。