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

如何在Fastify中实现REST接口的渐进式响应返回?

实现Fastify渐进式返回响应的两种方案

针对你这种先快速返回统计数据、再延迟返回详细结果的场景,有两种实用的实现方式:

一、使用Server-Sent Events(SSE)

SSE是专门为服务器向客户端推送实时数据设计的机制,天然适配这种分阶段返回的需求,客户端可以通过监听不同事件接收各阶段的数据。

fastify.get('/:query', async function (request, reply) {
  // 设置响应头,声明SSE格式
  reply.header('Content-Type', 'text/event-stream')
  reply.header('Cache-Control', 'no-cache')
  reply.header('Connection', 'keep-alive')

  const { query } = request.params
  // 1. 快速获取并返回记录数
  const count = await getCount(query)
  reply.write(`event: count\ndata: ${JSON.stringify({ count })}\n\n`)

  if (count > 0) {
    // 2. 执行耗时操作获取详细结果
    const res = await getResults(query)
    // 返回详细数据,同时标记结束事件
    reply.write(`event: results\ndata: ${JSON.stringify(res)}\n\n`)
    reply.write(`event: close\ndata: done\n\n`)
  }
})

客户端接收示例:

const eventSource = new EventSource('/your-query-content')
eventSource.addEventListener('count', (event) => {
  const data = JSON.parse(event.data)
  console.log('匹配记录数:', data.count)
})
eventSource.addEventListener('results', (event) => {
  const data = JSON.parse(event.data)
  console.log('详细结果:', data)
})
eventSource.addEventListener('close', () => {
  eventSource.close()
})

二、使用分块传输编码的流式响应

如果不想依赖SSE,也可以利用HTTP分块传输编码,通过可读流分批次返回JSON数据,不过需要客户端处理完整的JSON拼接逻辑。

const { Readable } = require('stream')

fastify.get('/:query', async function (request, reply) {
  const { query } = request.params
  // 创建可读流
  const stream = new Readable({
    read() {}
  })

  // 设置响应头,开启分块传输
  reply.header('Transfer-Encoding', 'chunked')
  reply.header('Content-Type', 'application/json')

  try {
    // 1. 先推送记录数(用逗号分隔,保证最终JSON格式合法)
    const count = await getCount(query)
    stream.push(JSON.stringify({ count }) + ',')

    if (count > 0) {
      // 2. 推送详细结果,补全JSON结构
      const res = await getResults(query)
      stream.push(JSON.stringify({ results: res }) + '}')
    } else {
      // 无结果时补全JSON结尾
      stream.push('}')
    }
  } catch (err) {
    stream.emit('error', err)
  } finally {
    // 结束流
    stream.push(null)
  }

  return reply.send(stream)
})

这种方式返回的是一个完整的JSON对象,浏览器会逐步接收分块数据,前端可通过监听progress事件感知数据到达,但需等待所有块接收完成才能解析成合法JSON。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:04:59