AWS SAMを使ってLambda + API Gatewayを試しました。Lambdaの言語環境はNode.jsです。
SAMのCLIツールをインストール
Installing the AWS SAM CLI on Linux - AWS Serverless Application Model
これを読むとLinuxにHomebrewを入れろとなっていますが、そこまではしたくないので、pip
で入れます。私の環境はいまはpipenv
を使うようにしていますので、コマンドは以下のようになります。
空のディレクトリにて、
$ pipenv install aws-sam-cli
$ pipenv run sam --version
SAM CLI, version 0.37.0
samコマンドでひな型を作成
sam init
というコマンドを実行すると、いくつか質問されるのでそれに答えると、ひな型となるファイル一式を生成してくれます。ディレクトリを1つ掘ってくれます。
以下は例です。Project nameは適当です。sam
はpipenv
でインストールしましたので、コマンドの前にpipenv run
を付けています。
$ pipenv run sam init --runtime nodejs12.x
Which template source would you like to use?
1 - AWS Quick Start Templates
2 - Custom Template Location
Choice: 1
Project name [sam-app]: hellonodealambda
Allow SAM CLI to download AWS-provided quick start templates from Github [Y/n]: Y
-----------------------
Generating application:
-----------------------
Name: hellonodealambda
Runtime: nodejs12.x
Dependency Manager: npm
Application Template: hello-world
Output Directory: .
Next steps can be found in the README file at ./hellonodealambda/README.md
すると、以下のようなファイル構成になります。
$ find . -type f
./hellonodealambda/events/event.json
./hellonodealambda/README.md
./hellonodealambda/packaged.yaml
./hellonodealambda/hello-world/app.js
./hellonodealambda/hello-world/package.json
./hellonodealambda/hello-world/.npmignore
./hellonodealambda/hello-world/tests/unit/test-handler.js
./hellonodealambda/.gitignore
./hellonodealambda/template.yaml
./Pipfile
./Pipfile.lock
Pipfile*
はsam
をインストールしたときのファイルで、pipenv
が必要とするだけです。Project nameのディレクトリ(hellonodealambda
)がsam init
で生成されたファイルです。これ以降はhellonodealambda
ディレクトリ内で作業します。
$ cd hellonodealambda
AWSにデプロイ
sam package
を実行してCloudFormationのテンプレートファイルを作成します。aws cloudformation package
に相当するものだと思います。これによりLambdaにデプロイするソース一式が一時的なS3にアップロードされ、アップロード先を参照するpackaged.yaml
が作成されます。
参考
AWS CloudFormationをちょっとだけ理解した - Qiita
コマンドはこんな感じ。
$ pipenv run sam package --profile AWS_CREDENTIAL_PROFILE_NAME --template-file template.yaml --output-template-file packaged.yaml --s3-bucket MYBUCKET_NAME --s3-prefix hellonodealambda
次にsam deploy
を実行して、CloudFormationにデプロイし、関連するAWSリソースを作成します。aws cloudformation deploy
に相当します。
$ pipenv run sam deploy --profile AWS_CREDENTIAL_PROFILE_NAME --region ap-northeast-1 --template-file packaged.yaml --stack-name hellonodealambda --capabilities CAPABILITY_IAM
--region
が必要なときとそうでないときがある気がするのですが、詳細はよくわかりません。~/.aws/config
にregionを指定しているつもりなのですが、sam deploy
のときにこれがないと私のアカウントでは botocore.exceptions.NoRegionError: You must specify a region.
というエラーになってしまいました。
--capabilities CAPABILITY_IAM
の意味もわかっていないです。これがないと
Error: Failed to create changeset for the stack: hellonodealambda, Parameter validation failed:
Invalid type for parameter Capabilities, value: None, type: <class 'NoneType'>, valid types: <class 'list'>, <class 'tuple'>
というエラーになってしまいました。
マネジメントコンソールのAPI GatewayでResourcesのページで、Actionsの中にあるDeploy APIというのをしますと、APIアクセスできるようになります。
$ curl 'https://XXXX.execute-api.ap-northeast-1.amazonaws.com/Stage/hello'
{"message":"hello world"}
GETパラメータを受け取る
APIとしてGETパラメータをLambdaが受け取れるようにします。
app.js
の中身を以下のようにしてみます。APIで渡したGETパラメータをログとレスポンスの両方に含めています。
console.log(event.queryStringParameters);
console.log(event.multiValueQueryStringParameters);
response = {
'statusCode': 200,
'body': JSON.stringify({
message: 'hello world',
params: event.queryStringParameters,
multiParams: event.multiValueQueryStringParameters,
})
}
実行してみます。
$ curl 'https://XXXX.execute-api.ap-northeast-1.amazonaws.com/Stage/hello?pa=A&pa=AA&pb=BB'
{"message":"hello world","params":{"pa":"AA","pb":"BB"},"multiParams":{"pa":["A","AA"],"pb":["BB"]}}
同じ名前のパラメータを複数渡すと、event.queryStringParameters
にはあとのものが優先され、event.multiValueQueryStringParameters
には配列形式で全部が含まれるようです。
以上。