使用 Express 和 MongoDB 的无服务器 API 速成课程 使用 Express 和 Mongodb 的无服务器 API 速成课程 使用 Express 和 Mongodb 的无服务器 API 速成课程

2025-05-24

使用 Express 和 MongoDB 的无服务器 API 速成课程

使用 Express 和 Mongodb 的无服务器 API 速成课程

使用 Express 和 Mongodb 的无服务器 API 速成课程

无服务器已经成为各种用例的绝佳工具。数据处理器、聊天机器人、API,等等,现在都可以使用无服务器架构进行开发。

今天,我将带您了解如何创建一个可在 AWS Lambda 上运行、并基于持久化 MongoDB 数据存储的生产级 Express API。没错,您可以在 AWS Lambda 上构建 Express 应用。太棒了!而且,您可以轻松使用 MongoDB!

仔细想想,其实很简单。使用 AWS Lambda 和使用一个小型 Node.js 运行时几乎一样。它只是抽象了除代码之外的所有内容。

让我们开始吧。

TL;DR

您可以严重伤害我的感情并跳到您感兴趣的部分,或者继续阅读。

项目设置

设置本身将非常简洁。但它仍然包含您为未来生产应用继续添加功能所需的一切。以下是最终布局的示意图,您可以大致了解。

项目设置.png

可以看出,这是一个相当简单的笔记 API,带有 CRUD 逻辑,但它能完成任务。闲话少叙,让我们开始启动项目吧。

1.安装无服务器框架

首先,您需要安装并配置无服务器框架。它是一个简单的CLI工具,可以使开发和部署变得非常容易。

$ npm i -g serverless
Enter fullscreen mode Exit fullscreen mode

现在,您已在计算机上全局安装了 Serverless 框架。现在,您可以从终端中的任何位置使用 Serverless 命令。

注意:如果您使用的是 Linux,则可能需要以 sudo 身份运行该命令。

2. 在 AWS 控制台中创建 IAM 用户

打开你的 AWS 控制台,点击左上角的服务下拉菜单。你会看到一大堆服务出现。在搜索框中输入“IAM”,然后点击它。

图片

您将被重定向到您帐户的 IAM 主页。继续添加新用户。

图片

为您的 IAM 用户命名,并勾选“编程访问”复选框。继续下一步。

图片

现在,您可以为用户添加一组权限。由于我们将让 Serverless 在我们的 AWS 账户上创建和删除各种资产,因此请检查 AdministratorAccess。

图片

继续下一步,您将看到用户已创建。现在,也只有现在,您才有权访问用户的访问密钥 ID和秘密访问密钥。请务必记下它们或下载 .csv 文件。请妥善保管,切勿向任何人展示。虽然这只是一个演示,但我已将它们像素化,以确保您了解保护它们安全的重要性。

图片

完成后,我们终于可以继续将密钥输入无服务器配置中。

3. 在无服务器配置中输入 IAM 密钥

太棒了!保存密钥后,您就可以设置 Serverless 来访问您的 AWS 账户了。切换回终端,在一行中输入以下代码:

$ serverless config credentials --provider aws --key xxxxxxxxxxxxxx --secret xxxxxxxxxxxxxx
Enter fullscreen mode Exit fullscreen mode

按下回车键!现在,你的 Serverless 安装知道在运行任何终端命令时要连接到哪个账户了。让我们开始实际操作吧。

4.创建服务

创建一个新目录来存放您的无服务器应用服务。在那里启动一个终端。现在,您可以创建新服务了。

您可能会问,什么是服务?可以将其视为一个项目。但实际上并非如此。服务是定义 AWS Lambda 函数、触发这些函数的事件以及它们所需的任何 AWS 基础设施资源的地方,所有这些都包含在一个名为serverless.yml的文件中。

返回终端类型:

$ serverless create --template aws-nodejs --path sls-express-mongodb
Enter fullscreen mode Exit fullscreen mode

create 命令会创建一个新的service。震惊!但接下来才是有意思的部分。我们需要为函数选择一个运行时。这被称为template。传入 templateaws-nodejs会将运行时设置为 Node.js。这正是我们想要的。path会为该服务创建一个文件夹。在本例中,我们将其命名为sls-express-mongodb

5. 使用代码编辑器探索服务目录

使用您喜欢的代码编辑器打开sls-express-mongodb文件夹。里面应该有三个文件,但现在我们只关注serverless.yml文件。它包含此服务的所有配置设置。在这里,您可以指定常规配置设置和每个函数的配置设置。您的serverless.yml 文件将充满样板代码和注释。您可以随意删除它们并粘贴此文件。

# serverless.yml

service: sls-express-mongodb

custom:
  secrets: ${file(secrets.json)}

provider:
  name: aws
  runtime: nodejs8.10
  stage: ${self:custom.secrets.NODE_ENV}
  region: eu-central-1
  environment: 
    NODE_ENV: ${self:custom.secrets.NODE_ENV}
    DB: ${self:custom.secrets.DB}

functions:
  app:
    handler: server.run
    events:
      - http:
          path: /
          method: ANY
          cors: true
      - http:
          path: /{proxy+}
          method: ANY
          cors: true

plugins:
  - serverless-offline
Enter fullscreen mode Exit fullscreen mode

functions属性列出了服务中的所有函数。但我们只需要一个函数,因为整个 Express 应用将被打包到这个函数中。处理程序会引用该函数。最终的应用将包含一个server.js包含该函数的文件run。非常简单。

现在看看这些事件。它们充当了代理的角色。这意味着所有到达 HTTP 端点的请求都会被代理到内部的 Express 路由器中。很酷。

我们在顶部还有一个custom部分。这可以安全地将环境变量加载到我们的应用中。稍后可以使用 来引用它们,${self:custom.secrets.<environment_var>}实际值保存在一个名为 的简单文件中secrets.json

最后,我们还有用于serverless-offline离线测试的插件。

在 MongoDB Atlas 上创建数据库

准备好进行更多配置了吗?是的,没人喜欢这部分。不过,请耐心等待。跳转到MongoDB Atlas 并注册

它是免费的,无需信用卡。这将是我们进行实际操作所需的沙盒。设置好帐户后,打开帐户页面并添加新组织。

创建组织

选择一个你喜欢的名称,任何名称都可以。点击“下一步”,继续创建组织。

图片

很好。这会带你进入组织页面。点击“新建项目”按钮。

图片

这将打开一个页面来命名你的项目。只需输入你喜欢的名称,然后点击“下一步”。

图片

MongoDB 非常重视权限和安全,因此 Atlas 会显示另一个权限管理页面。我们暂时跳过该页面,直接创建项目即可。

图片

呼,搞定了!终于可以创建真正的集群了!点击巨大的绿色“构建新集群”按钮。这会打开一个巨大的集群创建窗口。您可以保留所有默认设置,只需确保选择M0实例大小并禁用备份即可。如您所见,此集群的价格为免费。太棒了!就这样,点击“创建集群”

创建-db-7

完成所有操作后,为集群添加一个管理员用户并给他一个非常强的密码。

创建-db-9

现在,您只需启用从任何​​地方的访问即可。前往 IP 白名单。

创建-db-8

您的集群部署需要几分钟时间。在此期间,我们先安装一些依赖项。

安装依赖项

这绝对是我所有项目中最喜欢的部分……没人这么说过。不过,我们得确保这一步做得正确,这样才能顺利完成接下来的工作。

$ npm init -y
$ npm i --save express mongoose body-parser helmet serverless-http
$ npm i --save-dev serverless-offline
Enter fullscreen mode Exit fullscreen mode

首先,我们要安装生产依赖项,你肯定了解 Express、Mongoose 和 BodyParser。Helmet 是一个小型中间件,用于使用适当的 HTTP 标头保护你的端点。然而,真正的强大之处在于无服务器 HTTP 模块。它会在 Express 应用程序中创建代理,并将其打包成一个 lambda 函数。

最后,我们需要使用 Serverless Offline 在本地测试我们的应用。现在我们终于可以开始写代码了。

编写代码

是时候了!事不宜迟,让我们开始吧。

1.创建server.js

首先,我们需要将handler.js文件重命名为server.js。这里我们只放置使用模块运行 lambda 函数的逻辑serverless-http

// server.js
const sls = require('serverless-http')
const app = require('./lib/app')
module.exports.run = sls(app)
Enter fullscreen mode Exit fullscreen mode

如你所见,我们需要serverless-http,并导出一个名为 的函数run。它将保存实例的值,serverless-http并将我们的应用作为参数传递。这就是我们将 Express 应用打包成 lambda 函数所需的一切!简直太简单了。

2. 添加机密

接下来创建secrets.json文件来保存环境变量。

// secrets.json
{
  "NODE_ENV": "dev",
  "DB": "mongodb://<user>:<password>@<clustername>.mongodb.net:27017,<clustername>.mongodb.net:27017,<clustername>.mongodb.net:27017/<database>?ssl=true&replicaSet=Cluster0-shard-0&authSource=admin&retryWrites=true"
}
Enter fullscreen mode Exit fullscreen mode

要获取 Atlas 集群的连接字符串,请导航到集群仪表板并按灰色的连接按钮。按照说明操作,并确保 URL 看起来与上面的字符串类似。

3.创建 Express 应用

现在我们可以开始编写实际的 Express 应用程序了。

在根目录中创建一个名为 的新文件夹lib。在这里,您需要创建一个app.js文件和db.js一个文件作为开始。

// ./lib/db.js
const mongoose = require('mongoose')
mongoose.connect(process.env.DB)
Enter fullscreen mode Exit fullscreen mode

安装后,mongoose连接数据库的过程会大大简化。这就是我们所需要的。

注意process.env.DB在 中设置secrets.json并在 中引用serverless.yml

将开关添加db.jsapp.js文件后,粘贴下面的代码片段。

// ./lib/app.js
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
const helmet = require('helmet')
app.use(helmet())

require('./db')
const routes = require('./routes')
app.use('/api', routes)

module.exports = app
Enter fullscreen mode Exit fullscreen mode

如果你曾经用 Express 写过代码,你一定会觉得这很熟悉。我们引入了所有模块,使用了中间件,引入了上面刚刚创建的数据库连接,并将路由绑定到/api路径上。但是我们还没有创建任何路由。好吧,那就开始吧!

4. 添加路线

在文件夹中lib,创建一个名为 的新文件夹routes。它将作为应用中所有路由的基础。index.js在该文件夹中创建一个文件routes,并将此代码片段粘贴到其中。

// ./lib/routes/index.js
const express = require('express')
const router = express.Router()
const notes = require('./notes/notes.controller')
router.use('/notes', notes)
// Add more routes here if you want!
module.exports = router
Enter fullscreen mode Exit fullscreen mode

现在我们只需将任何额外的路由添加到此文件即可,无需修改任何其他内容。这太简单了。

5.编写 CRUD 逻辑

终于到了最精彩的部分了。正如你在index.js上面的文件中看到的,我们需要导入一个notes.controller.js文件,用于定义 CRUD 操作。好了,让我们开始创建它吧!

不过,为了避免跑题,我们首先需要一个 Notes API 的模型。notesroutes文件夹中创建一个文件夹,并在其中创建两个名为note.js和 的文件notes.controller.js。它们note.js将包含我们笔记的模型定义。就像这样。

// ./lib/routes/notes/note.js
const mongoose = require('mongoose')
const NoteSchema = new mongoose.Schema({

  title: String,
  // this is a bug in the markdown - should not have the quotes ""
  description: String

})
module.exports = mongoose.model('Note', NoteSchema)
Enter fullscreen mode Exit fullscreen mode

对于这个示例来说,只需要一个标题和描述就足够了。接下来,我们准备添加 CRUD。打开notes.controller.js并粘贴以下内容。

// ./lib/routes/notes/notes.controller.js
const express = require('express')
const notesController = express.Router()
const Note = require('./note')

notesController
  .post('/', async (req, res, next) => {
    const note = await Note.create(req.body)
    res.status(200).send(note)
  })

notesController
  .put('/:id', async (req, res, next) => {
    const note = await Note.findByIdAndUpdate(req.params.id, { $set: req.body }, { $upsert: true, new: true })
    res.status(200).send(note)
  })

notesController
  .get('/', async (req, res, next) => {
    const notes = await Note.find()
    res.status(200).send(notes)
  })

notesController
  .get('/:id', async (req, res, next) => {
    const note = await Note.findById(req.params.id)
    res.status(200).send(note)
  })

notesController
  .delete('/:id', async (req, res, next) => {
    const note = await Note.deleteOne({ _id: req.params.id })
    res.status(200).send(note)
  })

module.exports = notesController
Enter fullscreen mode Exit fullscreen mode

别忘了在文件顶部引用 Note 模型。除此之外,一切都相当简单。我们使用常用的 Mongoose 模型方法来创建 CRUD 操作,当然,它的语法也非常棒async/await。你还可以考虑在await操作符周围添加 try-catch 代码块。不过,这个简单的例子就足够了。

代码就这些了。准备测试!

测试

我习惯在部署应用之前先在本地进行测试。因此,我将快速向您介绍如何使用 进行测试serverless-offline。由于您已经安装并添加到plugins部分,serverless.yml您只需运行一个命令即可在本地计算机上启动 API 网关和 AWS Lambda 的本地仿真。

$ sls offline start --skipCacheInvalidation
Enter fullscreen mode Exit fullscreen mode

注意:在项目的根目录中运行sls,您应该会看到一个命令列表。如果您配置正确,sls offline应该sls offline start可以使用。

为了让您更轻松地使用此命令,请随意将其作为 npm 脚本添加到package.json.

// package.json
{
  "name": "a-crash-course-on-serverless-apis-with-express-and-mongodb",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "offline": "sls offline start --skipCacheInvalidation"
    // right here!
  },
  "keywords": [],
  "author": "Adnan Rahić",
  "license": "ISC",
  "dependencies": {
    "body-parser": "^1.18.3",
    "express": "^4.16.3",
    "helmet": "^3.12.1",
    "mongoose": "^5.1.7",
    "serverless-http": "^1.5.5"
  },
  "devDependencies": {
    "serverless-offline": "^3.20.2"
  }
}
Enter fullscreen mode Exit fullscreen mode

添加后,您可以npm run offline改为运行该命令。这样更简洁,也更容易记住。回到终端,继续运行它。

$ npm run offline
Enter fullscreen mode Exit fullscreen mode

您将看到终端告诉您本地服务器已在端口 3000 上启动。让我们测试一下!

为了测试我的端点,我通常使用 Insomnia 或 Postman,但您可以随意使用任何您喜欢的工具。首先,点击 POST 端点添加一条注释。

失眠帖

太棒了!一切正如预期。接下来尝试 GET 请求。

失眠得到一切

一切运行如梦似幻。现在,继续尝试所有其他端点。确保它们都能正常工作,然后,我们就可以准备将​​其部署到 AWS 了。

部署

如果我告诉你部署这个 API 只需要运行一个命令,你会相信吗?嗯,确实如此。

$ sls deploy
Enter fullscreen mode Exit fullscreen mode

回到终端,运行上面的命令并耐心等待。你会看到终端中出现了几个端点。这些就是你的 API 的端点。

按照我上面展示的方法,再次测试这些已部署的端点,确保它们能够正常工作。

接下来,你可能会注意到你只将 API 部署到了devstage 版本。这还不够。我们需要修改NODE_ENV并部署到生产环境。打开secrets.json文件,将第二行更改为:

"NODE_ENV": "production",
Enter fullscreen mode Exit fullscreen mode

这将传播并设置您的 Express API 的环境production以及stage生产环境。在部署生产 API 之前,我们只需删除该node_modules文件夹并重新安装所有带有该--production标志的模块即可。

$ rm -rf ./node_modules && npm i --production
Enter fullscreen mode Exit fullscreen mode

这将确保仅安装列表中指定的依赖项dependenciespackage.json而不安装列表中的依赖项devDependencies

在部署之前,您只需注释掉 中的插件部分serverless.yml

# serverless.yml

service: sls-express-mongodb

custom:
  secrets: ${file(secrets.json)}

provider:
  name: aws
  runtime: nodejs8.10
  stage: ${self:custom.secrets.NODE_ENV}
  region: eu-central-1
  environment: 
    NODE_ENV: ${self:custom.secrets.NODE_ENV}
    DB: ${self:custom.secrets.DB}

functions:
  app:
    handler: server.run
    events:
      - http:
          path: /
          method: ANY
          cors: true
      - http:
          path: /{proxy+}
          method: ANY
          cors: true

# comment this out
# plugins:
#   - serverless-offline
Enter fullscreen mode Exit fullscreen mode

继续使用与上面相同的命令进行部署。

$ sls deploy
Enter fullscreen mode Exit fullscreen mode

负载测试

如果我们不进行任何负载测试,那么这不会是一个合适的生产 API 设置教程。我倾向于使用一个很小的 ​​npm 模块来进行负载测试。它叫做loadtest,可以用一个简单的命令安装。

$ npm i -g loadtest
Enter fullscreen mode Exit fullscreen mode

注意:Linux 用户需要在命令前加上前缀sudo

让我们慢慢开始。我们要运行的命令是,/api/notes在 10 个并发用户的情况下,向该路径发送 100 次 GET 请求。

$ loadtest -n 100 -c 10 https://<id>.execute-api.eu-central-1.amazonaws.com/production/api/notes
Enter fullscreen mode Exit fullscreen mode

处理所有这些请求大约花了 5 秒钟,而且一切顺利。您可以放心,无论您最终拥有的 API 规模如何,它都会自动扩展到您需要的大小,并顺利地为您的用户提供服务。

如何深入了解您的系统?

所有无服务器应用程序的首要问题是其分布式特性。简而言之,想要全面了解所有正在发生的事情极其困难。更不用说当出现问题时,调试起来有多困难了。

为了平息我的恐惧,我使用了Tracetest。它提供由 OpenTelemetry 支持的端到端测试和调试。

幸好,这里有详细的文档,让新手入门变得轻而易举。请按照快速入门指南操作。不过,别忘了回来这里看看。😄

总结

这是一段充满冒险的旅程!您创建了一个可用于生产的无服务器 API。使用无服务器架构可能会令人感到畏惧。主要是因为您不熟悉一些服务,例如 Lambda 和 API Gateway。

上面展示的方法是我通常的做法。使用 Node.js 以及你熟悉的框架、模块和中间件,可以更轻松地过渡到无服务器模式。

幸运的是,我们拥有像Serverless Framework这样的开发工具和像Tracetest这样的可观察性工具,这使得成为开发人员变得非常容易。

如果您错过了上述任何步骤,这里是包含所有代码的存储库。

使用 Express 和 Mongodb 的无服务器 API 速成课程

关于如何创建无服务器 API 并将其部署到 AWS Lambda 的快速简便教程。持久数据存储在 Atlas 集群的 MongoDB 中。点击此处查看完整教程。




如果您想阅读我之前的一些无服务器思考,请转到我的个人资料加入我的时事通讯!

或者,立即查看我的几篇文章:

希望大家喜欢阅读这篇文章,就像我喜欢写这篇文章一样。如果你们喜欢,请点个小爱心,这样 dev.to 上会有更多人看到这篇教程。下次再见,保持好奇心,享受乐趣吧。


免责声明:Tracetest赞助了这篇博文。使用可观察性可以将测试创建和故障排除的时间和精力减少 80%。


文章来源:https://dev.to/adnanrahic/a-crash-course-on-serverless-apis-with-express-and-mongodb-193k
PREV
使用 React.js、Next.js 和 AWS Lambda 进行无服务器端渲染的速成课程 无服务器端渲染 React Next
NEXT
Vue 速查表 1 目录