3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

aws-nodejs-typescriptで作成したlambdaを使ってStep Functionsを構築したらハマったこと

Posted at

はじめに

ServerlessFrameworkaws-nodejs-typescriptテンプレートを使って構築したlambdaを使ったStep Functionsを構築した時にエラーになったので、修正内容をメモ。

Step Functionsとは

こちらの記事がわかりやすい

Step Funcitons構築

  1. 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
    
  2. Plugin: serverless-step-functionsのインストール

    serverless.yml
      service: '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
    
  3. serverless.tsの修正

    今回は試しとして、lambdaが1つだけある構成で作ってみる。
    lambdaはPOST: hellowがすでに作られているので、それを使う。

    構成

    公式から例を拾ってくる

    serverless.yml
    stepFunctions:
      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.ts
      stepFunctions: {
        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
                }
              }
            }
          }
        }
      }
    
  4. デプロイ

    sls deploy
    
    ・・・
    
    ✔ Serverless StepFunctions OutPuts
    endpoints:
      POST - https://************.execute-api.us-east-1.amazonaws.com/dev/gofunction
    
  5. 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}
    

    それらしいレスポンスが帰ってきた

  6. マネジメントコンソールから実行結果を確認してみる

    スクリーンショット 2023-02-14 1.49.39.png

    失敗していた

失敗の原因調査

step functionsでは失敗のログが出力されるので、それを確認すると、

Type
{
  "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)"
  ]
}

このように出ており、middyContent-Typeundefinedに対して呼ばれているようでした。

実際に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は使わないように直してあげれば良さそうです。

handler.ts
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}

スクリーンショット 2023-02-14 20.12.57.png

成功!

入出力もコンソールから確認できて良い感じですね

スクリーンショット 2023-02-14 20.13.41.png

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?