在本地部署与调试

优质
小牛编辑
133浏览
2023-12-01

在这几周的 Serverless 应用开发里,我觉得最大的不便就是,缺少一个本地的调试环境。在这种时候,我们需要不断地部署我们的代码,不断地在我们的代码里写上几行 console.log,然后在一切正常之后,再把这些 console.log 删除。

可要是,突然间又出现了一个 bug,我仿佛看到了我们又要重来一遍。

就这样经历了几次之后,我便想尝试一些新的手段,比如 serverless-offline

serverless-offline

serverless-offline 是一个 Serverless Framework 的插件,它可以在本地的机器上模拟 AWS Lamdba 和 API Gateway,以加快开发者的开发周期。为此,它启动一个处理请求生命周期的 HTTP 服务器,就像 APIG 一样,并调用你的处理程序。

及包含以下的特性:

  • 仅支持 Node.js 下的 Lambda 函数
  • 支持 Velocity 模板
  • 延迟加载你的、需要缓存失效文件:而不需要重载工具,如Nodemon。
  • 以及,集成,授权人,代理,超时,responseParameters,HTTPS,Babel 运行时环境,CORS 等…

那么,让我们看看如何做到这一点。

本地搭建 serverless-offline 与 DynamoDB 环境

这次我们将基于之前的文章《Serverless 应用开发指南:Lambda + API Gateway + DynamoDB 制作 REST API》中的 todolist,来开始我们的调试之旅。

在之前的示例里,我们使用了 DynamoDB 来存储数据。在这篇文章里,我们也将介绍 serverless-dynamodb-local 来在本地运行 DynamoDB。

在那之前,如果你还没有之前的代码,请先安装服务到本地:

npm install -u https://github.com/phodal/serverless-guide/tree/master/aws-node-rest-api-with-dynamodb -n dynamodb-offline

然后,在我们的项目里安装 serverless-offline 插件:

yarn add --dev serverless-offline

并安装 serverless-dynamodb-local 插件:

yarn add --dev serverless-dynamodb-local

然后,在 serverless.yml 中添加相应的插件:

plugins:
  - serverless-offline
  - serverless-dynamodb-local

紧接着,还需要进行相应的 dynamodb 配置:

custom:
  dynamodb:
    start:
      port: 8000
      inMemory: true
      migrate: true
    migration:
      dir: offline/migrations

其中的 migration 对应的是本地的 Scheme,位于 offline/migrations/todos.json,内容如下:

{
    "Table": {
        "TableName": "serverless-rest-api-with-dynamodb-dev",
        "KeySchema": [
            {
                "AttributeName": "id",
                "KeyType": "HASH"
            }
        ],
        "AttributeDefinitions": [
            {
                "AttributeName": "id",
                "AttributeType": "S"
            }
        ],
        "ProvisionedThroughput": {
            "ReadCapacityUnits": 1,
            "WriteCapacityUnits": 1
        }
    }
}

然后,执行:

serverless dynamodb install

以安装 DynamnoDB 的本地版本。

一切准备妥当了,我们可以进行测试了。

本地测试 serverless-offline 与 DynamoDB

接着,让我们用下面的命令,来运行起本地的环境:

$ serverless offline start

Dynamodb Local Started, Visit: http://localhost:8000/shell
Serverless: DynamoDB - created table serverless-rest-api-with-dynamodb-dev
Serverless: Starting Offline: dev/us-east-1.

Serverless: Routes for create:
Serverless: POST /todos

Serverless: Routes for list:
Serverless: GET /todos

Serverless: Routes for get:
Serverless: GET /todos/{id}

Serverless: Routes for update:
Serverless: PUT /todos/{id}

Serverless: Routes for delete:
Serverless: DELETE /todos/{id}

Serverless: Offline listening on http://localhost:3000

启动的时候,发现直接报错了:

  message: 'Missing region in config',
  code: 'ConfigError',
  time: 2017-11-07T01:18:45.365Z }

对比了官方的示例代码后,发现没有对本地调用的 DynamoDB 进行处理:

让我们,新增一个 todos/dynamodb.js 文件:

'use strict';

const AWS = require('aws-sdk'); // eslint-disable-line import/no-extraneous-dependencies

let options = {};

// connect to local DB if running offline
if (process.env.IS_OFFLINE) {
  options = {
    region: 'localhost',
    endpoint: 'http://localhost:8000',
  };
}

const client = new AWS.DynamoDB.DocumentClient(options);

module.exports = client;

当我们在本地运行的时候,将使用本地的 DynamoDB,当在服务端运行的时候,则会调用真正的 DynamoDB。

再去修改 create.jsdelete.jsget.jslist.jsupdate.js 中的:

const dynamoDb = new AWS.DynamoDB.DocumentClient();

改为

const dynamoDb = require('./dynamodb');

确认一切无误后,我们就可以使用 postman 测试:

PostMan 测试 Serverless Offline
PostMan 测试 Serverless Offline

或者 curl:

curl -X POST -H "Content-Type:application/json" http://localhost:3000/todos --data '{ "text": "Learn Serverless" }'

接着打开本地的 todos 地址:

http://localhost:3000/todos

就会返回类似于在线上生成的数据结果。

[{"checked":false,"createdAt":1510018445663,"id":"be15f600-c35b-11e7-8089-a5ea63a20ab5","text":"Learn Serverless","updatedAt":1510018445663}]

Awesome!

既然,已经有了可以在本地运行 DynamoDB,那么我们是不是可以写上几个测试呢?