RESTful 接口规划与路由拆分:前后端分离后接口越来越乱怎么办?

2026-09-14 107 浏览 0 评论 0 字

RESTful 接口规划是前后端协作的基础设施。本文围绕资源化设计讲解 RESTful 接口规范,用 HTTP 动词表达操作、用 URL 表达资源位置,并按资源边界拆分路由文件,帮你根治接口命名混乱、动词乱入、嵌套过深等问题,越写越顺。

问题背景

前端后端一旦分离开,接口就成了两边的"合同"。可往往写着写着接口就失控了:同一个资源有 /getUser 、 /userInfo 、 /user/get 三套叫法,POST 里传 id 做删除,查询参数和路径参数混着用。等到前端对接、后端维护,全凭猜。说实话,乱的根源往往是开始就没做接口规划。

原理说明

RESTful 的核心认知是: 把系统里的东西抽象成"资源"(Resource) ,用 HTTP 动词表达操作,用 URL 表达资源位置。一个资源一套 URL,做法统一、语义清晰。

  • GET /users :查列表
  • GET /users/:id :查单个
  • POST /users :新增
  • PUT /users/:id :整体更新
  • PATCH /users/:id :部分更新
  • DELETE /users/:id :删除

路径用复数名词,动词交给 HTTP method,永远不要用 getUserById 这种动词型的 URL。嵌套关系用层级表达,比如 GET /users/:id/orders 查某个用户的订单。

路由拆分则是对应着资源的边界,一个资源一个路由文件,既不臃肿,也好找好改。

示例代码

用 Express 拆资源路由,一个资源一个文件:

// routes/user.js
const express = require('express');
const router = express.Router();
const userService = require('../services/userService');

// 查列表
router.get('/', async (req, res, next) => {
  try {
    const list = await userService.list();
    res.json({ code: 0, data: list });
  } catch (err) { next(err); }
});

// 查单个
router.get('/:id', async (req, res, next) => {
  try {
    const user = await userService.getById(req.params.id);
    res.json({ code: 0, data: user });
  } catch (err) { next(err); }
});

// 新增
router.post('/', async (req, res, next) => {
  try {
    const created = await userService.create(req.body);
    res.status(201).json({ code: 0, data: created });
  } catch (err) { next(err); }
});

// 部分更新
router.patch('/:id', async (req, res, next) => {
  try {
    const updated = await userService.update(req.params.id, req.body);
    res.json({ code: 0, data: updated });
  } catch (err) { next(err); }
});

module.exports = router;

在 routes/index.js 汇总挂载:

const express = require('express');
const router = express.Router();
const userRouter = require('./user');
const orderRouter = require('./order');

router.use('/users', userRouter);
router.use('/orders', orderRouter);

module.exports = router;

常见坑与解决方案

  • 坑一:同一个资源出现多个 URL 变体。解法:先画接口清单,把资源罗列全,再定 URL,杜绝即兴命名。
  • 坑二:路径参数和查询参数混用,前端难缓存。解法:资源标识用路径参数,筛选分页用查询参数。
  • 坑三:动词英文混在 URL 里。解法:删除 get / list / delete 这类动词,交给 HTTP method 表达。
  • 坑四:嵌套层级无限加深导致 URL 又长又难读。解法:超过两层就用查询参数或独立资源,别硬套层级。

小结

接口规划是前后端协作的基础设施,多花十分钟在清单上,后面能省下几天对接口的时间。路由按资源拆分,每个资源一个文件,配合清晰的动词与语义,越写越顺。下一件事,我们把公共逻辑收敛到中间件里去统一处理。

FAQ(常见问题)

Q:URL 里到底该用复数还是单数?

A:统一用复数名词表示资源集合,如 /users 、 /orders 。单个资源再通过 /users/:id 定位。关键是全团队保持一致,避免同一资源出现多套命名。

Q:为什么不能把 getUser 、 deleteUser 这类动词写进 URL?

A:动词本身的语义应由 HTTP 的 method(GET、POST、PUT、DELETE)表达,URL 只负责表达资源位置。动词进 URL 会造成同一动作多种叫法,语义混乱且难缓存。

Q:嵌套资源层次太深怎么办?

A: GET /users/:id/orders 这类一层嵌套可读性尚可,但超过两层就该改用查询参数(如 /orders?userId=1 )或独立资源,避免 URL 又长又难维护。


发布评论

发布评论前请先 登录。
0 评论
点赞
收藏

评论列表 0

暂无评论