在第二章中,我们将尝试使用Serverless框架来实践【无服务器架构】,重点是API Gateway的使用
尝试在serverless框架中试用【无服务器架构】第二章 〜使用API Gateway编写API篇〜
あらすじ – 情节简介
今年的花粉真是厉害。我一直处于微热的状态。
自从加入公司后,已经过去了大约两年时间。
从这次开始,我想要以系列形式公开一下正在热议中的“无服务器架构”这个话题。
推荐您将此保存起来,因为以后通常会根据请求进行更新。
我在某公司担任CTO,但我认为与其只学习理论性的知识,不如学习能够模糊地把握概念,并通过实践来加深知识,这样学习起来更加高效。
作为一种教育风格,我们并不是僵化地教授正确的知识,而是以使没有经验的人能够大致理解为目标,来构建教材。
我将使用以下系列作品的主题来继续。
那么,让我们再次开始吧!
首先
让我们尝试使用serverless框架中的nodejs模板,并使用AWS APIGateway的endpoint,就像之前在第1章中试用【无服务器架构】时的文章一样。
那么,我们开始吧
环境
Mac环境
10.11.6
节点环境
$ 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
无服务器环境
$ npm install serverless -g
$ serverless --version
1.5.1
创建项目
我会继续使用在之前【服务器无架构】通过serverless框架尝试的第一章《使用nodejs的模板》创建的名为”serverlesstest”的AWS配置文件。
让我们像往常一样使用serverless命令在nodejs中创建一个名为apigateway的项目。
$ serverless create --template aws-nodejs --provider aws --profile serverlesstest --path apigateway --verbose
创建的项目
apigateway
├── handler.js
└── serverless.yml
使用API网关
更改设置
$ cd ~/Documents/apigateway
$ ls .
handler.js
serverless.yml
让我们尝试使用API Gateway通过将Lambda的阶段设置为测试,并使用默认的测试脚本。更改的部分如下:
这次我们将以显示diff结果的形式进行更好的体验。
由于一开始可能无法理解,请同时附上最后的文件状态。
--- 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
修改后的文件(只摘录更改部分)
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 部分的网址。
确认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。如果显示如下图所示,表示成功。

稍稍倒数一下,我尝试访问DynamoDB。
计划下一次创建一个访问DynamoDB的Restful API,
但我有点急于行动,所以这次也访问DynamoDB并读取结果吧。
解释的程度减少一些,就像平时一样。
使用serverless.yml
-
- Lambdaで実行するユーザーにDynamoDBの周りの権限を付与(iamRoleStatementsらへん)
- resourcesでDynamoDBの設定も同時に設定
设定中。
修改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.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
让我们使用Node.js的AWS SDK库来创建一个脚本,通过简单地使用DynamoDB的scan操作获取名为”members”的表的结果。
'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);
});
};
安装库
让我们安装在Node.js中使用的库。 这次我们不使用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。
为了避免确认数据为空的无聊行为,让我们从AWS控制台手动注册数据吧。
在DynamoDB表中创建项目

将数据存入DynamoDB表中

通过API网关查看DynamoDB的结果
让我们再次在浏览器中访问 https://xxxxxxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/test/members ,检查是否能够获取到之前注册到DynamoDB中的值。

编辑后记
我稍稍提前完成了与DynamoDB的协作。由于只包含了显示API结果的部分作为段子,所以可能无法真正感受到其效果,但如果有余力的人可以尝试创建API使用方。
下一次,我计划尝试创建一个更加符合Restful风格的能够处理CRUD的API。请拭目以待。