使用 Node、Express 和 MongoDB 构建 RESTful API

Mr.Dabaoqiang大约 7 分钟

使用 Node、Express 和 MongoDB 构建 RESTful API

目标

在本文中,我们将使用 Node、Express 和 MongoDB 构建一个 RESTful API。我们将创建用于创建数据、读取数据、更新数据和删除数据的终结点(基本 CRUD 操作)

基础知识

npm install:本地安装

npm install -g:全局安装

npm install --save:dependencies 运行时的依赖

npm install --save -dev:devDependencies 开发时的依赖

运行时使用的包用 npm install --save, 否则使用 npm install --save -dev.

The Twelve-Factor App (简体中文) (12factor.net)open in new window

这么做

在空文件夹中,运行以下命令:

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 文件将包含所有脚本,例如如何运行应用或如何测试应用,以及所有依赖项。

初始化项目

npm init

该命令是用于构建项目的分步工具。

它将提示您按以下顺序输入项目的几个方面:

项目名称, 该项目的初始版本, 项目描述, 项目的入口点(即项目的主文件), 项目的测试命令(以触发标准之类的测试) 项目的 git 存储库(可以找到项目源代码的地方) 项目的关键字(基本上是与项目相关的标签) 项目的许可证(默认为 ISC - 大多数开源 Node.js 项目都是 MIT)

安装依赖项

npm i express mongoose nodemon dotenv

Express

Node.jsopen in new window的快速,无主见,极简主义的Web框架。

express - npm (npmjs.com)open in new window

Mongoose

Mongoose是一个MongoDBopen in new window对象建模工具,旨在在异步环境中工作。

mongoosejs.comopen in new window

Nodemon

nodemon 是一种工具,通过在检测到目录中的文件更改时自动重新启动节点应用程序来帮助开发基于 Node.js 的应用程序。

nodemon 不需要对您的代码或开发方法进行任何其他更改。nodemon 是 的替换包装器。

nodemon - npm (npmjs.com)open in new window

Dotenv

Dotenv 是一个零依赖模块,它将环境变量从文件加载到 process.envopen in new window 中。将配置存储在与代码分开的环境中基于十二因素应用open in new window方法。

dotenv - npm (npmjs.com)open in new window

配置程序入口

创建一个名为 index.js 的文件,这将是我们应用程序的入口点。

const express = require('express');
const mongoose = require('mongoose');

const app = express();
// 接受 JSON 格式的数据
app.use(express.json());

app.listen(3000, () => {
    console.log(`Server Started at ${3000}`)
})

服务器设置在端口 3000 上。

热部署配置

package.json 文件中,添加一个脚本,内容如下:

  "scripts": {
    "start": "nodemon index.js",
  },

可以使用 npm start 启动我们的服务器,它将使用我们之前安装的 Nodemon 包运行

配置MongoDB数据库

下载mongo

docker pull mongo

启动实例

docker run -itd --name mongo -p 27017:27017 -v /opt/docker_v/mongo/data:/data/db mongo --auth

-d 将容器放入后台运行; -p 27017:27017:映射27017端口; -v /opt/docker_v/mongo/data:/data/db: 主机上的 /opt/docker_v/mongo/data 目录映射到容器内部的 /data/db 目录,这样容器内的数据将持久化保存在主机上; --auth:需要密码才能访问容器服务;

进入容器

docker exec -it mongo mongosh admin

创建用户

db.createUser({ user:'admin',pwd:'123456',roles:[ { role:'userAdminAnyDatabase', db: 'admin'},"readWriteAnyDatabase"]}); 进行连接

db.auth('admin', '123456')

配置数据库连接文件

在项目文件夹中创建一个名为 .env 的文件

DATABASE_URL = mongodb://admin:123456@101.43.18.117:27017/?authMechanism=DEFAULT

使用 Mongoose 将数据库连接到我们的服务器

// 获取数据库模块
const mongoose = require('mongoose');
// 获取连接
const database = mongoose.connection;

抛出成功或错误消息

具体取决于我们的数据库连接是成功还是失败

database.on('error', (error) => {
    console.log(error)
})

database.once('connected', () => {
    console.log('Database Connected');
})

database.on

表示它将连接到数据库,如果连接失败,则会抛出任何错误。

database.once

意味着它只会运行一次。如果成功,它将显示一条消息,指出“数据库已连接”。

完整代码

index.js

// 尽早在应用程序中导入并配置 dotenv
require('dotenv').config();
console.log(process.env) 

// 数据库配置
// 设置数据库配置信息
const mongoString = process.env.DATABASE_URL;
// 获取数据库模块
const mongoose = require('mongoose');
// 进行连接
mongoose.connect(mongoString);
// 获取连接
const database = mongoose.connection;
// 连接事件,异常
database.on('error', (error) => {
    console.log(error)
})
// 连接一次
database.once('connected', () => {
    console.log('Database Connected');
})

// express应用配置
const express = require('express');
// 初始化app
const app = express();
// 使用json返回
app.use(express.json());

// express容器进行监听端口
app.listen(3000, () => {
    console.log(`Server Started at ${3000}`)
})

创建路由

创建一个名为routes的文件夹,并在里面创建一个名为routes.js的文件。

将此文件导入到我们的主脚本文件。

index.js

// 导入路由 
const routes = require('./routes/routes');
// 注入路由
app.use('/api', routes);

app.use需要两件事。一个是路由,另一个是路由的内容。

现在,我们所有的端点都将从“/api”开始

路由声明

Routes.js

我们使用来自 Express 的路由器,我们也使用 module.exports 导出它。

const express = require('express');

const router = express.Router()

module.exports = router;

让我们在此路由文件中编写终结点。我们将有五条路线用于以下操作:

  1. 将数据发布到数据库。
  2. 从数据库中获取所有数据。
  3. 根据 ID 获取数据。
  4. 基于 ID 更新数据。
  5. 根据 ID 删除数据。
//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')
})

持久层

定义我们的数据库结构

创建一个名为 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('User', dataSchema)

数据发布到数据库

将此模型导入到路由.js文件中

const express = require('express');

const Model = require('../models/model');

const router = express.Router()

module.exports = router;

使用刚刚创建的模型创建要发布的数据正文

router.post('/post', (req, res) => {
    const data = new Model({
        name: req.body.name,
        age: req.body.age
    })
})

还将创建一个 try-catch 块来处理成功消息和错误

//Post Method
router.post('/post', (req, res) => {
    const data = new Model({
        name: req.body.name,
        age: req.body.age
    })
    try{
    }
    catch(error){
    }
})

在try块中,我们使用data.save()保存数据

然后,我们将数据存储在一个名为 dataToSave 的常量中。

我们还在响应正文中发送包含数据的成功消息。

在 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})
    }
})

此函数需要异步才能工作。因此,我们将使用 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})
    }
})

后面的查询,修改,删除附加下文

Routes.js

router.get('/getAll', async (req, res) => {
    try {
        const data = await Model.find();
        res.json(data)
    }
    catch (error) {
        res.status(500).json({ message: error.message })
    }
})

//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 })
    }
})

//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(500).json({ message: error.message })
    }
})


//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 })
    }
})

index.js

// 尽早在应用程序中导入并配置 dotenv
require('dotenv').config();
console.log(process.env) 

// 数据库配置
// 设置数据库配置信息
const mongoString = process.env.DATABASE_URL;
// 获取数据库模块
const mongoose = require('mongoose');
// 进行连接
mongoose.connect(mongoString);
// 获取连接
const database = mongoose.connection;
// 连接事件,异常
database.on('error', (error) => {
    console.log(error)
})
// 连接一次
database.once('connected', () => {
    console.log('Database Connected');
})

// express应用配置
const express = require('express');
// 初始化app
const app = express();
// 使用json返回
app.use(express.json());

// 获取应用里面的控制器 
const routes = require('./routes/routes');
// 进行注入
app.use('/api', routes);

// express容器进行监听端口
app.listen(3000, () => {
    console.log(`Server Started at ${3000}`)
})

项目地址

node-back/Express-Mongo-Crud at main · dabaoqiang/node-back (github.com)open in new window