APIGatewayの新機能Request Validationを試してみた

こんにちは、エンジニアの最上です。今回は、新しく発表されましたAPIGatewayのAutomatic Request Validationを試してみます。

この機能は、HTTPリクエストのqueryString、header、bodyパラメータのバリデーションを行います。例えば、APIGatewayの後ろにLambdaを設定した場合、メリットは下記が考えられます。

  • 本当に書かなければならないロジックのみ書けばよくなる
  • パラメータ不足の場合にLambdaが起動しないので、料金が節約できる

早速試してみましょう。

検証環境の準備

コンソールからポチポチとつくってみましょう。

f:id:mti-hackers:20170707182501p:plain

ひとまず、上記画像のように、/testに対してGET,POSTメソッドを作成します。LAMBDAプロキシ統合にはチェックを入れるようにしてください。そして、これらのメソッドには下記のような処理を行うLambdaへリクエストを流すように設定します。

exports.handler = (event, context, callback) => {
    callback(null, {
        headers: {},
        statusCode: 200,
        body: 'success.'
    });
};

想定としては、パラメータが正しく設定されたリクエストに対してはsuccessを返すAPIです。

Parameter Validationの設定と検証

GETの設定

GETの場合は非常に簡単です。GETのメソッドリクエストから下記画像のように設定します。

f:id:mti-hackers:20170707182528p:plain

param1は任意、param2は必須とします。設定ができたら、APIGatewayをデプロイします。

GETの検証

まずはシンプルに、/testにGETリクエストします。レスポンスはこんな感じでした。

{
    "message": "Missing required request parameters: [param2]"
}

なるほど、不足しているパラメータが列挙されそうな感じですね。何が足りないのかを隠す方法はパッと探した感じでは見当たりませんでした。(そもそも、このAPIGWの呼び出しをAWS_IAMやAPIキーで縛ってしまえば、セキュリティの面では問題なさそうです。)

次は、/test?param2=hogeにGETリクエストします。レスポンスはsuccess.でした。予想通りですね。

POSTの設定

POSTの場合はJSON Schemaで設定する必要があるようです(型やObjectのネストがあるためでしょう)。

APIGWの左側のメニューからモデルを選択し、Testモデルを作成します。スキーマは下記にしました。str(String)とnum(Number)を必須として設定しています。

{
    "title": "Test",
    "type": "object",
    "properties": {
        "str": {
            "type": "string"
        },
        "num": {
            "type": "number"
        }
    },
    "required": ["str", "num"]
}

作成が完了したら、メソッドリクエストのリクエスト本文から、作成したTestモデルを選択します。これで設定は完了です。

POSTの検証

/testのbodyに{}(空オブジェクト)を設定してPOSTリクエストを投げます。

{
  "message": "Invalid request body"
}

POSTでは、シンプルにInvalid request bodyと返ってきました。

続いては、下記をbodyとしてPOSTしてみます。

{
  "str": "hoge",
  "num": 123
}

この場合は、予想通りsuccess.と返ってきました。

試しにnumをStringにしてみます。

{
  "str": "hoge",
  "num": "123"
}

すると、ちゃんとInvalid request bodyと返ってきました。

まとめ

パラメータチェックのコードを書かなくてもよいのはとっても楽でよいですね。ただ、この設定が正しく出来ているかをテストするのが難しそうなので、実案件で利用するかどうかは要検討といったところだと思います。

おわり。