You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 09:22:44