API路由调整需求:将users/userId/{userId}改为users/?id=abc
调整Express API路由:将路径参数改为查询参数
需求:将原API路由/users/userId/{userId}调整为/users/?id=abc,把用户ID从路径参数改为查询参数,符合API设计规范。
以下是具体修改步骤:
1. 修改路由定义
移除原有的路径参数路由,新增查询参数路由,注意路由匹配顺序(Express会优先匹配先定义的路由):
const express = require("express"); const router = express.Router(); const authenticate = require("../middlewares/authenticate"); const authorizeRoles = require("../middlewares/authorizeRoles"); const users = require("../controllers/users"); const { SUPERUSER } = require("../constants/roles"); const userValidator = require("../middlewares/validators/user"); const { upload } = require("../utils/multer"); const { getUserBadges } = require("../controllers/badges"); router.post("/verify", authenticate, users.verifyUser); // 新增:处理带查询参数id的单个用户请求 router.get("/", userValidator.validateUserIdQuery, users.getUserById); router.patch("/self", authenticate, userValidator.updateUser, users.updateSelf); // 原用户列表路由会在无id查询参数时匹配 router.get("/", authenticate, userValidator.getUsers, users.getUsers); router.get("/self", authenticate, users.getSelfDetails); router.get("/isUsernameAvailable/:username", authenticate, users.getUsernameAvailabilty); router.get("/chaincode", authenticate, users.generateChaincode); router.get("/:username", users.getUser); router.get("/:userId/intro", authenticate, authorizeRoles([SUPERUSER]), users.getUserIntro); router.put("/self/intro", authenticate, userValidator.validateJoinData, users.addUserIntro); router.get("/:id/skills", users.getUserSkills); router.get("/:id/badges", getUserBadges); // upload.single('profile') -> multer inmemory storage of file for type multipart/form-data router.post("/picture", authenticate, upload.single("profile"), users.postUserPicture); router.patch("/profileURL", authenticate, userValidator.updateProfileURL, users.profileURL); router.patch("/rejectDiff", authenticate, authorizeRoles([SUPERUSER]), users.rejectProfileDiff); router.patch("/:userId", authenticate, authorizeRoles([SUPERUSER]), users.updateUser); router.get("/suggestedUsers/:skillId", authenticate, authorizeRoles([SUPERUSER]), users.getSuggestedUsers); module.exports = router;
2. 添加查询参数验证(可选但推荐)
在userValidator中间件中添加逻辑,确保查询参数id合法:
// ../middlewares/validators/user.js exports.validateUserIdQuery = (req, res, next) => { const { id } = req.query; if (!id || typeof id !== "string" || id.trim() === "") { return res.status(400).json({ error: "有效的用户ID是必填查询参数" }); } next(); };
3. 修改控制器参数获取逻辑
更新users.getUserById控制器,从req.query.id获取用户ID,替代原有的req.params.userId:
// ../controllers/users.js exports.getUserById = async (req, res) => { try { const userId = req.query.id; // 后续业务逻辑:根据userId查询用户信息 const user = await User.findById(userId); if (!user) { return res.status(404).json({ error: "用户不存在" }); } res.status(200).json(user); } catch (error) { res.status(500).json({ error: "获取用户信息失败" }); } };
额外注意事项
- 路由顺序:必须将单个用户查询路由放在用户列表路由之前,否则会被列表路由优先匹配。
- 兼容性过渡:如果原有客户端仍在使用旧路由,可暂时保留旧路由并添加重定向,待客户端迁移完成后再移除:
// 临时重定向旧路由到新路由 router.get("/userId/:userId", (req, res) => { res.redirect(`/users?id=${req.params.userId}`); });
内容的提问来源于stack exchange,提问作者letim
相关产品推荐
相关产品推荐

