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