aws-serverless-expressで配列なクエリパラメータを扱う


※ 2019/04/18時点の記事です。

やりたかったこと

aws-serverless-expressを利用している開発で、GETリクエストに配列のクエリパラメータを指定したかった。

expressのドキュメントのこんな感じで。

// GET /shoes?color[]=blue&color[]=black&color[]=red
req.query.color
// => [blue, black, red]

で、プログラムの方でいい感じにデータ取りたかった。
素直にやろうとしたらできなかったので諸々調べた備忘録として残す。

最終的な実現方法

ちょっと邪悪な感じになってますので、よりよい方法なんかがあればアドバイスください...

tsです
export function handle(event: APIGatewayEvent, context: Context): void {
    if (event.queryStringParameters && event.multiValueQueryStringParameters) {
        Object.keys(event.queryStringParameters).forEach(key => {
            if (key.match(/\[\]/) && Object.keys(<any>event.multiValueQueryStringParameters).includes(key)) {
                (<any>event.queryStringParameters)[key] = (<any>event.multiValueQueryStringParameters)[key];
            }
        });
    }
    proxy(server, event, context);
}

aws-serverless-expressproxy() に渡す前に、event.multiValueQueryStringParametersの値をevent.queryStringParametersに突っ込みました。

環境

AWS

  • apiGateway
  • lambda(lanbdaプロキシ)

利用しているパッケージ等(package.jsonから抜粋)

  • "typescript": "^2.9.2"
  • "aws-serverless-express": "^3.3.6"
  • "@types/aws-lambda": "^8.10.24"
  • "@types/aws-serverless-express": "^3.3.0"
  • "serverless-offline": "^3.33.0"

経緯

え、配列のクエリ動いてない?

// GET /shoes?color[]=blue&color[]=black&color[]=red

console.log(req.query);

{
    color: ["red"]
}

なるほど(震える)
そうですかキー上書きされますか。

ちなみにこの段階で利用していたパッケージのバージョン

  • "typescript": "^2.9.2"
  • "aws-serverless-express": "^3.2.0"
  • "@types/aws-lambda": "^8.10.7"
  • "@types/aws-serverless-express": "^3.0.1"
  • "serverless-offline": "^3.25.6"

各サービスやパッケージの対応状況を調べる

apiGateway

  • 配列のクエリパラメータに対応してる
    • というか、比較的最近対応した
    • リリース / ドキュメント / ブログ
    • multiValueQueryStringParameters ってやつ
    • ?color=blue&color=black&color=red て感じで使えるようである

@types/aws-lambda

これで型使えます

serverless-offline

ローカルも対応できます

aws-serverless-express

https://github.com/awslabs/aws-serverless-express/issues/196

コア部分なので、お前だけが頼りだ的状況にも関わらずお前だけ...

まあ一応本パッケージと型定義のバージョンはあげておく

それでどう対応しようか考えた結果、 冒頭の「最終的な実現方法」のような対応をしました。