Blog

Blog

PHODAL

Serverless 应用开发指南:API Gateway + S3 + AWS Lambda 打造 CRUD

在前两篇文章《Serverless 应用开发指南: serverless 的 hello, world》和 《Serverless 开发指南:AWS IoT 服务开发》 里,我们简单地介绍了如何用 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

curl -X POST https://XXXX.execute-api.region.amazonaws.com/dev/form-response --data '{ "body" : "Learn Serverless" }'

List

curl https://XXXX.execute-api.region.amazonaws.com/dev/form-response

ReadOne

curl https://XXXX.execute-api.region.amazonaws.com/dev/form-response/<id>

ReadAll

curl https://XXXX.execute-api.region.amazonaws.com/dev/form-response/readAll

Update

curl -X PUT https://XXXX.execute-api.region.amazonaws.com/dev/form-response/<id> --data '{ "body" : "Understand Serverless" }'

Delete

curl -X DELETE https://XXXX.execute-api.region.amazonaws.com/dev/form-response/<id>

如果只是测试用途,可以在执行完成后执行 serverless remove 来删除对应的服务,以减少开支。

相关项目:https://github.com/tscanlin/serverless-s3-crud

关于我

Github: @phodal     微博:@phodal     知乎:@phodal    

微信公众号(Phodal)

围观我的Github Idea墙, 也许,你会遇到心仪的项目

QQ技术交流群: 321689806

新书《全栈应用开发:精益实践》

这不是一本深入前端、后台、运维、设计、分析等各个领域的书籍。本书以实践的方式,将这一系列的领域及理论知识结合到一起,来帮助读者构建全栈Web 开发的知识体系,并辅以精益及敏捷的思想,来一步步开发Web 应用:从创建一个UI 原型到编写出静态的前端页面;从静态的前端页面到带后台的应用,并部署应用;从Web 后台开发API 到开发移动Web 应用。在这个过程中,我们还将介绍一些相辅相成的步骤:使用构建系统来加速Web 应用的开发;为应用添加数据分析工具来改进产品;使用分析工具来改善应用的性能;通过自动化部署来加快上线流程;从而帮助读者开发出一个真正可用的全栈 Web 应用。同时,我们也将帮助读者把这些步骤应用到现有的系统上,改进现有系统的开发流程。

comment

Feeds

RSS / Atom

最近文章

关于作者

Phodal Huang

Developer, Consultant, Writer, Designer

ThoughtWorks 高级咨询师

工程师 / 咨询师 / 作家 / 设计学徒

开源深度爱好者

出版有《自己动手设计物联网》、《全栈应用开发:精益实践》

联系我: h@phodal.com

微信公众号: 与我沟通

标签