AWSにServerless Frameworkを利用してRESTfulAPIを作成する際、クエリー文字列などの引数を取得する方法についてメモします。今回はAPI Gatewayのテンプレート関連の機能は使わず、Lambda側ですべて処理します。利用する言語はNode.jsです。
目次
基本的な考え方
クエリーを受け取る
引数eventの中にqueryStringParameters
というプロパティがありますので、これを参照するだけ。例えばURL/dev/hello?foo=bar
のクエリfooを参照したかったら以下のようにするだけです。
module.exports.echo1 = async event => {
const foo = event.queryStringParameters.foo;
// (略)
}
ただこれだけだとfooが渡されなかった場合に実行時エラーとなってしまうため、以下のようにチェックが必要です。
module.exports.echo1 = async event => {
const query = event.queryStringParameters;
const foo = ((query !== null) && ("foo" in query))? query.foo:"fooが渡されませんでした";
// (略)
}
クエリーが1件も渡されなかった場合はevent.queryStringParameters
はnull
になります。
リクエストボディを受け取る
POSTなどで渡されたリクエストボディのデータを受け取りたい場合はevent.body
を参照します。ただし特にパースやデコードが一切されていない生の文字列のまま入っていますので、扱いやすいように下準備をする必要があります。
application/json
以下の例ではJSON形式で渡されたリクエストボディをJavaScriptで扱えるようにパースを行っています。こちらもクエリーと同様にリクエストボディが空の状態で呼び出された場合event.body
はnull
になります。
module.exports.echo1 = async event => {
const body = JSON.parse(event.body);
const foo = ((body !== null) && ("foo" in body))? body.a:"fooが渡されませんでした";
// (略)
}
x-www-form-urlencoded
JSON形式ではなくa=123&b=456
といった形式の文字列を扱う場合には、自前でデコード&パース処理を書いても良いのですが既存のモジュールを使ってあげると手早くできます。
というわけでquery-stringモジュールをインストール。
$ npm install query-string
以下のようにモジュールを読み込みevent.bodyをparseしてあげるだけです。
const queryString = require("query-string");
module.exports.echo2 = async event => {
const body = queryString.parse(event.body)
// 略
}
実際に試している
準備
今回は「echo」という名前のプロジェクトを作成しました。
$ serverless
Serverless: No project detected. Do you want to create a new one? Yes
Serverless: What do you want to make? AWS Node.js
Serverless: What do you want to call this project? echo
ディレクトリが作成されているはずですので、中に入ってnpm init
しておきます。
$ cd echo
$ npm init
このあたりの詳細は過去記事を参照ください。
サンプルコード
serverless.yml
プロジェクトの設定を行います。URL/(stage)/echo
をGETでリクエストするとecho1を、POSTでリクエストするとecho2を実行するよう設定しています。
service: echo
provider:
name: aws
runtime: nodejs12.x
functions:
echo1:
handler: handler.echo1
events:
- http:
path: echo
method: get
echo2:
handler: handler.echo2
events:
- http:
path: echo
method: post
handler.js
実際のコードです。handler.jsの中に以下の2つの関数をそのまま貼り付けます。
'use strict';
/**
* GET /(stage)/echo?foo=xxxxx
*/
module.exports.echo1 = async event => {
const query = event.queryStringParameters;
const foo = ((query !== null) && ("foo" in query))? query.foo:"foo is empty";
return {
statusCode: 200,
body: JSON.stringify(
{
message: 'Im echo1',
query: foo,
},
null,
2
),
};
};
/**
* POST /(stage)/echo/
* foo=xxxxx
*/
module.exports.echo2 = async event => {
const body = JSON.parse(event.body)
const foo = ((body !== null) && ("foo" in body))? body.foo:"foo is empty";
return {
statusCode: 200,
body: JSON.stringify(
{
message: 'Im echo2',
body: foo,
},
null,
2
),
};
};
デプロイ
deployコマンドでAWSへ反映します。
$ serverless deploy
途中でURLが表示されるのでこれをメモします。
endpoints:
GET - https://38unnrqr5b.execute-api.us-east-1.amazonaws.com/dev/echo
POST - https://38unnrqr5b.execute-api.us-east-1.amazonaws.com/dev/echo
実行する
ではcurlコマンドで挙動を確認します。まずはGETでクエリー文字列を取得します。
$ curl 'https://38unnrqr5b.execute-api.us-east-1.amazonaws.com/dev/echo?foo=12345'
{
"message": "Im echo1",
"query": "12345"
}
次にPOSTでリクエストボディの値を取得します。
$ curl -X POST \
-H "Content-Type: application/json" \
-d '{"foo":67890}' \
'https://38unnrqr5b.execute-api.us-east-1.amazonaws.com/dev/echo'
{
"message": "Im echo2",
"body": 67890
}
参考ページ
このブログを応援する
お寄せいただいたお気持ちは全額サーバ代や次の記事を執筆するための原資として活用させていただいております。この記事が参考になった場合などぜひご検討ください。
同じカテゴリの記事
- [AWS] ECRにDockerイメージをプッシュする
- [AWS] S3へMIMEタイプを自動判定しながらアップロードする – Node.js
- [AWS] Serverless FrameworkでS3にファイルが追加されたらLambdaを起動する
- [AWS] CloudFrontのオリジンを動的に変更する – Lambda@Edge + Node.js
- [AWS] Serverless FrameworkでLambdaをArm64対応する
- [AWS] CloudFront+S3オリジンでindex.htmlを省略する – Lambda@Edge + Node.js
- [AWS] CloudFrontでBASIC認証を行う – Lambda@Edge + Node.js
- [AWS] Comprehendで日本語の感情分析を行う