LoginSignup
6
3

More than 5 years have passed since last update.

Serverless framework と Lambda + API Gateway でサーバーレスな動的サイトをつくる

Posted at

Serverless Framework と Lambda + API Gateway でサーバーレスな動的サイトを構築する方法を紹介します。

いろいろと試行錯誤が必要でしたが、できあがってみれば意外と簡単でした。

あと、この方法ではローカルでも動作確認ができるのでサクサクと開発できると思います。

セットアップ

なにはともあれ npm init

その後、以下のモジュールをインストールしてください。

$ npm install serverless serverless-offline --save-dev

serverless-offline というモジュールは Serverless Framework のプラグインで、これを使用するとローカルでアプリを実行することができます。

あと、package.jsonscripts に、以下のような感じの項目も追加。

  "scripts": {
    "start": "sls offline start",
    "deploy": "sls deploy --stage dev",
    "deploy:prod": "sls deploy --stage prod",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

テストはお好みでどうぞ。

Serverless Framework の設定

必要最小限な構成は以下の通り。意外と簡単!

service: serverless-cms
frameworkVersion: ">=1.29.2 <2.0.0"

plugins:
- serverless-offline

provider:
  name: aws
  runtime: nodejs8.10
  memorySize: 512
  region: ap-northeast-1

functions:
  api:
    handler: handler.app
    events:
      - http:
          path: /
          method: get
      - http:
          path: /{any+}
          method: get

この例では、Lambda Proxy を使っていて、すべての URL に対するリクエストを handler.app でキャッチしています。

あとは、handler.app でレスポンスヘッダーやコンテンツをゴニョゴニョする感じです。

ラムダ関数の例

以下のソースを handler.js というファイル名で保存してください。

'use strict';

module.exports.app = (event, context, callback) => {
  callback(null, { 
    statusCode: 200, 
    body: `<html><head><title>Hello World</title></head><body>
            <h1>Hello World!</h1>
            <pre>${JSON.stringify(event, null, 2)}</pre>
            </body></html>`, 
    headers: { 
        "Content-Type": "text/html" 
      } 
    }
  );
}

callback() の第二引数に渡している連想配列で、ブラウザで表示するためのコンテンツを定義しています。

スタータスコードとHTMLコンテンツ、あとレスポンスヘッダーを指定できるので、必要なことはなんでもできそうですね。

この例では、どんな URL にアクセスがあっても 200 を返していますが、実用的なウェブアプリにするには、event.path で判別してレスポンスヘッダーを適切にコントロールする必要があります。

ローカル環境での動作確認

上で、package.jsonnpm start 用のコマンドを追加していればそれを叩くだけです。

$ npm start

ローカルでの開発環境が手軽に立ち上がるのはかなりうれしいですね。

AWS へのデプロイ

以下のような感じで、AWS のクレデンシャルを環境変数として設定。

$ export AWS_ACCESS_KEY_ID=xxxx
$ export AWS_SECRET_ACCESS_KEY=xxxx

僕はプロジェクトディレクトリごとに direnv で設定する方法がお気に入りです。

以上が終わったらデプロイ用のコマンドを実行しましょう。

$ npm run deploy

コマンド出力の最後に以下のような出力があるので、その URL にアクセスすればオッケーです。

Service Information
service: serverless-cms
stage: dev
region: ap-northeast-1
stack: serverless-cms-dev
api keys:
  None
endpoints:
  GET - https://xxxx.execute-api.ap-northeast-1.amazonaws.com/dev/
  GET - https://xxxx.execute-api.ap-northeast-1.amazonaws.com/dev/{any+}
functions:
  api: serverless-cms-dev-api
layers:
  None

上で紹介した package.json の記述例ではステージングと本番を切り替えてデプロイすることも想定しています。

本番にデプロイするには、以下のような感じです。

$ npm run deploy:prod

サンプル

今回紹介したサンプルのリポジトリは以下です。

6
3
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
6
3