You need to enable JavaScript to run this app. Fastify中OpenAPI schema基于查询参数条件返回字段的实现问题
优惠活动
大模型
产品
解决方案
定价
更多

Fastify中OpenAPI schema基于查询参数条件返回字段的实现问题

Fastify 按需返回响应字段的正确实现方式

原有配置的核心问题

  1. JSON Schema 的 dependencies 关键字仅支持校验当前 schema 上下文内的字段依赖,你配置的依赖路径指向了请求参数的 schema,和响应 schema 属于完全独立的校验上下文,规则完全不生效。
  2. 响应 schema 中给 total_documents 配置了 default: -1,Fastify 默认会把默认值自动填充到响应中,就算你业务逻辑没有返回该字段也会被自动补上,不符合“不存在就不返回”的需求。

正确实现步骤

1. 修正查询参数 schema

针对无值查询参数的场景,补充类型定义,方便 Fastify 正确解析参数:

fastify.addSchema({
  $id: 'persistence-query-params',
  title: "PersistenceQueryParams",
  type: 'object',
  description: 'Persistence Service GET API URL query specification. Applicable for GET API only.',
  properties: {
    'total_documents': {
      description: 'Total number of documents present in the collection, after applying filters, if any. This query paramater does not take any value, just pass it as the name (e.g. &total_documents).',
      type: ['boolean', 'null'],
      nullable: true
    }
  }
})

2. 修正响应 schema

移除不需要的默认值和依赖配置,仅声明字段格式:

querystring: {
  description: 'Persistence Service GET API URL query specification. Applicable for GET API only.',
  $ref: 'persistence-query-params#'
},
response: {
  200: {
    type: 'object',
    required: ['documents'], // 仅标记必返回的字段为必填
    properties: {
      'documents': {
        description: 'All the retrieved document(s) from the specified collection for the specified service database and account.',
        type: 'array',
        items: {
          $ref: 'persistence-response-doc#'                  
        }
      },
      'total_documents': {
        description: "If total_documents query paremeter is specified, gives the total number of documents present in the collection, after applying query paramaters, if any. If total_documents is not specified, this field will not be available in the response payload.",
        type: 'integer' // 总记录数为整数,改用更贴合的integer类型,移除default配置
      }
    }
  },
  '4xx': {
    $ref: 'error-response#',
    description: 'Error response.'
  }
}

3. 补充业务逻辑判断

在接口处理函数中根据查询参数是否存在,决定是否追加总数字段:

async function yourApiHandler(request, reply) {
  // 原有查询文档列表的逻辑
  const documents = await fetchDocuments(request.query)
  const responseData = { documents }

  // 判断是否需要返回总记录数
  if (request.query.total_documents !== undefined) {
    // 计算符合过滤条件的总记录数,注意过滤逻辑要和文档查询逻辑保持一致
    const totalCount = await countTotalDocuments(request.query)
    responseData.total_documents = totalCount
  }

  return responseData
}

可选强化配置

如果需要严格避免意外返回额外字段,可以开启 Fastify 序列化的 removeAdditional 配置,不符合 schema 声明的字段会被自动过滤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 19:30:06