使用 Sequelize 执行 CRUD
在本文的第一部分中,我们介绍了如何设置 Sequelize、创建迁移/模型以及填充数据库。在本部分中,我们将在第一部分的基础上进行 CRUD 构建。
如果您想继续,您可以从第一部分开始(如果您还没有这样做),但如果您对第一步已经感到满意,您可以直接跳到这一部分。
您可以在此处克隆本文的完整代码
安装依赖项
npm i express
我们需要安装 nodemon,它会在每次发生变化时重新启动服务器,从而减轻手动重新启动服务器的压力。
npm i -D nodemon
请注意该-D
标志,它表明该包仅在开发环境中才需要。
快速服务器设置
要设置服务器,我们需要创建两个目录 -server
和routes
:
mkdir server routes
server
在每个目录中创建一个 index.js 文件routes
:
touch server/index.js routes/index.js
添加以下代码到routes/index.js
const { Router } = require('express');
const router = Router();
router.get('/', (req, res) => res.send('Welcome'))
module.exports = router;
添加以下代码到server/index.js
const express = require('express');
const routes = require('../routes');
const server = express();
server.use(express.json());
server.use('/api', routes);
module.exports = server;
接下来,我们在项目根目录创建应用程序入口点:
touch index.js
将以下代码添加到index.js
require('dotenv').config();
const server = require('./server');
const PORT = process.env.PORT || 3300;
server.listen(PORT, () => console.log(`Server is live at localhost:${PORT}`));
最后,我们将启动脚本添加到package.json
添加以下代码到package.json
"scripts": {
"start-dev": "nodemon index.js"
},
要启动服务器运行
npm start-dev
现在访问localhost:3300/api
POSTMAN 将返回,"Welcome"
表明服务器已启动并正在运行。
创建新帖子 [C IN CRUD]
首先,让我们创建一个新文件controllers/index.js
来容纳 CRUD 逻辑。
mkdir controllers && touch controllers/index.js
将以下代码添加到controllers/index.js
const models = require('../database/models');
const createPost = async (req, res) => {
try {
const post = await models.Post.create(req.body);
return res.status(201).json({
post,
});
} catch (error) {
return res.status(500).json({error: error.message})
}
}
module.exports = {
createPost,
}
接下来,我们需要创建创建新帖子的路由。编辑routes/index.js
如下:
const { Router } = require('express');
const controllers = require('../controllers');
const router = Router();
router.get('/', (req, res) => res.send('Welcome'))
router.post('/posts', controllers.createPost);
module.exports = router;
现在,当您访问 Postman 上的创建帖子端点[POST] localhost:330/api/posts
并为请求正文填写适当的值时,将创建一个新帖子,如下面的屏幕截图所示:
获取帖子列表 [R 中的 CRUD]
我们将创建另一个用于检索帖子列表的端点。这里我们将应用eager loading
Sequelize 提供的 ORM 功能。预加载意味着在查询模型的同时检索关联的模型。在 Sequelize 中,预加载是使用include
属性实现的,如下面的代码片段所示。
将以下代码添加到controllers/index.js
。
const getAllPosts = async (req, res) => {
try {
const posts = await models.Post.findAll({
include: [
{
model: models.Comment,
as: 'comments'
},
{
model: models.User,
as: 'author'
}
]
});
return res.status(200).json({ posts });
} catch (error) {
return res.status(500).send(error.message);
}
}
getAllPosts
通过将其添加到对象来导出module.exports
。
module.exports = {
createPost,
getAllPosts
}
接下来,通过添加以下代码来定义端点routes/index.js
:
router.get('/posts', controllers.getAllPosts);
现在,当您访问 Postman 上的“获取所有帖子端点”时[GET] localhost:330/api/posts
,响应如下所示。
请注意,每篇文章都有一个评论数组和与之关联的作者对象,这是预先加载的
获取单个帖子 [CRUD 中的 R]
Sequelize 提供了一种findOne
根据模型的给定属性检索单个记录的方法。
将以下代码添加到controllers/index.js
const getPostById = async (req, res) => {
try {
const { postId } = req.params;
const post = await models.Post.findOne({
where: { id: postId },
include: [
{
model: models.Comment,
as: 'comments',
include: [
{
model: models.User,
as: 'author',
}
]
},
{
model: models.User,
as: 'author'
}
]
});
if (post) {
return res.status(200).json({ post });
}
return res.status(404).send('Post with the specified ID does not exists');
} catch (error) {
return res.status(500).send(error.message);
}
}
接下来,我们通过添加以下代码来创建端点routes/index.js
router.get('/posts/:postId', controllers.getPostById);
现在,当您访问[GET] localhost:330/api/posts/1
Postman 时,响应如下所示。
更新帖子 [CRUD 中的 U]
Sequelize 中的方法update
会更新传递给它的对象中指定的模型字段。这减轻了手动检查传递给update
方法的对象并相应地更新模型字段的压力。
添加以下代码到controllers/index.js
const updatePost = async (req, res) => {
try {
const { postId } = req.params;
const [ updated ] = await models.Post.update(req.body, {
where: { id: postId }
});
if (updated) {
const updatedPost = await models.Post.findOne({ where: { id: postId } });
return res.status(200).json({ post: updatedPost });
}
throw new Error('Post not found');
} catch (error) {
return res.status(500).send(error.message);
}
};
然后,我们通过添加以下代码来创建端点routes/index.js
router.put('/posts/:postId', controllers.updatePost);
删除帖子 [CRUD 中的 D]
destroy
Sequelize 提供了删除模型记录的方法。
添加以下代码到controllers/index.js
const deletePost = async (req, res) => {
try {
const { postId } = req.params;
const deleted = await models.Post.destroy({
where: { id: postId }
});
if (deleted) {
return res.status(204).send("Post deleted");
}
throw new Error("Post not found");
} catch (error) {
return res.status(500).send(error.message);
}
};
routes/index.js
然后使用DELETE
如下所示更新:
router.delete('/posts/:postId', controllers.deletePost);
结论
我们已经能够使用 Sequelize 实现 CRUD。但是,为了保持简单,我们跳过了一些部分,例如表单输入验证、错误处理、适当的关注点分离。因此,您可以决定进一步改进。
如果您有任何问题或希望对文章的改进做出贡献,请随时通过任何您认为方便的方式与我联系。