配列をクエリー文字列としてAWS Lambdaに渡す
API Gateway、AWS Lambdaについて説明します.
会社の開発過程で、axiosを使用してarrayをquery stringに入れてバックエンドを要求する際に正しく伝達できないという問題に遭遇しました.
同社のバックエンドはAWS Lambdaのサーバリースに基づくMSAアーキテクチャとして設計されており、理由が判明すると、APIゲートウェイがHTTPリクエストを処理する際に発生する問題であることが分かった.
そこで、本明細書では、AWS LambdaがAPIゲートウェイなどの外部サービスにどのように関連付けられているか、arrayがクエリ文字列に含まれている場合にAPIゲートウェイがどのようにグループ化されているかについて説明します.
AWS Lambda(以下、Ramdaと略す)は、AWS内の他のサービスに関連付けられて呼び出される関数です.
このとき、ramda関数は、ramda関数を実行するAWSサービスに依存するeventというパラメータを受信する.
APIゲートウェイでは、HTTP要求の情報(パス、メソッド、ボディなど)をjson形式でグループ化し、Ramda関数のイベントパラメータに渡す.したがって、ramda関数でリクエストの応答方法を決定できます.
しかしこのようにAPI GatewayとRamdaを接続して使用する際に不便な点は私が今送っているリクエストのイベントですjsonがどんな様子なのか分かりにくい.
AWSに開示されている例またはガイド人を除き、要求情報が記載されていれば、要求されたイベントに該当する.jsonを直接表示するサービスが見つかりません.
そこで、簡単なLambda関数を導入してテストすることにしました.
次に、サーバless frameworkを使用して配置します.serverless.ymlは次のように作成されます.
次に、query stringを使用して配列を渡す方法を見て、APIゲートウェイが各query stringをどのようにグループ化するかを見てみましょう.
query stringでarrayを渡す方法は次のとおりです.
次に、リクエストを上に配置したラムダ関数に送信し、APIゲートウェイが各query stringをラムダにどのようにグループ化するかを検証します.
実験で分かったことは以下の通りです.
APIゲートウェイはquery stringをグループ化し、queryStringParameters、multiValueQuery StringParametersフィールドを介して渡す.
同じキーが複数ある場合、queryStringParametersには最後のkey-valueペアのみが含まれます.
各queryStringParametersとmultiValueQuery StringParametersをqsのライブラリに分割します.
簡単にJavascriptで書いた
1番、3番の方法の1つで、マルチバリュークォーリーStringParametersを使用します.
2番のメソッドを使用して、queryStringParametersを使用します.
4番の方法でqueryStringParametersでJSONみんなに解析してあげる
などルールがたくさんあります
あるいはあなたも状況に応じてすべての症例を処理することができますか?
上記のように、私はまずすべてのケースを処理しました.当社はAWS Lambda専用Webフレームワークを独自に作成し、requestパラメータ検証中
JSON.parseを使用して検証する理由は、qsの出力結果が表示された場合に推測されるためです./1番方法 JSON.解析に失敗しました(アレイ済み) マルチValue Query StringParametersから を読み込むすべての値が に正しく渡されました.
2番方法 JSON.解析成功 Array条件 を通過 JSON.解析結果値 を返します.すべての値が に正しく渡されました.
3番方法 JSON.解析成功 アレイインスタンス条件失敗 マルチValue Query StringParametersから を読み込むすべての値が に正しく渡されました.
4番方法 JSON.解析成功 Array条件 を通過 JSON.解析結果値 を返します.すべての値が に正しく渡されました.
JSON.parseを使用すると、クエリー文字列を使用して配列を渡すすべてのインスタンスを正常に処理できます.
フレームワークを変更してすべてのケースを処理する以外に、私たちのチームはquery stringをarrayとして渡すときに4つ目の方法で強制的に実行することにしました.
axiosリクエストが次のように作成された場合:
概要
会社の開発過程で、axiosを使用してarrayをquery stringに入れてバックエンドを要求する際に正しく伝達できないという問題に遭遇しました.
同社のバックエンドはAWS Lambdaのサーバリースに基づくMSAアーキテクチャとして設計されており、理由が判明すると、APIゲートウェイがHTTPリクエストを処理する際に発生する問題であることが分かった.
そこで、本明細書では、AWS LambdaがAPIゲートウェイなどの外部サービスにどのように関連付けられているか、arrayがクエリ文字列に含まれている場合にAPIゲートウェイがどのようにグループ化されているかについて説明します.
AWS Lambdaと外部サービスの接続
AWS Lambda(以下、Ramdaと略す)は、AWS内の他のサービスに関連付けられて呼び出される関数です.
このとき、ramda関数は、ramda関数を実行するAWSサービスに依存するeventというパラメータを受信する.
APIゲートウェイでは、HTTP要求の情報(パス、メソッド、ボディなど)をjson形式でグループ化し、Ramda関数のイベントパラメータに渡す.したがって、ramda関数でリクエストの応答方法を決定できます.
特定のリクエストのイベント。json
しかしこのようにAPI GatewayとRamdaを接続して使用する際に不便な点は私が今送っているリクエストのイベントですjsonがどんな様子なのか分かりにくい.
AWSに開示されている例またはガイド人を除き、要求情報が記載されていれば、要求されたイベントに該当する.jsonを直接表示するサービスが見つかりません.
そこで、簡単なLambda関数を導入してテストすることにしました.
import { APIGatewayProxyHandler } from "aws-lambda";
export const handler: APIGatewayProxyHandler = async (event) => {
return {
statusCode: 200,
body: JSON.stringify(event)
}
};
リクエストが受信された場合、リクエストのイベント.jsonに応答するコード.次に、サーバless frameworkを使用して配置します.serverless.ymlは次のように作成されます.
service: api-gateway-test
provider:
name: aws
runtime: nodejs12.x
apiGateway:
shouldStartNameWithService: true
lambdaHashingVersion: 20201221
plugins:
- serverless-plugin-typescript
functions:
api:
handler: src/index.handler
events:
- http:
path: /{proxy+}
method: any
pathは/{proxy+}に設定され、methodはanyに設定され、urlおよびすべてのメソッドの要求をramda関数に渡す.次に、query stringを使用して配列を渡す方法を見て、APIゲートウェイが各query stringをどのようにグループ化するかを見てみましょう.
query stringを使用して配列を渡す方法。
query stringでarrayを渡す方法は次のとおりです.
1. ?a[]=1&a[]=2
2. ?a[0]=1&a[1]=2
3. ?a=1&a=2
4. ?a=[1,2]
(axiosのデフォルトで使用される方法は1です.)次に、リクエストを上に配置したラムダ関数に送信し、APIゲートウェイが各query stringをラムダにどのようにグループ化するかを検証します.
1号メソッド結果
2号メソッド結果
3号メソッド結果
4号メソッド結果
実験で分かったことは以下の通りです.
APIゲートウェイはquery stringをグループ化し、queryStringParameters、multiValueQuery StringParametersフィールドを介して渡す.
同じキーが複数ある場合、queryStringParametersには最後のkey-valueペアのみが含まれます.
簡単にJavascriptで書いた
const qs = require("qs");
// ?a[]=1&a[]=2
const result1 = {
queryStringParameters: qs.parse(
qs.stringify({
"a[]": "2",
})
),
multiValueQueryStringParameters: qs.parse(
qs.stringify({
"a[]": ["1", "2"],
})
)
};
console.log("1. ?a[]=1&a[]=2");
console.log(result1);
// ?a[0]=1&a[1]=2
const result2 = {
queryStringParameters: qs.parse(
qs.stringify({
"a[0]": "1",
"a[1]": "2",
})
),
multiValueQueryStringParameters: qs.parse(
qs.stringify({
"a[0]": ["1"],
"a[1]": ["2"],
})
)
};
console.log("2. ?a[0]=1&a[1]=2");
console.log(result2);
// ?a=1&a=2
const result3 = {
queryStringParameters: qs.parse(
qs.stringify({
"a": "2",
})
),
multiValueQueryStringParameters: qs.parse(
qs.stringify({
"a": ["1", "2"],
})
)
};
console.log("3. ?a=1&a=2");
console.log(result3);
// ?a=[1,2]
const result4 = {
queryStringParameters: qs.parse(
qs.stringify({
"a": "[1,2]",
})
),
multiValueQueryStringParameters: qs.parse(
qs.stringify({
"a": ["[1,2]"],
})
)
};
console.log("4. ?a=[1,2]");
console.log(result4);
出力結果は次のとおりです.1. ?a[]=1&a[]=2
{
queryStringParameters: { a: [ '2' ] },
multiValueQueryStringParameters: { a: [ '1', '2' ] }
}
2. ?a[0]=1&a[1]=2
{
queryStringParameters: { a: [ '1', '2' ] },
multiValueQueryStringParameters: { a: [ [Array], [Array] ] }
}
3. ?a=1&a=2
{
queryStringParameters: { a: '2' },
multiValueQueryStringParameters: { a: [ '1', '2' ] }
}
4. ?a=[1,2]
{
queryStringParameters: { a: '[1,2]' },
multiValueQueryStringParameters: { a: [ '[1,2]' ] }
}
出力結果から、問題を簡単に解決するには、チームでルールを作ったほうがいいです.1番、3番の方法の1つで、マルチバリュークォーリーStringParametersを使用します.
2番のメソッドを使用して、queryStringParametersを使用します.
4番の方法でqueryStringParametersでJSONみんなに解析してあげる
あるいはあなたも状況に応じてすべての症例を処理することができますか?
トラブルシューティング
上記のように、私はまずすべてのケースを処理しました.当社はAWS Lambda専用Webフレームワークを独自に作成し、requestパラメータ検証中
function parse(value: any) {
try {
return JSON.parse(value);
} catch (e) {
return value;
}
}
const value = schema.type === "array"
? (() => {
const parsed = parse(queryStringParameters[key]);
if (casted instanceof Array) {
return parsed;
}
return multiValueQueryStringParameters[key];
})()
: queryStringParameters[key];
(実際のコードとは全く同じではありません)もう処理しました.JSON.parseを使用して検証する理由は、qsの出力結果が表示された場合に推測されるためです./
JSON.parseを使用すると、クエリー文字列を使用して配列を渡すすべてのインスタンスを正常に処理できます.
フレームワークを変更してすべてのケースを処理する以外に、私たちのチームはquery stringをarrayとして渡すときに4つ目の方法で強制的に実行することにしました.
axiosリクエストが次のように作成された場合:
await axios.request({
url: "/asdf",
method: "GET",
params: {
a: [1, 2, 3],
b: 123
},
});
最終的には、次のような要求が送信されます.GET /asdf?a[]=1&a[]=2&a[]=3&b=123
ただし、axiosのparamsSerializerオプションを使用すると、query stringを任意に操作できます.axiosは、開発者が設定したparamsオプション値をparamsSerializerの最初のパラメータとして開発者に渡し、qsのようなライブラリに操作します.await axios.request({
url: "/asdf",
method: "GET",
params: {
a: [1, 2, 3],
b: 123
},
paramsSerializer: (params) => {
const mappedParams = _.mapValues(params, (value) => {
if (typeof value === "string") {
return value;
} else {
return JSON.stringify(value);
}
});
return qs.stringify(mappedParams);
}
});
次に示すようにquery stringが変換されて送信されます.GET /asdf?a=[1,2,3]&b=123
Reference
この問題について(配列をクエリー文字列としてAWS Lambdaに渡す), 我々は、より多くの情報をここで見つけました https://velog.io/@alvin/AWS-Lambda에-query-string으로-array-전달하기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol