
Serverlessフレームワークを用いてAPI-GatewayとLambdaの構成でサーバーレスなAPIを作成した場合に、curlをしてみると502となってエラーになってしまう場合があります。今回はその対処法を紹介します。
前提
前提として、Serverlessフレームワークを使ってAPI-Gateway、Lambda、DynamoDBの構成とし、ローカルでのテストが完了しているものとします。Serverlessフレームワークは使っていなくてもよいですが、ローカルですら動いていない場合は、対処法の「その他の可能性」を参考にして下さい。
発生しているエラー
以下のエラーが発生している場合です。
Unable to import module 'src/handler': Error
「src/handler」の場所は適宜読み替えてください。
再現
例えば、Itemのテーブルがあり、それを取得するgetItems関数がある場合を想定します。Item.jsはテーブルのモデルで、handler.js内にgetItems関数が書かれています。
それらがローカルで動くことを確認し、AWS上にデプロイした後、curlでAPIを呼び出します。
$ tree src/
src/
├── models
│ └── Item.js
└── handler.js
$ cat serverless.yml
...
functions:
getItems:
handler: src/handler.getItems
events:
- http:
method: get
path: items
private: true
...
$ sls deploy -s prod
$ curl -v -H 'x-api-key:XXXXXXXXXX' https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/prod/items | jq
...
< HTTP/2 502
...
{
"message": "Internal server error"
}
$ sls logs -f getItems --stage prod
...
Unable to import module 'src/handler': Error
at Function.Module._resolveFilename (module.js:547:15)
at Function.Module._load (module.js:474:25)
at Module.require (module.js:596:17)
at require (internal/module.js:11:18)
at Object.<anonymous> (/var/task/src/models/Item.js:1:78)
at Module._compile (module.js:652:30)
at Object.Module._extensions..js (module.js:663:10)
at Module.load (module.js:565:32)
at tryModuleLoad (module.js:505:12)
at Function.Module._load (module.js:497:3)
...
テーブルが空であれば空のレスポンスが返ってくるはずですが、502でInternal server errorが返ってきてしまった場合が問題です。関数のログを確認してみると今回のエラーが表示されてしまっています。
サーバーレスなアプリケーション開発の初心者がよく遭遇する事象なので、今回はこのエラーの対処法を紹介します。
対処法
NPMパッケージの確認
実はかなり単純な答えなのですが、このエラーが出ている場合の原因は単なるNPMパッケージの漏れです。今回の「再現」の場合を考えてみましょう。エラー内容をよく見てみると「at Object.
こういった事象はパッケージをいろいろいじっていると出るのですが、ひとまずローカルのnode_modulesを削除して、yarn installしてパッケージを入れ直してみましょう。すると、ローカルでも漏れいてるパッケージを発見できます。
その他の可能性
ほとんどの人はすでに問題を解決したと思いますが、より初心者向けにその他の起こりうる原因を紹介します。以下です。
- ディレクトリのパスとserverless.ymlのhandlerのパスが一致しているか? -> Serverlessフレームワークでzipファイルを作成した場合「サービス名.zip」というファイルが作成されますが、それを解凍した時に「サービス名」ディレクトリ配下からパスがスタートしている必要があります。今回の「再現」のserverless.ymlのhandlerを確認してみて下さい。
- レスポンスのフォーマットは適切か? -> statusCode、headers、bodyというJSONフォーマットである必要があります。
最後に
いかがでしたか?サーバーレスなアプリケーションを作っているとよく発生する事象なので、焦らず対応しましょう。それでは。