Powertoolsでリクエストパラメータをバリデーションする

AWS Lambda Powertoolsを使うと、Lambdaに渡されるリクエストパラメータのバリデーションを容易に実現できる。
…のだが、一部のパターンでハマったのでメモしておく。

公式ドキュメントはここ

POST (JSON、Base64Encodeなし)の実装サンプル

Lambdaのエントリポイントはlambda_handler関数。

from aws_lambda_powertools.utilities.validation import envelopes, validator
from aws_lambda_powertools.utilities.validation.exceptions import SchemaValidationError
import json

# リクエストパラメータの仕様をJSONスキーマで定義する
INPUT = {
    "$schema": "http://json-schema.org/draft-07/schema",
    "type": "object",
    "examples": [{"date": "20220720"}],
    "required": ["date"],
    "properties": {
        "date": {
            "type": "string",
            "pattern": "^[0-9]{8}$",
        },
    },
}

@validator(inbound_schema=INPUT, envelope=envelopes.API_GATEWAY_HTTP)
def validate(event, context):
    # バリデーション済のリクエストパラメータ部のみを返す。(デコレータにて、既に処理が行われている)
    return event

def lambda_handler(event, context):
    try:
        # バリデーション済のリクエストパラメータを受け取る
        validated_parameters = validate(event, context)
        return {
            "statusCode": 200,
            "body": json.dumps({
                "message": validated_parameters["date"]
            })
        }
    except SchemaValidationError as e:
        # バリデーションエラーの場合は、Bad Requestを返す
        return {
            "statusCode": 400,
            "body": json.dumps({
                "message": e.validation_message
            })
        }

GETの場合のenvelope指定

GETではenvelopeにそのまま使えるような定数が用意されていないため、JMESPath形式で記述する必要がある。
GETの場合、リクエストパラメータはクエリストリングとしてevent["message"]["queryStringParameters"]に格納される。
これをJMESPath形式で指定するには"queryStringParameters"とすればOK。
それ以外はすべてPOSTの場合と同様で動作する。

@validator(inbound_schema=INPUT, envelope="queryStringParameters")
def validate(event, context):
    return event

ただしクエリストリングの特性上、JSONスキーマではすべてStringのパラメータとする必要があることに注意。

POST (JSON、Base64Encodeあり)の場合のenvelope指定

どうやらAWS Lambda Function URLsでは、POSTのJSONはBase64Encodeされた状態でbodyに格納される模様。
このような場合でもenvelopeを以下のように指定することで、bodyのBase64デコード+JSONパースを行うことができる。

@validator(inbound_schema=INPUT, envelope="powertools_json(powertools_base64(body))")
def validate(event, context):
    return event

関連記事


  1. AWSソリューションアーキテクト アソシエイトに合格しました
  2. Google検索とChatAIにみる、エンタープライズサーチとRAGの未来
  3. Spring BootをGoogle App Engineフレキシブル環境へデプロイする
  4. Spring BootをGoogle App Engineスタンダード環境にデプロイする

comments powered by Disqus