LoginSignup
8
7

More than 5 years have passed since last update.

【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第2章 〜API Gateway利用編〜

Last updated at Posted at 2017-03-07

【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第2章 〜API Gateway利用編〜

あらすじ

今年も花粉が凄いですね。自分はずっと微熱出てる状況です。

会社にジョインしてから、もう2年くらい経ちました。
今回からは少し話題になっている「サーバーレスアーキテクチャ」というネタをシリーズで公開したいと思います。

※後々、リクエストに応じて更新することが多いのでストックしておくことをおすすめします。

自分は某社でCTOをしていますが、頭でっかちに理論ばっかり学習するよりは、イメージがなんとなく掴めるように学習し、実践の中で知識を深めていく方が効率的に学習出来ると考えています。

教育スタイルとしては正しい事をきっちりかっちり教えるのではなく、未経験レベルの人がなんとなく掴めるように、資料を構成していきます。

以下のようなシリーズネタで進めます。

No. 記事
1 【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第1章 〜nodejsのtemplate利用編〜
2 【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第2章 〜API Gateway利用編〜
3 [【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第3章 〜DynamoDB利用編〜]

では、今回もはじめていきましょう!

はじめに

今回は前回【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第1章 〜nodejsのtemplate利用編〜の記事と同様、serverlessのnodejsのtemplateを用いてAWS APIGatewayのエンドポイントを利用するにしてみましょう。

でははじめましょう

環境

Mac環境

10.11.6

node環境

$ nodebrew ls

v0.12.14
$ nodebrew install-binary v7.4.0
$ nodebrew ls
v0.12.14
v7.4.0

python環境

$ pyenv versions
  system
  2.7.12
$ pyenv install -v 3.5.2
$ eval "$(pyenv init -)"
$ pyenv shell 3.5.2
$ python --version
Python 3.5.2

awscli環境

$ pip install awscli
$ aws --version
aws-cli/1.11.9 Python/2.7.10 Darwin/15.6.0 botocore/1.4.66

serverless環境

$ npm install serverless -g
$ serverless --version
1.5.1

プロジェクト作成

前回【サーバーレスアーキテクチャ】をserverlessフレームワークで試す第1章 〜nodejsのtemplate利用編〜で作った「serverlesstest」というAWSプロファイルを引続き利用する形ですすめます。

いつも通り、serverlessコマンドでnodejsでapigatewayというプロジェクトを作って見ましょう。

$ serverless create --template aws-nodejs --provider aws --profile serverlesstest --path apigateway --verbose

作成されたプロジェクト

apigateway
├── handler.js
└── serverless.yml

API Gatewayを利用する

設定変更

$ cd ~/Documents/apigateway
$ ls .
handler.js
serverless.yml

LambdaのステージをtestにデフォルトのテストスクリプトをAPI Gateway経由で利用してみましょう。
変更箇所は以下の通りです。
今回からはdiffの結果を表示する形で楽しようと思います。
最初はイメージわかないと思うので、最終のファイル状況も併記しておきます。

serverless.yml
--- serverless.yml.before   2017-03-06 18:26:48.000000000 +0900
+++ serverless.yml.after    2017-03-06 19:00:41.000000000 +0900
@@ -20,6 +20,9 @@
 provider:
   name: aws
   runtime: nodejs4.3
+  profile: serverlesstest
+  stage: test
+  region: ap-northeast-1

 # you can overwrite defaults here
 #  stage: dev
@@ -56,7 +59,12 @@
 functions:
   hello:
     handler: handler.hello
-
+    events:
+      - http:
+          path: hello
+          method: get
+          cors: true
+
 #    The following are a few example events you can configure
 #    NOTE: Please make sure to change your handler code to work with those events
 #    Check the event documentation for details

変更後のファイル(変更箇所だけを抜粋)

serverless.yml
provider:
  name: aws
  runtime: nodejs4.3
  profile: serverlesstest
  stage: test
  region: ap-northeast-1

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get
          cors: true

デプロイ

修正が完了したら、デプロイをしてみましょう。

$ serverless deploy --provider aws --profile serverlesstest -v

デプロイが上手く行くと以下のようなインフォメーションが表示されるので
endpointsという箇所のURLをコピーしましょう。

API GateWayの情報を確認する。

Service Information
service: apigateway
stage: test
region: ap-northeast-1
api keys:
  None
endpoints:
  GET - https://xxxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test/hello
functions:
  apigateway-test-hello: arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxxx:function:apigateway-test-hello

Stack Outputs
HelloLambdaFunctionArn: arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxxx:function:apigateway-test-hello
HelloLambdaFunctionQualifiedArn: arn:aws:lambda:ap-northeast-1:xxxxxxxxxxxxxx:function:apigateway-test-hello:1
ServiceEndpoint: https://xxxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test
ServerlessDeploymentBucketName: apigateway-test-xxxxxxxxxxxxxx

ブラウザでアクセスしてみる

さきほどコピーしたエンドポイントのURLにブラウザでアクセスしてみましょう
以下の画像のように表示されれば成功です。

ブラウザでAPIGateWayのエンドポイントにアクセスした結果

少しフライングしてDynamoDBにもアクセスしてみる

次回にDynamoDBにアクセスするRestfulなAPIを作る予定でしたが
少しフライングして、この回でもDynamoDBにアクセスして結果を読み取るようにしてみましょう。
いつも通り解説はほどほどに。

serverless.ymlを使って

  • Lambdaで実行するユーザーにDynamoDBの周りの権限を付与(iamRoleStatementsらへん)
  • resourcesでDynamoDBの設定も同時に設定

を設定しています。

serverless.ymlを変更する

serverless.yml
--- serverless.yml.before   2017-03-06 19:00:41.000000000 +0900
+++ serverless.yml.after    2017-03-07 10:52:00.000000000 +0900
@@ -23,6 +23,17 @@
   profile: serverlesstest
   stage: test
   region: ap-northeast-1
+  iamRoleStatements:
+  - Effect: Allow
+    Action:
+      - dynamodb:DescribeTable
+      - dynamodb:Query
+      - dynamodb:Scan
+      - dynamodb:GetItem
+      - dynamodb:PutItem
+      - dynamodb:UpdateItem
+      - dynamodb:DeleteItem
+    Resource: "arn:aws:dynamodb:ap-northeast-1:*:*"

 # you can overwrite defaults here
 #  stage: dev
@@ -57,14 +68,14 @@
 #    - exclude-me-dir/**

 functions:
-  hello:
-    handler: handler.hello
+  readAll:
+    handler: handler.readAll
     events:
       - http:
-          path: hello
+          path: members
           method: get
           cors: true
-
+
 #    The following are a few example events you can configure
 #    NOTE: Please make sure to change your handler code to work with those events
 #    Check the event documentation for details
@@ -95,3 +106,21 @@
 #     NewOutput:
 #       Description: "Description for the output"
 #       Value: "Some output value"
+resources:
+  Resources:
+    MembersDynamoDbTable:
+      Type: 'AWS::DynamoDB::Table'
+      DeletionPolicy: Retain
+      Properties:
+        AttributeDefinitions:
+          -
+            AttributeName: id
+            AttributeType: S
+        KeySchema:
+          -
+            AttributeName: id
+            KeyType: HASH
+        ProvisionedThroughput:
+          ReadCapacityUnits: 1
+          WriteCapacityUnits: 1
+        TableName: 'members'

handler.jsを変更する

次の章でDynamoDBを使ったRestfulなAPIを作ってみようと考えていましたが
たいしたレベルでもないので、フライングして今回の章でもDynamoDBにアクセスして
結果を取得するようなAPIを作ってみましょう。

handler.js

--- handler.js.before   2017-03-06 14:47:50.000000000 +0900
+++ handler.js.after    2017-03-07 10:29:24.000000000 +0900
@@ -1,16 +1,17 @@
 'use strict';

-module.exports.hello = (event, context, callback) => {
-  const response = {
-    statusCode: 200,
-    body: JSON.stringify({
-      message: 'Go Serverless v1.0! Your function executed successfully!',
-      input: event,
-    }),
-  };
+const membersReadAll = require('./members-read-all.js');

-  callback(null, response);
+module.exports.readAll = (event, context, callback) => {
+  membersReadAll(event, (error, result) => {
+    const response = {
+      statusCode: 200,
+      headers: {
+        "Access-Control-Allow-Origin" : "*"
+      },
+      body: JSON.stringify(result),
+    };

-  // Use this code if you don't use the http event with the LAMBDA-PROXY integration
-  // callback(null, { message: 'Go Serverless v1.0! Your function executed successfully!', event });
+    context.succeed(response);
+  });
 };

members-read-all.jsを作成する

nodejs用のaws-sdkのライブラリを使ってアクセスするスクリプトを作ってみましょう
単純にDynamoDBのmembersというテーブルに対してscanをした結果を取得するだけの
スクリプトです。

members-read-all.js
'use strict';

const AWS = require('aws-sdk');
const dynamoDb = new AWS.DynamoDB.DocumentClient();

module.exports = (event, callback) => {
  const params = {
    TableName: 'members',
  };

  return dynamoDb.scan(params, (error, data) => {
    if (error) {
      callback(error);
    }
    callback(error, data.Items);
  });
};

ライブラリをインストールする

nodejsで使うライブラリをインストールしましょう。
今回はpackage.jsonなども使わずインストールしてます。

$ npm install aws-sdk --save

これでプロジェクトフォルダの配下にnode_modulesが作成されて対象のライブラリが保存されました。

デプロイ

長かったですね。実際にデプロイしてみましょう。

$ serverless deploy --provider aws --profile serverlesstest -v

デプロイ結果から、エンドポイントをコピーしブラウザからもアクセスしてみましょう。
https://xxxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test/members

「[]」という結果が表示されましたか?

AWSコンソールからDynamoDBを確認する

DynamoDB

DynamoDBにデータをいれる

データが空な事を確認するというのもつまらないので
AWSコンソール画面から手動でデータを登録してみましょう。

DynamoDBのテーブルに項目を作成

DynamoDBのテーブルに項目を作成する

DynamoDBのテーブルにデータを登録

今回はidとnameで登録してみましょう。
DynamoDBのテーブルにデータを登録する

API Gateway経由でDynamoDBの結果を確認する

再度ブラウザで
https://xxxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test/members
にアクセスして、さきほど登録したDynamoDBの値が取得出来るか確認してみましょう。

API Gatewayの結果

編集後記

少しフライングしてDynamoDBまで連携させてみました。APIの結果を表示するところまでしかネタに含めなかったのでイマイチ実感がわかないと思いますが、余力のある人はAPIを利用する側も作ってみてください。

次回は、もう少しCRUDをRestfulな感じで対応出来るAPIを作ってみようと思います。
お楽しみに。

8
7
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
8
7