原文:How to Build a RESTful API Using Node, Express, and MongoDB,作者:Nishant Kumar
在这篇文章中,我们将使用 Node、Express 和 MongoDB 构建一个 RESTful API。我们将为创建数据、读取数据、更新数据和删除数据(基本 CRUD 操作)创建端点(endpoints)。
但在我们开始之前,请确保你的系统中已经安装了 Node。如果没有,请到 https://nodejs.org/en/download/ 下载并安装它。
让我们先做一下基本设置
在一个空文件夹中,运行以下命令:
npm init
这个命令会问你各种细节,比如你的项目名称、作者、存储库等等。然后它将在该文件夹中生成一个 package.json 文件。
{
"name": "rest-api-express-mongo",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
Package.json file
这个 Package.json 文件将包含所有的脚本,如如何运行应用程序,或如何测试应用程序,以及所有的依赖。
我们现在需要安装一些依赖项。
npm i express mongoose nodemon dotenv
这里,
- Express 将被用于中间件,以创建各种 CRUD 端点
- Mongoose 用于使用各种查询来管理 MongoDB 中的数据
- Nodemon 用于在我们每次保存文件时重新启动我们的服务器
- Dotenv 管理 .env 文件
因此,请继续安装它们。
在它们完成安装后,创建一个名为 index.js. 的文件,这将是我们应用程序的入口。
而在这个文件中,让我们添加 Express 和 Mongoose,并运行该文件。
const express = require('express');
const mongoose = require('mongoose');
现在,将 Express 的内容转移到一个名为 app 的新常量中。
const express = require('express');
const mongoose = require('mongoose');
const app = express();
现在,让我们修改这个文件,在 3000 端口监听。
const express = require('express');
const mongoose = require('mongoose');
const app = express();
app.use(express.json());
app.listen(3000, () => {
console.log(`Server Started at ${3000}`)
})
现在,服务器被设置在 端口3000。让我们写脚本来启动我们的服务器。我们还添加了 app.use。在这里面,我们有一个代码片段,允许我们接受 JSON 格式的数据。
在package.json文件中,添加一个脚本,内容如下:
"scripts": {
"start": "nodemon index.js"
},
这意味着我们可以使用 npm start 启动我们的服务器,它将使用我们之前安装的 Nodemon 包运行。
在终端中输入 npm start,我们将在终端中看到以下输出:
如何配置 MongoDB 数据库
现在,让我们来配置 mongoDB 数据库。前往 https://account.mongodb.com/account/login 并创建你的账户,如果你已经有一个账户,则可以登录。
登录后,我们要创建一个数据库。
因此,创建一个 Free Shared Cluster。
它将会要求你输入用户名和密码,输入它们。
然后,添加你的 IP 地址。
点击完成并关闭。
我们的集群将需要一些时间来完成,所以让我们等待吧。同时,在项目文件夹中创建一个名为 .env 的文件。
并在集群主页中,点击连接按钮。
将出现以下窗口:
点击 MongoDB Compass,它将返回以下字符串。同时,下载并安装 MongoDB Compass。
将你的用户名和密码添加到这个你以前使用过的字符串中。最后的连接字符串将看起来像这样:
mongodb+srv://nishant:********@cluster0.xduyh.mongodb.net/testDatabase
这里,nishant 是用户名,其次是密码,最后是数据库名称。
所以,把这个字符串粘贴到 .env 文件中。
DATABASE_URL = mongodb+srv://nishant:*******@cluster0.xduyh.mongodb.net/testDatabase
现在在 MongoDB Compass 中,也添加这个字符串。
然后,点击 Connect
。
在这里,我们将得到两个数据库,这是默认的。第三个将在以后自动创建。
现在,让我们在脚本文件 index.js 中导入我们的 .env 文件的内容。
require('dotenv').config();
const mongoString = process.env.DATABASE_URL
在这里,我们将字符串存储到一个名为 mongoString. 的变量中。
现在,让我们使用 Mongoose 将数据库连接到我们的服务器。
mongoose.connect(mongoString);
const database = mongoose.connection
现在,我们必须根据我们的数据库连接是成功还是失败,抛出一个成功或错误信息。
database.on('error', (error) => {
console.log(error)
})
database.once('connected', () => {
console.log('Database Connected');
})
这里,database.on 意味着它将连接到数据库,如果连接失败,将抛出任何错误。而 database.once 意味着它将只运行一次。如果它成功了,它将显示一条信息:数据库已连接。
以下是到此为止的全部代码:
require('dotenv').config();
const express = require('express');
const mongoose = require('mongoose');
const mongoString = process.env.DATABASE_URL;
mongoose.connect(mongoString);
const database = mongoose.connection;
database.on('error', (error) => {
console.log(error)
})
database.once('connected', () => {
console.log('Database Connected');
})
const app = express();
app.use(express.json());
app.listen(3000, () => {
console.log(`Server Started at ${3000}`)
})
如何为端点(Endpoints)创建我们的路由
创建一个名为 routes 的文件夹,并在里面制作一个名为 routes.js 的文件。
将此文件导入我们的主脚本文件 index.js 中。
const routes = require('./routes/routes');
另外,让我们使用这个路由文件(routes.js)。
const routes = require('./routes/routes');
app.use('/api', routes)
这里,这个 app.use 需要两样东西。一个是基础端点(base endpoint),另一个是路由的内容。现在,我们所有的端点将从'/api'开始。
我们会得到一个错误,因为我们在路由文件里面没有任何东西。所以,让我们添加它们。
const express = require('express');
const router = express.Router()
module.exports = router;
在这里,我们使用 Express 中的 Router,并且我们也使用 module.exports 导出了它。现在,我们的应用程序可以正常工作了。
如何编写我们的端点(Endpoints)
现在,让我们在这个路由文件中写入我们的端点。我们将有五条路由用于以下 actions:
- 将数据发布到数据库
- 从数据库中获取所有数据
- 获取基于 ID 的数据
- 基于 ID 更新数据
- 根据 ID 删除数据
因此,让我们为这些 actions 创建路由:
//Post Method
router.post('/post', (req, res) => {
res.send('Post API')
})
//Get all Method
router.get('/getAll', (req, res) => {
res.send('Get All API')
})
//Get by ID Method
router.get('/getOne/:id', (req, res) => {
res.send('Get by ID API')
})
//Update by ID Method
router.patch('/update/:id', (req, res) => {
res.send('Update by ID API')
})
//Delete by ID Method
router.delete('/delete/:id', (req, res) => {
res.send('Delete by ID API')
})
我们有五个方法,使用 REST 方法的 Post、Get、Patch 和 Delete。
这个路由器把路由作为第一个参数。然后,在第二个参数中,它正在接受一个回调。
在回调中,我们有一个 res 和一个 req。res 表示响应,req 表示请求。我们使用 res 来向我们的客户端,如 Postman,或任何前端客户端发送响应。而我们使用 req 来接收来自客户端应用程序(如 Postman)或任何前端客户端的请求。
然后在回调 body 中,我们要打印一条消息,说明是响应 API 消息。
保存这个,然后打开 Postman 来检查端点(endpoints)。如果你没有,请下载 Postman。它是测试 API 端点的一个好工具。
在地址栏中添加这个地址,然后点击发送,或按回车键。
我们将在 Postman 的正文中得到这个消息,因为我们只是使用 res.send. 发送一个消息。
现在,让我们从一个客户应用中获取一个响应。让我们简单地打印一个 ID。
我们必须首先改变 getOne 函数。我们使用 req.params.id 获取 ID,然后使用 res.send. 将其发送到客户端应用程序。
//Get by ID Method
router.get('/getOne/:id', (req, res) => {
res.send(req.params.id)
})
localhost:3000/api/getOne/1000
在地址栏中添加这个端点(endpoint)。这里,我们使用 getOne 端点,后面是 ID。然后,点击发送。
我们将在 Postman 的响应 body 中获得 ID。
如何创建模型
现在,让我们创建一个模型,它将定义我们的数据库结构。
创建一个名为 model 的文件夹,里面有一个名为 model.js 的文件。
const mongoose = require('mongoose');
const dataSchema = new mongoose.Schema({
name: {
required: true,
type: String
},
age: {
required: true,
type: Number
}
})
module.exports = mongoose.model('Data', dataSchema)
在这里,我们有一个定义数据库结构的模式,它有一个 name 和一个 age 属性。这两个字段都有类型,而且都是必填的。
然后,我们简单地导出模式模型。
现在,在 routes.js 文件中导入这个模型。
const Model = require('../models/model');
如何向数据库 post 数据
让我们使用刚刚创建的模型创建要发布(post)的数据体。
router.post('/post', (req, res) => {
const data = new Model({
name: req.body.name,
age: req.body.age
})
})
我们的 name 和 agg 是接受来自 req body 的 name 和 age。我们从客户端应用如Postman,或任何前端客户端如 React 或 Angular. 获得这些数据。
我们还将创建一个try-catch块来处理成功信息和错误。
//Post Method
router.post('/post', (req, res) => {
const data = new Model({
name: req.body.name,
age: req.body.age
})
try{
}
catch(error){
}
})
在尝试块中,我们使用 data.save() 来保存 data。然后,我们将数据存储在一个叫做 dataToSave 的常量中。
我们还将成功的消息与数据一起发送到响应体中(response body)。
在 catch 块中,我们将接收任何错误,如果我们得到任何错误。
//Post Method
router.post('/post', (req, res) => {
const data = new Model({
name: req.body.name,
age: req.body.age
})
try {
const dataToSave = data.save();
res.status(200).json(dataToSave)
}
catch (error) {
res.status(400).json({message: error.message})
}
})
现在,让我们从 Postman 添加一些数据。但在这之前,这个函数需要异步工作。所以,我们将使用 async-await。
router.post('/post', async (req, res) => {
const data = new Model({
name: req.body.name,
age: req.body.age
})
try {
const dataToSave = await data.save();
res.status(200).json(dataToSave)
}
catch (error) {
res.status(400).json({message: error.message})
}
})
如果我们在正文中添加数据并点击发送,我们将得到以下结果:
它也在生成一个唯一的 ID。打开 MongoDB Compass 应用程序,你会看到数据库和你刚刚创建的这条记录。
如何获得所有数据
获取数据也很简单,只需几行代码:
router.get('/getAll', async (req, res) => {
try{
const data = await Model.find();
res.json(data)
}
catch(error){
res.status(500).json({message: error.message})
}
})
这里,我们使用 Model.find 方法从数据库中获取所有数据。然后,我们将其以 JSON 格式返回。如果我们有一个错误,我们也会得到它。
如果我们在 Postman 中调用这个端点(endpoint),我们将在 Postman 主体中得到一个对象的数组。
如何根据 ID 获取数据
这个方法也很简单。我们只需要在一个叫做 findById 的方法中传递文档的 ID,也就是 req.params.id。
//Get by ID Method
router.get('/getOne/:id', async (req, res) => {
try{
const data = await Model.findById(req.params.id);
res.json(data)
}
catch(error){
res.status(500).json({message: error.message})
}
})
如果我们点击发送,我们将根据 ID 获得数据。
如何根据 ID 来更新和删除数据
首先,让我们使用 补丁(patch) 方法来针对更新方法。
//Update by ID Method
router.patch('/update/:id', async (req, res) => {
try {
const id = req.params.id;
const updatedData = req.body;
const options = { new: true };
const result = await Model.findByIdAndUpdate(
id, updatedData, options
)
res.send(result)
}
catch (error) {
res.status(400).json({ message: error.message })
}
})
在这里,我们有三个参数传递给 findByIdAndUpdate 方法,我们用它来通过 ID 找到一个文档并更新它。
其中 req.params.id 是常量 id,updatedData 包含 req.body,还有 options,它指定了是否在 body 中返回更新的数据。
现在我们来测试一下。只要粘贴一个特定文件的 ID,然后点击发送,也要改变端点(endpoints)。
我们正在使用一个 ID 进行更新,而且它正在被更新。
删除也很简单,让我们来实现它:
//Delete by ID Method
router.delete('/delete/:id', async (req, res) => {
try {
const id = req.params.id;
const data = await Model.findByIdAndDelete(id)
res.send(`Document with ${data.name} has been deleted..`)
}
catch (error) {
res.status(400).json({ message: error.message })
}
})
我们在这里获取 ID,然后使用 Model.findByIdAndDelete 来删除该字段,同时传递 ID。
我们将更新的数据存储在一个常量 data 中。
在响应中,我们将得到这样的消息:具有特定名称的文档已经被删除。
如果我们测试一下,我们会得到以下结果:
所以,所有五个方法都完成了。我们可以发布数据和获取所有的数据(也基于 ID)。我们还可以更新它们和删除它们。
谢谢你阅读本文
在这篇文章中,你了解了如何使用 Node、Express 和 MongoDB 设计和开发一个 RESTful API。
现在你可以使用这些端点来构建一个全栈应用程序,使用 Vanilla JavaScript、React、Angular、Next 或 Vue.js。
你也可以看看我关于同一主题的视频,RESTful APIs - 使用 Node、Express 和 MongoDB 构建 RESTful API
欢迎从 GitHub 下载代码并进行实验。
祝你学习愉快!