用 Express 构建 Web API:从零到完整 CRUD

手把手用 Express 5 + Sequelize + SQLite 构建博客 API:路由、模型、校验、增删改查与错误处理全流程,适合作为 Express API 开发的入门模板。

最佳实践
应用接口与数据存储连接插画

Express API 开发的标准结构是:路由层声明端点 → 校验中间件拦截非法输入 → ORM(Sequelize)操作数据库 → 统一错误中间件兜底。本文的博客 API 示例覆盖 POST/GET/PUT/DELETE 四类端点与参数校验的完整写法,可直接作为项目脚手架参考。

项目搭建

mkdir blog-api && cd blog-api
npm init -y
npm install express sequelize sqlite3 express-validator

Express 5 + Sequelize(ORM)+ SQLite(零配置数据库,学习场景最佳)。

数据库与模型

// db.js
const { Sequelize, DataTypes } = require('sequelize');

const sequelize = new Sequelize({ dialect: 'sqlite', storage: 'blog.db' });

const Post = sequelize.define('Post', {
  title: { type: DataTypes.STRING, allowNull: false },
  content: { type: DataTypes.TEXT, allowNull: false },
  published: { type: DataTypes.BOOLEAN, defaultValue: false },
});

module.exports = { sequelize, Post };

启动时 await sequelize.sync() 自动建表(生产环境用迁移替代 sync——见 Sequelize 篇)。

路由与校验

const { body, validationResult } = require('express-validator');

const postRules = [
  body('title').trim().notEmpty().withMessage('标题必填').isLength({ max: 200 }),
  body('content').trim().notEmpty().withMessage('内容必填'),
];

app.post('/posts', postRules, async (req, res) => {
  const errors = validationResult(req);
  if (!errors.isEmpty()) {
    return res.status(422).json({ errors: errors.array() });
  }
  const post = await Post.create(req.body);
  res.status(201).json(post);
});

app.get('/posts', async (req, res) => {
  const posts = await Post.findAll({ order: [['createdAt', 'DESC']] });
  res.json(posts);
});

app.get('/posts/:id', async (req, res) => {
  const post = await Post.findByPk(req.params.id);
  if (!post) return res.status(404).json({ message: '文章不存在' });
  res.json(post);
});

app.put('/posts/:id', postRules, async (req, res) => {
  const post = await Post.findByPk(req.params.id);
  if (!post) return res.status(404).json({ message: '文章不存在' });
  await post.update(req.body);
  res.json(post);
});

app.delete('/posts/:id', async (req, res) => {
  const post = await Post.findByPk(req.params.id);
  if (!post) return res.status(404).json({ message: '文章不存在' });
  await post.destroy();
  res.status(204).end();
});

REST 约定一次到位:创建返回 201、删除返回 204、找不到返回 404、校验失败返回 422。

错误处理兜底

app.use((err, req, res, next) => {
  console.error(err);
  res.status(err.statusCode || 500).json({
    message: err.isOperational ? err.message : '服务器内部错误',
  });
});

Express 5 自动捕获异步路由的异常——async handler 里的数据库错误会自然汇入这个中间件。

下一步扩展

这个骨架往生产方向还差:分页(limit/offset 或游标)、认证(见 Passport 篇)、限流(express-rate-limit)、日志(pino)、环境配置(见环境变量篇)。按本系列对应文章逐项补齐即可。

验证接口上线后的延迟与错误

用 Express 构建 Web API完成开发验证后,可选一条包含数据库或外部调用的业务路径接入观测云。按 Node.js APM 文档确认探针初始化顺序与框架兼容性,检查请求及下游 Span 是否连续,再按文档注入日志关联字段。以路由模板或稳定的操作名聚合,避免用用户 ID、动态 URL 或完整 GraphQL 查询作为高基数标签。

接入文档:Node.js APM 接入 · 日志采集 · 日志与链路关联。

常见问题(FAQ)

Q:Express 适合做大型 API 吗?

适合,但需要自建结构:按资源拆 routes/、controllers/、services/ 三层,用 Router() 模块化。想要开箱的分层架构选 NestJS(见对比篇)。

Q:Sequelize 和其他 ORM 怎么选?

JS 生态选 Sequelize 最稳;TS 项目优先 Drizzle 或 Prisma(类型推导更好)。本系列有专门的 ORM 对比篇。

Q:API 版本管理怎么做?

URI 前缀最直白:app.use('/v1', v1Router)。大版本变更时新旧路由并行运行,客户端灰度迁移后下线旧版本。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台