はじめに
ServerlessFramework
のaws-nodejs-typescript
テンプレートを使って構築したlambdaを使ったStep Functions
を構築した時にエラーになったので、修正内容をメモ。
Step Functionsとは
こちらの記事がわかりやすい
Step Funcitons構築
-
sls create
sls create --template aws-nodejs-typescript
これで以下ファイルが生成される
$ tree -L 1 . ├── README.md ├── node_modules ├── package.json ├── pnpm-lock.yaml ├── serverless.ts ├── src ├── tsconfig.json └── tsconfig.paths.json
-
Plugin:
serverless-step-functions
のインストールserverless.ymlservice: 'step-functions', frameworkVersion: '3', // serverless-step-functions追加 plugins: ['serverless-esbuild', 'serverless-step-functions'], provider: { name: 'aws', runtime: 'nodejs14.x',
serverless plugin install -n serverless-step-functions
-
serverless.tsの修正
今回は試しとして、lambdaが1つだけある構成で作ってみる。
lambdaはPOST: hellow
がすでに作られているので、それを使う。公式から例を拾ってくる
serverless.ymlstepFunctions: stateMachines: hellostepfunc1: events: - http: path: gofunction method: GET name: myStateMachine definition: Comment: "A Hello World example of the Amazon States Language using an AWS Lambda Function" StartAt: HelloWorld1 States: HelloWorld1: Type: Task Resource: Fn::GetAtt: [hello, Arn] End: true
これを
POST
にし、corsを有効にして、`serverless.tsに書き直すと↓のようになる。ただし、Commentは使えなかったので外しています。
serverless.tsstepFunctions: { stateMachines: { hellostepfunc1: { events: [{ http: { path: 'gofunction', method: 'POST', cors: { origin: "*", headers: [ "Content-Type", "X-Amz-Date", "Authorization", "X-Api-Key", "X-Amz-Security-Token", "X-Amz-User-Agent" ] } } }], name: 'myStateMachine', definition: { Commnet: "A Hello World example of the Amazon States Language using an AWS Lambda Function", StartAt: 'HelloWorld1', States: { HelloWorld1: { Type: 'Task', Resource: { 'Fn::GetAtt': ['hello', 'Arn'] }, End: true } } } } } }
-
デプロイ
sls deploy ・・・ ✔ Serverless StepFunctions OutPuts endpoints: POST - https://************.execute-api.us-east-1.amazonaws.com/dev/gofunction
-
POSTリクエストを送ってみる
$ curl -X POST -H "Content-Type: application/json" -d '{"name":"太郎"}' https://***********.execute-api.us-east-1.amazonaws.com/dev/gofunction {"executionArn":"arn:aws:states:us-east-1:**********:execution:myStateMachine:***************-*******","startDate":1.67637299142E9}
それらしいレスポンスが帰ってきた
-
マネジメントコンソールから実行結果を確認してみる
失敗していた
失敗の原因調査
step functionsでは失敗のログが出力されるので、それを確認すると、
{
"errorType": "TypeError",
"errorMessage": "Cannot read property 'Content-Type' of undefined",
"trace": [
"TypeError: Cannot read property 'Content-Type' of undefined",
" at httpJsonBodyParserMiddlewareBefore (/node_modules/.pnpm/@middy+http-json-body-parser@3.6.2/node_modules/@middy/http-json-body-parser/index.js:13:29)",
" at runMiddlewares (/node_modules/.pnpm/@middy+core@3.6.2/node_modules/@middy/core/index.js:118:27)",
" at runRequest (/node_modules/.pnpm/@middy+core@3.6.2/node_modules/@middy/core/index.js:78:15)",
" at Runtime.middy2 (/node_modules/.pnpm/@middy+core@3.6.2/node_modules/@middy/core/index.js:32:16)",
" at Runtime.handleOnceNonStreaming (/var/runtime/Runtime.js:74:25)"
]
}
このように出ており、middy
でContent-Type
がundefined
に対して呼ばれているようでした。
実際にlambdaのコードを見てみると、この部分でした。👇
const httpJsonBodyParserMiddlewareBefore = async (request) => {
const { headers, body } = request.event;
// headersがundefinedになっていた
const contentType = headers["Content-Type"] ?? headers["content-type"];
middyとは
「AWS Lambda 向け軽量Node.jsミドルウエアエンジン」と紹介されていました。
詳しくは調べてみてください。
修正
step functionsのlambaでは、headersやbodyがundefined
になってしまうため、
middyは使わないように直してあげれば良さそうです。
const hello = async (event) => {
return {
message: `Hello ${event.body.name}, welcome to the exciting Serverless world!`,
event,
};
};
export const main = hello;
再度POSTリクエストを送ってみる
$ curl -X POST -H "Content-Type: application/json" -d '{"name":"太郎"}' https://***********.execute-api.us-east-1.amazonaws.com/dev/gofunction
{"executionArn":"arn:aws:states:us-east-1:**********:execution:myStateMachine:***************-*******","startDate":1.67637299142E9}
成功!
入出力もコンソールから確認できて良い感じですね