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

Express对接MongoDB时通过ID查询单条数据返回404问题

问题原因及修复方案

你遇到的404错误及接口异常由以下3个可修复的问题导致:

  • 路由匹配规则错误:路由文件中定义单条资源路径时缺少前置斜杠,Express路由匹配规则下,router.route(':id')无法命中/api/v1/bootcamps/xxx格式的请求,直接返回404。
  • Mongoose方法传参不规范:getBootcamp控制器中findById方法直接传入id字符串即可,不需要封装为{_id: req.params.id}对象,不符合Mongoose官方调用规范,容易触发查询异常。
  • 代码拼写错误:updateBootcamp、deleteBootcamp方法中多次出现res.statuc的拼写错误,正确拼写为res.status,会导致接口异常时抛出运行时错误。

修复后代码示例

1. routes/bootcamps.js(路由文件)

const express = require('express')
const { getBootcamp, getBootcamps, createBootcamps, updateBootcamp, deleteBootcamp } = require('../controllers/bootcamps')

const router = express.Router()

router.route('/').get(getBootcamps).post(createBootcamps)
// 新增路径前置斜杠
router.route('/:id').put(updateBootcamp).delete(deleteBootcamp).get(getBootcamp)

module.exports = router

2. controllers/bootcamps.js(控制器文件)

const Bootcamp = require('../models/Bootcamp')

exports.getBootcamps = async (req, res, next) =>
{
    try {
        const bootcamps = await Bootcamp.find()
        res.status(200).json({success: true, count: bootcamps.length, data: bootcamps})
    } catch (error) {
        res.status(400).json({success: false})
    }
}

// 修正传参问题
exports.getBootcamp = async (req, res, next) =>
{
    try {
        // 直接传入id字符串即可
        const bootcamp = await Bootcamp.findById(req.params.id)
        if (!bootcamp)
        {
            // 找不到资源返回404更符合REST规范
            return res.status(404).json({success: false})
        }
        res.status(200).json({success: true, data: bootcamp})
    } catch (error) {
        res.status(400).json({success: false})
    }
}

exports.createBootcamps = async (req, res, next) =>
{
    try {
        const bootcamp = await Bootcamp.create(req.body)
        res.status(201).json({
            success: true,
            data: bootcamp,
            msg: 'Bootcamp created'
        })
    } catch (error) {
        console.log(error)
        res.status(400).json({success: false})
    }
}

// 修正拼写错误
exports.updateBootcamp = async (req, res, next) =>
{
   try {
    const bootcamp = await Bootcamp.findByIdAndUpdate(req.params.id, req.body, {
        new: true,
        runValidators: true
    });
    if (!bootcamp) {
        // statuc改为status
        return res.status(404).json({success: false})
    }
    res.status(200).json({ success: true, data: bootcamp })
   } catch (error) {
    // statuc改为status
    return res.status(400).json({success: false})
   }
}

// 修正拼写错误
exports.deleteBootcamp = async (req, res, next) =>
{
    try {
        const bootcamp = await Bootcamp.findByIdAndDelete(req.params.id);
        if (!bootcamp) {
            // statuc改为status
            return res.status(404).json({success: false})
        }
        res.status(200).json({ success: true, data: {} })
       } catch (error) {
        // statuc改为status
        return res.status(400).json({success: false})
       }
}

修改完成后重启服务即可正常请求单条资源接口。

内容的提问来源于stack exchange,提问作者Daniel Chikaka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 07:45:04