51
50

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 5 years have passed since last update.

Expressで作ったAPIをaws-serverless-expressでサーバレス化した話

Last updated at Posted at 2018-02-25

はじめに

最近Expressで作ったAPIを、aws-serverless-expressを使ってサーバレス化したときの手順をまとめる。

今回はExpressをサーバレス化する話なので、Expressを使ったAPIの構築については触れない。

前提

  • Expressで既にAPIを作っている
  • AWSアカウントを持っている
  • aws-cliが設定済みである

aws-serverless-expressとは

awslabが出してる、Expressで作ったRESTful APIをサーバレス化するツール。
サーバレスAPIは、Express + Lambda + API Gatewayを用いて構築する。

このツールの凄いところは、アプリケーションでいじるところが殆ど無いところだ。
なので、既にExpressでAPIサーバを構築している人なら、少しの手順を踏むだけで、サーバレスなAPIを簡単に構築することができる。

細かいことはGithubのREADMEに書いてある。
天下のAWSさんが出しているだけあって、exampleもちゃんとしてる。
1からAPIを作る人はexampleをコピーするところから始めると良いと思う。

Githubのリンクはこちら

サーバレス化

1. aws-serverless-expressのインストール

以下を実行して、aws-serverless-expressをインストール。

$ npm install --save aws-serverless-express

2. exampleのpackage.jsonのscriptsをコピー

aws-serverless-expressのexampleには、既に便利なscriptが用意されているため、今回はそれを利用する。

自分のプロジェクトのpackage.jsonに以下をコピペする。
(Windows以外の人はwin-config以下はコピペする必要なし)。

  "scripts": {
    "start": "node app.local.js",
    "config": "node ./scripts/configure.js",
    "deconfig": "node ./scripts/deconfigure.js",
    "local": "node scripts/local",
    "invoke-lambda": "aws lambda invoke --function-name $npm_package_config_functionName --region $npm_package_config_region --payload file://api-gateway-event.json lambda-invoke-response.json && cat lambda-invoke-response.json",
    "create-bucket": "aws s3 mb s3://$npm_package_config_s3BucketName --region $npm_package_config_region",
    "delete-bucket": "aws s3 rb s3://$npm_package_config_s3BucketName --region $npm_package_config_region",
    "package": "aws cloudformation package --template ./cloudformation.yaml --s3-bucket $npm_package_config_s3BucketName --output-template packaged-sam.yaml --region $npm_package_config_region",
    "deploy": "aws cloudformation deploy --template-file packaged-sam.yaml --stack-name $npm_package_config_cloudFormationStackName --capabilities CAPABILITY_IAM --region $npm_package_config_region",
    "package-deploy": "npm run package && npm run deploy",
    "delete-stack": "aws cloudformation delete-stack --stack-name $npm_package_config_cloudFormationStackName --region $npm_package_config_region",
    "setup": "npm install && (aws s3api get-bucket-location --bucket $npm_package_config_s3BucketName --region $npm_package_config_region || npm run create-bucket) && npm run package-deploy",
    "win-config": "npm run config",
    "win-deconfig": "npm run deconfig",
    "win-local": "npm run local",
    "win-invoke-lambda": "aws lambda invoke --function-name %npm_package_config_functionName% --region %npm_package_config_region% --payload file://api-gateway-event.json lambda-invoke-response.json && cat lambda-invoke-response.json",
    "win-create-bucket": "aws s3 mb s3://%npm_package_config_s3BucketName% --region %npm_package_config_region%",
    "win-delete-bucket": "aws s3 rb s3://%npm_package_config_s3BucketName% --region %npm_package_config_region%",
    "win-package": "aws cloudformation package --template ./cloudformation.yaml --s3-bucket %npm_package_config_s3BucketName% --output-template packaged-sam.yaml --region %npm_package_config_region%",
    "win-deploy": "aws cloudformation deploy --template-file packaged-sam.yaml --stack-name %npm_package_config_cloudFormationStackName% --capabilities CAPABILITY_IAM --region %npm_package_config_region%",
    "win-package-deploy": "npm run win-package && npm run win-deploy",
    "win-delete-stack": "aws cloudformation delete-stack --stack-name %npm_package_config_cloudFormationStackName% --region %npm_package_config_region%",
    "win-setup": "npm install && (aws s3api get-bucket-location --bucket %npm_package_config_s3BucketName% --region %npm_package_config_region% || npm run win-create-bucket) && npm run win-package-deploy"
  }

次に、exampleで使用しているscriptファイルや、yamlファイルをコピーする必要がある。
プロジェクトルートで以下を実行。

$ git clone https://github.com/awslabs/aws-serverless-express.git ase
$ cp -r ase/example/scripts .
$ cp ase/example/api-gateway-event.json .
$ cp ase/example/cloudformation.yaml .
$ cp ase/example/lambda.js .
$ cp ase/example/simple-proxy-api.yaml .
$ rm -rf ase

3. awsアカウントとs3バケットの設定

先程コピーしたスクリプトを使用して、awsアカウントとs3バケットの設定を行う。

$ npm run config -- \
--account-id="<accountId>" \
--bucket-name="<bucketName>" \
--region="<region>" \            # optinal
--function-name="<functionName>" # optinal

このコマンドの実行が成功すると、以下の3つのファイルが書き換わる。

  • package.json
  • simple-proxy-api.yaml
  • cloudformation.yaml

4. app.jsの修正

Expressをaws-serverless-expressで動かすには少しコードに手を加えなくてはならない。

まず、app.jsでaws-serverless-expressのMiddlewareを有効化する必要がある。
以下をapp.jsに追加

const express = require('express')
+ const awsServerlessExpressMiddleware = require('aws-serverless-express/middleware')

const app = express()

+ app.use(awsServerlessExpressMiddleware.eventContext())

次に、aws-serverless-expressではUNIXドメインソケットで別の箇所でlistenしているらしいので、app.jsに書いてるlistenメソッドは削除する必要がある。

- app.listen()

最後に、lambda.jsでapp.jsを読み込む必要があるため、app.jsをmodule化する必要がある。

以下の一文をapp.jsの末尾に追加

+ module.exports = app

5. lambda.jsの修正

exampleからコピーした、lambda.jsを修正する。
先程修正したapp.jsのパスを指定して、importするだけで良い。

const awsServerlessExpress = require('aws-serverless-express')
- const app = require('./app')
+ const app = require('./path/to/app')

6. デプロイ

exampleで用意されているsetupスクリプトを実行するだけで良い。

$ npm run setup

setupスクリプトを実行すると以下が順番に実行される。

  1. npm install
  2. デプロイ先のs3バケットの作成
  3. CloudFormationのテンプレートの作成
  4. CloudFormationのデプロイ

3. で生成されるCloudFormationのテンプレートはpackaged-sam.yamlというファイルに出力される。
packaged-sam.yamlの内容は以下の通り

  1. API Gatewayの構築
  2. Lambda Functionの作成
  3. Lambdaの実行権限のあるIAMロールの作成

setupスクリプトの実行が成功していれば、CloudFormationのStackが実行されているはずなので、AWSコンソールにログインして、CloudFormationが実行されているか確認する。

7. 確認

AWSコンソールにサインインし、API Gatewayサービスを選択。
新しくAPIが作成されていることを確認する。

新しく作成されたAPIを選択し、「ステージ > prod > URLの呼び出し」に書かれているURLをBase URLとしてAPIを叩いてみる。

Expressで予め作成したAPIを実行して、動くことを確認する。
以下は例。

$ curl http://hogehoge.execute-api.ap-northeast-1.amazonaws.com/prod/v1/fuga

まとめ

Expressを使って既に動いているAPIを、たった7つのステップで、簡単にサーバレス化できてしまった。

これからサーバレス、マイクロサービスがトレンドになる中、簡単に既存のAPIをサーバレス化できてしまう仕組みは本当に凄いと思った。流石AWSさん。

API Gatewayの作成まではできたので、後は独自ドメインにしたりhttpsを有効化したり、色々カスタマイズすると良いと思う。
自分はめんどくさがって手動でポチポチ設定してしまったが、本当はこの辺もCloudFormationでできるはずなので、暇になったら設定してみる。

51
50
1

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
51
50

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?