Fastify中OpenAPI schema基于查询参数条件返回字段的实现问题
Fastify 按需返回响应字段的正确实现方式
原有配置的核心问题
- JSON Schema 的
dependencies关键字仅支持校验当前 schema 上下文内的字段依赖,你配置的依赖路径指向了请求参数的 schema,和响应 schema 属于完全独立的校验上下文,规则完全不生效。 - 响应 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
相关产品推荐
相关产品推荐

