基于OpenAPI 3.0改造Flask REST API:查询参数对象数组过滤器实现
符合OpenAPI 3.0规范的过滤器实现方案
关于JSON字符串打包进FormData的做法
这种方式能正常运行,但确实不符合OpenAPI的设计初衷——OpenAPI的核心价值是明确参数结构、支持自动校验和客户端代码生成。把复杂数组打包成JSON字符串后,Swagger UI等工具无法识别内部的过滤器结构,没法生成正确的请求示例,也没法自动校验参数格式。资深开发者看到会觉得这是“绕过规范的权宜之计”,但不至于上升到“诟病”的程度,更多是认为不够优雅、没利用好规范的能力。
三种优雅的规范实现方式
1. 使用JSON请求体(推荐,适合纯查询场景)
如果接口仅用于查询数据(无需上传文件),直接用POST请求+JSON请求体是最符合REST规范的方式,OpenAPI对这种结构的支持非常完善。
OpenAPI 3.0 定义示例:
paths: /api/items: post: summary: 带过滤器查询数据 requestBody: required: true content: application/json: schema: type: array items: type: object properties: prop: type: string description: 要过滤的字段名 operator: type: string enum: [equal, not_equal, gt, lt, contains] description: 过滤操作符 value: type: string description: 过滤值 example: - prop: is_automatic operator: equal value: "true" - prop: brand operator: equal value: "Sumsang" responses: '200': description: 查询结果
Flask 后端处理代码:
from flask import request, jsonify @app.route('/api/items', methods=['POST']) def get_filtered_items(): filters = request.get_json() # 直接拿到解析好的过滤器数组,无需手动json.loads # 后续数据库查询逻辑... return jsonify({"data": []})
这种方式的优点:Swagger UI能自动生成请求示例,支持参数校验,客户端可直接传JSON数组,无需额外序列化,完全符合OpenAPI规范。
2. 在FormData中明确标记JSON格式(适合需同时上传文件的场景)
如果必须用FormData(比如接口还要上传文件),可以在OpenAPI定义中明确filters字段是格式为JSON的字符串,既符合规范,又兼容现有客户端逻辑。
OpenAPI 3.0 定义示例:
paths: /api/items/upload: post: summary: 上传文件并带过滤器查询 requestBody: required: true content: multipart/form-data: schema: type: object properties: file: type: string format: binary description: 要上传的文件 filters: type: string format: json description: 过滤器数组的JSON字符串 example: '[{"prop":"is_automatic", "operator":"equal", "value":"true"}, {"prop":"brand", "operator":"equal", "value":"Sumsang"}]' responses: '200': description: 处理结果
Flask 后端处理代码:
import json from flask import request, jsonify @app.route('/api/items/upload', methods=['POST']) def upload_and_filter(): file = request.files.get('file') filters_str = request.form.get('filters') filters = json.loads(filters_str) if filters_str else [] # 后续处理逻辑... return jsonify({"status": "success"})
这种方式的优点:在OpenAPI规范中明确了参数格式,Swagger UI会提示用户输入JSON字符串,同时兼容现有客户端代码,是折中的优雅方案。
3. 使用GET请求的数组参数(不推荐,仅适合简单场景)
如果坚持用GET请求,可以利用OpenAPI 3.0对数组参数的支持,但要注意不同工具对deepObject风格的数组处理可能有差异。
OpenAPI 3.0 定义示例:
paths: /api/items: get: summary: 带过滤器查询数据(GET方式) parameters: - name: filters in: query required: true style: deepObject explode: true schema: type: array items: type: object properties: prop: type: string operator: type: string value: type: string responses: '200': description: 查询结果
对应的请求URL示例:
/api/items?filters[0][prop]=is_automatic&filters[0][operator]=equal&filters[0][value]=true&filters[1][prop]=brand&filters[1][operator]=equal&filters[1][value]=Sumsang
缺点:客户端构造URL非常麻烦,URL长度容易超限,且部分旧版工具对deepObject数组的支持不完善,仅适合简单过滤场景。
内容的提问来源于stack exchange,提问作者Luca P.
相关产品推荐
相关产品推荐

