使用 Nodejs、Express、Sequelize、Postgres、Docker 和 Docker Compose 的 JavaScript CRUD Rest API
简介
分步指南
Docker 部分
构建 Docker 镜像并运行 Docker 容器
结论
让我们用 JavaScript 创建一个 CRUD rest API,使用:
- Node.js
- 表达
- 续集
- Postgres
- Docker
- Docker Compose
所有代码均可在 GitHub 存储库中找到(链接在视频描述中):https://youtube.com/live/Uv-jMWV29rU
简介
以下是我们要创建的应用程序架构图:
我们将为基本的 CRUD 操作创建 5 个端点:
- 创造
- 阅读全部
- 阅读一篇
- 更新
- 删除
我们将使用以下内容创建一个 Node.js 应用程序:
- Express 作为框架
- Sequelize 作为 ORM
-
我们将 Docker 化 Node.js 应用程序
-
我们将有一个 Postgres 实例,我们将使用 Tableplus 对其进行测试
-
我们将创建一个 docker compose 文件来运行这两个服务
-
我们将使用 Postman 测试 API
分步指南
以下是分步指南。
创建新文件夹
mkdir node-crud-api
踏入其中
cd node-crud-api
初始化一个新的 npm 项目
npm init -y
安装依赖项
npm i express pg sequelize
- express 是 Node.js 框架
- pg 是与 Postgres db 连接的驱动程序
- sequelize 是 ORM,因此我们避免输入 SQL 查询
创建 4 个文件夹
mkdir controllers routes util models
使用你喜欢的 IDE 打开文件夹。如果你有 Visual Studio Code,可以在终端中输入以下命令:
code .
您现在应该有一个类似于此的文件夹:
现在让我们开始编码。
数据库连接
在“util”文件夹中创建一个名为“database.js”的文件。
该文件将包含内部配置,以允许 Node.js 应用程序和正在运行的 Postgres 实例之间的连接。
填充 util/database.js 文件
const Sequelize = require('sequelize');
const sequelize = new Sequelize(
process.env.PG_DB,
process.env.PG_USER,
process.env.PG_PASSWORD,
{
host: process.env.PG_HOST,
dialect: 'postgres',
}
);
module.exports = sequelize;
用户模型
在“models”文件夹中创建一个名为“user.js”的文件。
该文件将包含模型,在本例中为具有自动递增 ID、姓名和电子邮件的用户。
填充 models/user.js 文件:
const Sequelize = require('sequelize');
const db = require('../util/database');
const User = db.define('user', {
id: {
type: Sequelize.INTEGER,
autoIncrement: true,
allowNull: false,
primaryKey: true
},
name: Sequelize.STRING,
email: Sequelize.STRING
});
module.exports = User;
控制器
该文件包含与数据库交互所需执行的所有函数,并具有 4 个基本功能:
在“controllers”文件夹中创建一个名为“users.js”的文件
填充 controllers/users.js 文件
const User = require('../models/user');
// CRUD Controllers
//get all users
exports.getUsers = (req, res, next) => {
User.findAll()
.then(users => {
res.status(200).json({ users: users });
})
.catch(err => console.log(err));
}
//get user by id
exports.getUser = (req, res, next) => {
const userId = req.params.userId;
User.findByPk(userId)
.then(user => {
if (!user) {
return res.status(404).json({ message: 'User not found!' });
}
res.status(200).json({ user: user });
})
.catch(err => console.log(err));
}
//create user
exports.createUser = (req, res, next) => {
const name = req.body.name;
const email = req.body.email;
User.create({
name: name,
email: email
})
.then(result => {
console.log('Created User');
res.status(201).json({
message: 'User created successfully!',
user: result
});
})
.catch(err => {
console.log(err);
});
}
//update user
exports.updateUser = (req, res, next) => {
const userId = req.params.userId;
const updatedName = req.body.name;
const updatedEmail = req.body.email;
User.findByPk(userId)
.then(user => {
if (!user) {
return res.status(404).json({ message: 'User not found!' });
}
user.name = updatedName;
user.email = updatedEmail;
return user.save();
})
.then(result => {
res.status(200).json({message: 'User updated!', user: result});
})
.catch(err => console.log(err));
}
//delete user
exports.deleteUser = (req, res, next) => {
const userId = req.params.userId;
User.findByPk(userId)
.then(user => {
if (!user) {
return res.status(404).json({ message: 'User not found!' });
}
return User.destroy({
where: {
id: userId
}
});
})
.then(result => {
res.status(200).json({ message: 'User deleted!' });
})
.catch(err => console.log(err));
}
路线
在“routes”文件夹中创建一个名为“users.js”的文件。
填充 routes/users.js 文件
const controller = require('../controllers/users');
const router = require('express').Router();
// CRUD Routes /users
router.get('/', controller.getUsers); // /users
router.get('/:userId', controller.getUser); // /users/:userId
router.post('/', controller.createUser); // /users
router.put('/:userId', controller.updateUser); // /users/:userId
router.delete('/:userId', controller.deleteUser); // /users/:userId
module.exports = router;
索引文件
要运行我们的应用程序,我们需要在根级别创建更多文件。这是将由 docker 容器执行的文件。
在根文件夹中,创建一个名为 index.js 的文件
填充“index.js 文件”:
const express = require('express');
const bodyparser = require('body-parser');
const sequelize = require('./util/database');
const User = require('./models/user');
const app = express();
app.use(bodyparser.json());
app.use(bodyparser.urlencoded({ extended: false }));
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
next();
});
//test route
app.get('/', (req, res, next) => {
res.send('Hello World');
});
//CRUD routes
app.use('/users', require('./routes/users'));
//error handling
app.use((error, req, res, next) => {
console.log(error);
const status = error.statusCode || 500;
const message = error.message;
res.status(status).json({ message: message });
});
//sync database
sequelize
.sync()
.then(result => {
console.log("Database connected");
app.listen(3000);
})
.catch(err => console.log(err));
Docker 部分
让我们在根级别创建另外 3 个文件:
- .dockerignore(以点开头)
- Dockerfile(大写 D)
- docker-compose.yml
结构看起来应该是这样的:
.dockerignore 将包含一行:
node_modules
Dockerfile
要创建 Docker 镜像,我们需要一个简单但功能强大的文件。它叫做“Dockerfile”(大写 D)。我们可能会使用其他名称,但目前我们先简单介绍一下。
FROM node:14
# Create app directory
WORKDIR /app
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
EXPOSE 3000
CMD [ "node", "index.js" ]
Docker 撰写文件
要运行多个服务,一个简单的方法是创建一个名为“docker-compose.yml”的文件
docker-compose.yml 文件:
version: "3.9"
services:
node_app:
container_name: node_app
build: .
image: francescoxx/node_live_app
ports:
- "3000:3000"
environment:
- PG_DB=node_live_db
- PG_USER=francesco
- PG_PASSWORD=12345
- PG_HOST=node_db
depends_on:
- node_db
node_db:
container_name: node_db
image: postgres:12
ports:
- "5432:5432"
environment:
- POSTGRES_DB=node_live_db
- POSTGRES_USER=francesco
- POSTGRES_PASSWORD=12345
volumes:
- node_db_data:/var/lib/postgresql/data
volumes:
node_db_data: {}
构建 Docker 镜像并运行 Docker 容器
在容器中运行 Postgres
首先,让我们运行 postgres 容器:
docker compose up -d node_db
要检查日志,我们可以输入:
docker compose logs
您应该得到类似这样的输出:
如果我们看到“数据库系统已准备好接受连接”,那么我们就可以开始了!
让我们使用 TablePlus 来测试它。
单击 + 创建新连接
从 docker-compose.yml 文件复制值。(如果保留原值,则密码为 12345)
构建并运行 Docker 服务
其次,让我们构建我们的 Docker 图像:
docker compose build
最后,让我们启动服务:
docker compose up node_app
这应该是终端上的输出
使用 Postman 测试应用程序
让我们使用 Postman 测试该应用程序。
向 localhost:3000 发出 GET 请求
向 localhost:3000/users 发出 GET 请求
我们应该有一个空数组作为响应
让我们创建 3 个用户:aaa、bbb 和 ccc
让我们再次检查所有用户:
向 localhost:3000/users 发出 GET 请求
我们应该看到 3 个用户:
让我们获取一个用户,例如用户 2
向 localhost:3000/users/2 发出 GET 请求
让我们更新一个现有的用户,例如同一个用户 2
使用不同的主体向 localhost:3000/users/2 发出 PUT 请求
最后,我们删除3号用户
向 localhost:3000/users/3 发出 DELETE 请求
我们还可以使用 TablePlus 检查值
结论
这是如何使用 Node.js、Express、Sequelize、Postres、Docker 和 Docker Compose 构建 CRUD rest API 的基本示例。
所有代码均可在 GitHub 存储库中找到(链接在视频描述中):https://youtube.com/live/Uv-jMWV29rU
就这样。
如果您有任何疑问,请在下面发表评论。