Blog | Phodal - A Growth Engineerhttp://www.phodal.com/blog/2017-10-29T13:22:11.907962+00:00BlogServerless 应用开发指南:使用 S3 部署静态网站 2017-10-29T13:21:32+00:002017-10-29T13:22:11.907962+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/serverless-development-guide-use-serverless-finch-deploy-s3-static-html/
在尝试了使用 Router53 路由到 S3 后,并想试试能否使用 serverless 框架来上传静态内容。在探索官方的 DEMO 后,找到了一个 ``serverless-finch`` 插件可以做相应的事情。
```
serverless create --template aws-nodejs s3-static-file s3-static-file
```
配置 serverless-finch
---
官网的 ``serverless-client-s3`` 已经停止维护了,并推荐使用 ``serverless-finch``。
``serverless-finch`` 的安装方式是:
```
npm install --save serverless-finch
```
默认的官网生成的项目,并没有 ``package.json`` 文件,需要手动执行 ``npm inti``,再安装插件。
因此修改完后的 ``package.json`` 文件如下所示:
```
{
"name": "s3-static-file",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Phodal Huang",
"license": "MIT",
"dependencies": {
"serverless-finch": "^1.1.1"
}
}
```
在这个时候,我们需要按 serverless 框架的插件要求,添加如下的内容:
```
plugins:
- serverless-finch
```
并配置好我们的 S3 存储桶的名字,最后 ``serverless.yml`` 文件的内容如下所示:
```
service: s3-static-file
plugins:
- serverless-finch
provider:
name: aws
runtime: nodejs6.10
custom:
client:
bucketName: wdsm.io
```
我们配置的 S3 存储桶的名字是: **wdsm.io**,然后其使用 ``client/dist`` 文件来放置静态文件。
静态内容
---
如我们的 ``index.html`` 文件的路径是: ``client/dist/index.html``,对应的内容是:
```
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>WDSM.io</title>
</head>
<body>
<h1>WDSM</h1>
</body>
</html>
```
最后,执行 ``serverless client deploy`` 就可以部署我们的网站。
``再次提醒``,这次我们用的是 ``serverless client deploy``。
相应的过程日志如下所示:
```
Serverless: Deploying client to stage "dev" in region "us-east-1"...
Serverless: Bucket wdsm.io exists
Serverless: Listing objects in bucket wdsm.io...
Serverless: Deleting all objects from bucket wdsm.io...
Serverless: Configuring website bucket wdsm.io...
Serverless: Configuring policy for bucket wdsm.io...
Serverless: Configuring CORS policy for bucket wdsm.io...
Serverless: Uploading file error.html to bucket wdsm.io...
Serverless: If successful this should be deployed at: https://s3.amazonaws.com/wdsm.io/error.html
Serverless: Uploading file index.html to bucket wdsm.io...
Serverless: If successful this should be deployed at: https://s3.amazonaws.com/wdsm.io/index.html
```
由于配置了 Router53 指向了 S3,因此可以直接访问:[http://wdsm.io/](http://wdsm.io/) 来看最后的内容。
并且,对应的删除命令也变成了:``serverless client remove``。
Serverless 应用开发指南:API Gateway + S3 + AWS Lambda 打造 CRUD2017-10-29T10:42:59+00:002017-10-29T10:45:56.042562+00:00Phodal Huanghttp://www.phodal.com/blog/author/root/http://www.phodal.com/blog/serverless-development-guide-use-s3-api-gateway-create-crud/在前两篇文章《Serverless 应用开发指南: serverless 的 hello, world》和 《[Serverless 开发指南:AWS IoT 服务开发](https://www.phodal.com/blog/serverless-guide-development-aws-iot-serverless-example/)》 里,我们简单地介绍了如何用 Serverless 和 AWS IoT 开发入门级的 Serverless 应用。
在这一篇文章里,我们将开始进入正式的应用开发领域里:一个 CRUD 示例。
原先,我考虑直接先使用 DynamoDB 进行实验,但是考虑到我之前误用 DynamoDB 被扣 500 刀,再追回来的经历。我决定先用 S3 练练手——主要是已经有一个成型的 DEMO。
概念:API Gateway 与 S3
---
以下是来自官网对于 API Gateway 和 S3 的介绍:
> Amazon API Gateway 是一种完全托管的服务,可以帮助开发者轻松创建、发布、维护、监控和保护任意规模的 API。只需在 AWS 管理控制台中点击几下,您便可以创建可充当应用程序“前门”的 API,从后端服务访问数据、业务逻辑或功能,例如基于 Amazon Elastic Compute Cloud (Amazon EC2) 运行的工作负载、基于 AWS Lambda 运行的代码或任意 Web 应用。Amazon API Gateway 负责管理所有任务,涉及接受和处理成千上万个并发 API 调用,包括流量管理、授权和访问控制、监控以及 API 版本管理。Amazon API Gateway 没有最低费用或启动成本,您只需为收到的 API 调用和传输出去的数据量付费。
> Amazon S3 将数据作为对象存储在被称为“存储桶”的资源中。您可以在一个存储桶中尽可能多地存储对象,并写入、读取和删除您的存储桶中的对象。对象大小最多可为 5 TB。
简单地来说,API Gateway 就是那个 API gateway,即所有 API 请求的入口。而 S3 就存储内容的部分——可以视作为云盘。
基于 S3 的 Serverless CRUD
---
为了使用 S3,我们需要引入 aws-sdk 库来帮助我们更好的编写 AWS 应用。接着,让我们引入这个服务:
```
serverless install --url https://github.com/tscanlin/serverless-s3-crud
```
然后,到目录中,安装依赖:
```
cd serverless-s3-crud
npm install
```
再执行部署:
```
serverless deploy
```
执行的时候,发现了:
```
Serverless Error ---------------------------------------
An error occurred: MyBucket - form-response already exists.
Get Support --------------------------------------------
Docs: docs.serverless.com
Bugs: github.com/serverless/serverless/issues
Forums: forum.serverless.com
Chat: gitter.im/serverless/serverless
Your Environment Information -----------------------------
OS: darwin
Node Version: 6.11.0
Serverless Version: 1.23.0
```
啊哈,这个 MyBucket 已经存在了,这意味着,我们需要改一个新的名字。打开 ``serverless.yml`` 文件,将其中的 16、22、72 行中的 from-response 改成你想要的名字,如 ``phodal-serverless``。
以及** handlers 目录下的各个文件的 Bucket 名**。
serverless.yml 代码中的 ``iamRoleStatements`` 用于设置 serverless 的权限,Action 代码其所能进行的操作,Resource 则是相应的资源:
```
iamRoleStatements:
- Effect: Allow
Action:
- s3:ListBucket
Resource: "arn:aws:s3:::phodal-serverless"
- Effect: Allow
Action:
- s3:PutObject
- s3:GetObject
- s3:DeleteObject
Resource: "arn:aws:s3:::phodal-serverless/*"
```
下面的代码则定义了,我们的资源,所使用的存储桶(BucketName)的名字:
```
resources:
Resources:
MyBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: phodal-serverless
AccessControl: PublicReadWrite
WebsiteConfiguration:
IndexDocument: index.html
ErrorDocument: error.html
```
然后再执行 ``serverless deploy``,就会返回我们想要的结果及 API 地址:
```
api keys:
None
endpoints:
POST - https://xc1iprfbsg.execute-api.us-east-1.amazonaws.com/dev/form-response/{id}
GET - https://xc1iprfbsg.execute-api.us-east-1.amazonaws.com/dev/form-response
GET - https://xc1iprfbsg.execute-api.us-east-1.amazonaws.com/dev/form-response/readAll
GET - https://xc1iprfbsg.execute-api.us-east-1.amazonaws.com/dev/form-response/{id}
PUT - https://xc1iprfbsg.execute-api.us-east-1.amazonaws.com/dev/form-response/{id}
DELETE - https://xc1iprfbsg.execute-api.us-east-1.amazonaws.com/dev/form-response/{id}
functions:
create: serverless-crud-s3-dev-create
list: serverless-crud-s3-dev-list
readAll: serverless-crud-s3-dev-readAll
readOne: serverless-crud-s3-dev-readOne
update: serverless-crud-s3-dev-update
delete: serverless-crud-s3-dev-delete
```
上面列出了所有端口的 API 地址,
上传原理
---
那么,它是怎么进行操作的呢,先看看 ``serverless.yml`` 文件中定义的 create 动作。
```
functions:
create:
handler: handler.create
events:
- http:
path: form-response/{id}
method: post
cors: true
```
对应了 ``handler.js`` 文件中的 create 方法:
```
const Create = require('./handlers/create.js')
...
function makeResponse(error, result) {
const statusCode = error && error.statusCode || 200
return {
statusCode,
headers: {
"Access-Control-Allow-Origin" : "*"
},
body: JSON.stringify(result),
}
}
exports.create = (event, context, callback) => {
Create(event, (error, result) => {
const response = makeResponse(error, result)
context.succeed(response)
})
}
```
对应的 create 操作,即是:
```
'use strict'
const AWS = require('aws-sdk')
const S3 = new AWS.S3(require('../s3config.js')())
module.exports = (event, callback) => {
S3.upload({
Bucket: 'phodal-serverless',
Key: event.pathParameters.id,
Body: event.body,
// ACL: 'public-read-write' // TODO: Make this an option.
}, (err, res) => {
console.log(err, res)
callback(err, res)
})
}
```
我们就是在这里上传数据到 S3 的。
Serverless S3 CRUD 示例
---
一个简单的方式是使用 curl:
```
curl -X POST https://xc1iprfbsg.execute-api.us-east-1.amazonaws.com/dev/form-response/1 --data '{ "body" : "Learn Serverless" }'
```
```
{
"ETag": "\"695827e7012d367b7e7a28a3fdf7ce06\"",
"Location": "http://s3.amazonaws.com/phodal-serverless/1",
"key": "1",
"Key": "1",
"Bucket": "phodal-serverless"
}
```
然后同样的可以通过 curl 来获取:
```
curl https://xc1iprfbsg.execute-api.us-east-1.amazonaws.com/dev/form-response
```
就是这么简单。
接口一览
---
### Create
```bash
curl -X POST https://XXXX.execute-api.region.amazonaws.com/dev/form-response --data '{ "body" : "Learn Serverless" }'
```
### List
```bash
curl https://XXXX.execute-api.region.amazonaws.com/dev/form-response
```
### ReadOne
```bash
curl https://XXXX.execute-api.region.amazonaws.com/dev/form-response/<id>
```
### ReadAll
```bash
curl https://XXXX.execute-api.region.amazonaws.com/dev/form-response/readAll
```
### Update
```bash
curl -X PUT https://XXXX.execute-api.region.amazonaws.com/dev/form-response/<id> --data '{ "body" : "Understand Serverless" }'
```
### Delete
```bash
curl -X DELETE https://XXXX.execute-api.region.amazonaws.com/dev/form-response/<id>
```
如果只是测试用途,可以在执行完成后执行 serverless remove 来删除对应的服务,以减少开支。
相关项目:https://github.com/tscanlin/serverless-s3-crud
</id></id></id>