AWS × SERVERLESSフレームワークv1.0でWebAPIを爆速で作る。

こんにちは、エムティーアイヘルスケア部門の1年目エンジニアの最上(もがみ)です。今回は業務でも利用しているSERVERLESSフレームワークのv1.0を使ってみたという記事になります。

はじめに

ついに、SERVERLESSフレームワークが正式リリースされました!👏 少し反応が遅れてしまい、すでにv1.0.3(2016/10/24現在)になっていましたが、触ってみたのでまとめました。

この記事のゴール

AWSと組み合わせてAPIをデプロイするところまで使ってみます。

AWSでは、API GatewayとLambdaを組み合わせてWebAPIを作成できます。それをSERVERLESSフレームワークを通してコマンド一つで簡単にデプロイできるようになります。このフレームワークを活用することで、デプロイ周りの面倒なことから開放され、APIの処理の内容に集中できるのではないでしょうか。とにかく便利です。

今回新たにinstallコマンドができ、すでにテンプレートがいくつか公開されています。この調査も是非したい。

実施環境

  • serverless v1.0.3
  • node v6.7.0(v4以上が必要)
  • npm v3.10.4
  • OSX

環境構築

必要なもの

node、npm、aws-cli、awsアカウントが必要です。これらの導入方法は一番下のセクションに書いておきました。前の3つは下記コマンドをターミナルで叩いて反応すれば大丈夫。

  • node -v
  • npm -v
  • aws --version

SERVERLESSインストール

sudo npm install -g serverless

このコマンドを叩くとSERVERLESSがグローバルインストールされます。serverless --vでバージョンが表示されれば、無事インストールされています。

SERVERLESSフレームワークの活用

と、その前に、様々なことをserverlessコマンドを経由します。ですが、非常に長ったらしいので、下記エイリアスのどちらかを活用してください。slsを使うのが無難ですかね。

  • sls
  • slss

雛形の作成

ターミナルで下記を行ってください。

$ mkdir slstest
$ cd slstest
$ sls create --template aws-nodejs --name testapi

--templateオプションで、雛形の種類を指定(必須)することで、サービスの雛形を作成できます。SERVERLESSでは1つのAPI Gatewayあたり1つのサービスが対応しているようです。 --nameオプションでは、サービスの名前を指定できますが、ここでは必須ではありません。serverless.ymlから変更することが可能です。ちなみに、サービスの名前はAWSコンソールでのAPI Gatewayの名前になります(プレフィックスとしてステージ名がつきますが)。

$ sls create --template [aws-nodejs | aws-python | aws-java-maven | aws-java-gradle | aws-scala-sbt]

Node.jsやpythonやJavaが選べるみたいです。Lambdaが対応している言語ですね。rc版とは異なり、scalaが追加されています。今回はNode.jsを使います。Azureの場合はどうするんでしょうかね、公式ドキュメントに全く記載がなくてわかりませんでした。

雛形として生成されるファイルは下記の通りです。

slstest
|-- .npmignore
|-- event.json
|-- handler.js
`-- serverless.yml
  • event.json
    • invoke(ローカルでAPIを叩く)時に利用します。APIに渡すJSONパラメータですね。
  • handler.js
    • これはAWSのLambdaにあたり、ここにAPIの処理を書きます。パラメータなどの情報がeventオブジェクトに詰めて渡されます。それをうまくパースして、処理を行い、cb関数の第2引数にレスポンスのJSONを渡してあげます。第1引数にレスポンスを詰めて渡すと、異常系の終了(400〜)として扱われます。詳しくはこちら
    • どうでもいいですが、RC以前のものと、自動で生成される処理の内容が変わっていますね。statusCodeの記述等が増えています。これは、LAMBDA-PROXY INTEGRATIONに対応するためのようです。
  • serverless.yml
    • API Gatewayの設定を書きます。APIの名前や、どのようなFunctionを作るか、ステージングなどの設定を書きます。
    • 個人的にはYAMLなのが辛い。そのうちJSONにも対応するって昔どこかに書いてあったような気がしたのですが…。

APIの設定(Gatewayの設定)

serverless.ymlを編集します。せっかくなのでREST APIっぽくします。YAMLはインデントが命なので、気をつけてください。

# 不要なコメントは消しています
service: testapi # API Gatewayの名前

provider:
  name: aws
  runtime: nodejs4.3
  stage: dev # ステージング名
  region: us-east-1

functions:
  # AWSコンソールでのLambdaの名前、わかりやすいのをつけるとよい
   user:
     # handler.jsのuserモジュールが呼ばれる
     # handler.jsをfunctionsディレクトリに入れたりする場合はfunctions/handler.userとする
     handler: handler.user
     events:
       # endpointの作成
       - http:
           # pathには例えば、v1/api/userとかもできる
           path: user
           method: get
           cors: true
       - http:
           path: user
           method: post
           cors: true

# ちなみにこんな風にも書けます
#functions:
#  getuser:
#    handler: handler.user
#    events:
#      - http:
#          path: user
#          method: get
#          cors: true
#  # このように書くとLambdaが2つできる
#  postuser:
#    handler: handler.user
#    events:
#      - http:
#          path: user
#          method: post
#          cors: true

APIの処理内容を書く

handler.jsを修正します。

'use strict';

// helloになっているところをuserに変更
module.exports.user = (event, context, cb) => 

// GETかPOSTが取得できる
var method = event.httpMethod

cb(null,
  { message: 'Go Serverless v1.0! Your function executed successfully!', event }
);

モジュールの中にAPIにさせたい処理を書いて、cbにレスポンスを返してあげればAPIの完成です。methodの内容で処理を分けるとよさそうです。

デプロイ

めちゃくちゃ簡単です。

$ sls deploy
Serverless: Uploading service .zip file to S3...
Serverless: Updating Stack...
Serverless: Checking Stack update progress... 
.......................................
Serverless: Stack update finished...

Service Information
service: testapi
stage: dev
region: us-east-1
endpoints:
  GET - https://hogehoge.execute-api.us-east-1.amazonaws.com/dev/user
  POST - https://hogehoge.execute-api.us-east-1.amazonaws.com/dev/user
functions:
  apitest-dev-user: arn:aws:lambda:us-east-1:0000000000000:function:apitest-dev-user

これでデプロイができました。AWSコンソールのAPI Gatewayを見てみると、デプロイされていることが確認できると思います。

疎通確認

GETは、ブラウザからendpointにアクセスしてみてください。cbの第2引数のオブジェクトが表示されているはずです。試しに、URLに?id=10をつけてみてください。v0系までは、GETの場合リクエストテンプレートなどを設定しなければ、eventにパラメータが渡せなかったのですが、v1からは何もしなくても、eventオブジェクトの終わりの方のqueryに格納されていることが確認できるかと思います。これは、SERVERLESSフレームワークがデプロイ時にAPI Gatewayの統合リクエストの本文マッピングテンプレートにマッピングコードを記載してくれているためです。初心者に非常に優しいですね。

まとめ

「非常に簡単にWebAPIが作れるSERVERLESSフレームワークのv1の触ってみた」でした。RC版とほとんど違いがありませんでしたね。

今後は、sls installの調査をしてみたいと思います。

おわり。

以下はセットアップ方法です。

セットアップ

必要なのは以下。 - AWSアカウント - node - aws-cli - serverless v1.0

以下は、インストール方法です。AWSのアカウントは、適当なユーザ作って、Administratorポリシーをアタッチしておいてください。Administratorじゃなくていいじゃんと思いますが、2016/10/25現在ではAdministratorじゃないと動かないみたいです(こちら)。今後、必要最低限なポリシーを列挙してくれることを期待。

Macの方

nodeインストール

下記手順に従ってインストール http://www.websuppli.com/nodejs/424/

aws-cliインストール

※Python 2.6.5以降必要。入ってなければインストール 1. curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py" 2. sudo python get-pip.py 3. sudo pip install awscli

Windowsの方

動作試してません。

nodeインストール

nodistを入れます。 1. https://github.com/marcelklehr/nodist/releases/tag/v0.7.2からダウンロード、インストール。 2. パス通す(設定されてたらスキップ) 3. 環境変数のPathにbinまでのパス 4. 環境変数のNODIST_PREFIXを新規追加しでnodistまでのパス 5. コマンドラインでnodist update実行

aws-cliインストール

https://aws.amazon.com/jp/cli/ こっからインストーラ落としてインストール。