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

JSON Server向allMessages数组POST请求报404错误求助

JSON Server 0.17.3 POST嵌套数组接口返回404问题解决

问题

使用JSON Server 0.17.3时,向http://localhost:3000/messages/1/allMessages发送POST请求以操作嵌套的allMessages数组,返回404错误。已确认:

  • 服务器正常运行,其他资源接口(如http://localhost:3000/messages/1)可正常访问
  • db.json中id=1的messages对象确实存在allMessages字段

环境配置

db.json

{
  "messages": [
    {
      "id": 1,
      "allMessages": [
        {
          "isMyMsg": true,
          "msg": "Hi my friend.",
          "time": 1690186800,
          "read": true,
          "id": 1
        },
        {
          "isMyMsg": true,
          "msg": "Do you like the new messenger?",
          "time": 1690186845,
          "read": true,
          "id": 2
        },
        {
          "isMyMsg": true,
          "msg": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure commodi voluptas vel cum esse qui labore. Dolorum voluptatem quod nostrum, quaerat beatae iure esse molestias quasi deleniti, vero sapiente obcaecati.",
          "time": 1690187760,
          "read": true,
          "id": 3
        },
        {
          "dateCommunication": 1690287540
        },
        {
          "isMyMsg": false,
          "msg": "Hello my dear friend. How are you? Maybe you need help?",
          "time": 1690287540,
          "read": false,
          "id": 4
        }
      ]
    }
  ]
}

routes.json

{
  "/api/messages": "/messages",
  "/api/messages/:id": "/messages/:id",
  "/api/messages/:id/allMessages": "/messages/:id/allMessages"
}

RTK Query代码(UserService.ts)

export const messageAPI = createApi({
  reducerPath: "messageAPI",
  tagTypes: ["Messages"],
  baseQuery: fetchBaseQuery({ baseUrl: "http://localhost:3000" }),
  endpoints: (build) => ({
    createMessage: build.mutation<IMessages, object>({
      query: ({ params, message }) => ({
        url: `/api/messages/1/allMessages`,
        method: "POST",
        headers: {
         "Accept": "application/json",
         "Content-Type": "application/json",
        },
        body: {
          isMyMsg: true,
          msg: "ffff",
          time: 1690287540,
          read: false,
        },
      }),
      invalidatesTags: ["Messages"],
    }),
  }),
});

问题原因

JSON Server默认仅支持顶层资源的CRUD操作,无法直接对嵌套在对象中的数组进行POST请求——它没有内置路由来处理这种嵌套资源的创建请求,因此返回404。

解决方法

方法1:调整数据结构为顶层资源(推荐,符合REST规范)

将allMessages改为顶层数组,通过messageId关联到对应的messages对象,这样JSON Server可以直接处理其CRUD请求。

修改db.json

{
  "messages": [
    {
      "id": 1
    }
  ],
  "allMessages": [
    {
      "isMyMsg": true,
      "msg": "Hi my friend.",
      "time": 1690186800,
      "read": true,
      "id": 1,
      "messageId": 1
    },
    {
      "isMyMsg": true,
      "msg": "Do you like the new messenger?",
      "time": 1690186845,
      "read": true,
      "id": 2,
      "messageId": 1
    },
    {
      "isMyMsg": true,
      "msg": "Lorem ipsum dolor sit amet, consectetur adipisicing elit. Iure commodi voluptas vel cum esse qui labore. Dolorum voluptatem quod nostrum, quaerat beatae iure esse molestias quasi deleniti, vero sapiente obcaecati.",
      "time": 1690187760,
      "read": true,
      "id": 3,
      "messageId": 1
    },
    {
      "dateCommunication": 1690287540,
      "messageId": 1
    },
    {
      "isMyMsg": false,
      "msg": "Hello my dear friend. How are you? Maybe you need help?",
      "time": 1690287540,
      "read": false,
      "id": 4,
      "messageId": 1
    }
  ]
}

更新routes.json

添加映射关系,支持通过messageId过滤消息:

{
  "/api/messages": "/messages",
  "/api/messages/:id": "/messages/:id",
  "/api/messages/:id/allMessages": "/allMessages?messageId=:id",
  "/api/allMessages": "/allMessages"
}

修改RTK Query代码

直接POST到顶层的allMessages接口,并携带messageId关联:

export const messageAPI = createApi({
  reducerPath: "messageAPI",
  tagTypes: ["Messages"],
  baseQuery: fetchBaseQuery({ baseUrl: "http://localhost:3000" }),
  endpoints: (build) => ({
    createMessage: build.mutation<IMessages, object>({
      query: ({ message }) => ({
        url: `/api/allMessages`,
        method: "POST",
        headers: {
         "Accept": "application/json",
         "Content-Type": "application/json",
        },
        body: {
          isMyMsg: true,
          msg: "ffff",
          time: 1690287540,
          read: false,
          messageId: 1 // 关联到目标message的id
        },
      }),
      invalidatesTags: ["Messages"],
    }),
  }),
});

方法2:使用PATCH请求更新嵌套数组

如果不想调整数据结构,可通过PATCH请求将新消息追加到allMessages数组中。需要先获取目标message的当前allMessages数据,再拼接新元素后提交。

修改RTK Query代码

export const messageAPI = createApi({
  reducerPath: "messageAPI",
  tagTypes: ["Messages"],
  baseQuery: fetchBaseQuery({ baseUrl: "http://localhost:3000" }),
  endpoints: (build) => ({
    // 新增查询接口获取目标message数据
    getMessage: build.query<any, number>({
      query: (id) => `/api/messages/${id}`,
      providesTags: ["Messages"],
    }),
    createMessage: build.mutation<any, { messageId: number; newMsg: any }>({
      query: ({ messageId, newMsg }) => ({
        url: `/api/messages/${messageId}`,
        method: "PATCH",
        headers: {
         "Accept": "application/json",
         "Content-Type": "application/json",
        },
        // 先通过getMessage获取原allMessages数组,再拼接新元素
        body: {
          allMessages: [...existingAllMessages, newMsg]
        },
      }),
      invalidatesTags: ["Messages"],
    }),
  }),
});

方法3:自定义JSON Server中间件处理嵌套POST

通过编写自定义服务器中间件,直接处理/messages/:id/allMessages的POST请求,手动将新消息添加到嵌套数组中。

创建server.js文件

const jsonServer = require('json-server')
const server = jsonServer.create()
const router = jsonServer.router('db.json')
const middlewares = jsonServer.defaults()

server.use(middlewares)
server.use(jsonServer.bodyParser)

// 自定义处理嵌套数组的POST请求
server.post('/messages/:id/allMessages', (req, res) => {
  const db = router.db
  const messageId = parseInt(req.params.id)
  const targetMessage = db.get('messages').find({ id: messageId }).value()

  if (!targetMessage) {
    return res.status(404).json({ error: 'Message not found' })
  }

  // 生成新消息的自增id(可选)
  const maxId = targetMessage.allMessages.reduce((max, item) => {
    return item.id ? Math.max(max, item.id) : max
  }, 0)
  const newMsg = { ...req.body, id: maxId + 1 }

  // 添加到数组并保存
  targetMessage.allMessages.push(newMsg)
  db.write()

  res.status(201).json(newMsg)
})

// 应用路由映射
server.use(jsonServer.rewriter(require('./routes.json')))
server.use(router)

server.listen(3000, () => {
  console.log('JSON Server is running with custom middleware')
})

启动服务器

替换原启动命令,运行:

node server.js

此时原RTK Query代码无需修改,即可正常发送POST请求到/api/messages/1/allMessages。


内容的提问来源于stack exchange,提问作者Олексій Шевчук

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 02:33:10