首页
/ Flasgger项目示例解析:如何构建多版本REST API文档

Flasgger项目示例解析:如何构建多版本REST API文档

2025-07-09 05:00:56作者:翟萌耘Ralph

概述

Flasgger是一个基于Flask框架的Swagger UI集成工具,能够自动从Flask应用中生成美观且交互式的API文档。本文将通过分析示例代码,深入讲解如何使用Flasgger构建支持多版本的RESTful API文档系统。

基础配置

首先需要初始化Flask应用并配置Swagger:

from flask import Flask, jsonify, request
from flask.views import MethodView
from flasgger import Swagger
from flasgger.utils import swag_from

app = Flask(__name__)
swag = Swagger(app)

多版本API配置

Flasgger支持在同一应用中定义多个API版本,每个版本可以有自己的文档端点、过滤规则和模型定义:

app.config['SWAGGER'] = {
    "swagger_version": "2.0",
    "title": "Flasgger",
    "specs": [
        {
            "version": "0.0.1",
            "title": "Api v1",
            "endpoint": 'v1_spec',
            "route": '/v1/spec',
            "rule_filter": lambda rule: rule.endpoint.startswith('should_be_v1_only'),
            "definition_filter": lambda definition: ('v1_model' in definition.tags)
        },
        {
            "version": "0.0.2",
            "title": "Api v2",
            "endpoint": 'v2_spec',
            "route": '/v2/spec',
            "rule_filter": lambda rule: rule.endpoint.startswith('should_be_v2_only'),
            "definition_filter": lambda definition: ('v2_model' in definition.tags)
        }
    ]
}

关键配置项说明:

  • rule_filter: 过滤规则,决定哪些路由属于当前API版本
  • definition_filter: 模型定义过滤器,控制哪些数据模型出现在当前版本文档中

定义API端点

基于MethodView的API

示例中展示了如何使用Flask的MethodView创建RESTful端点:

class UserAPI(MethodView):
    def get(self, team_id):
        """
        Get a list of users
        ---
        tags:
          - users
        parameters:
          - name: team_id
            in: path
            type: integer
            default: 42
        responses:
          200:
            description: Returns a list of users
            schema:
                type: array
                items:
                    $ref: '#/definitions/User'
        """
        # 实现代码...

文档注释采用YAML格式,包含端点描述、参数定义和响应模型等信息。

直接路由定义

也可以直接在路由函数上添加文档:

@app.route("/v2/resource", endpoint="should_be_v2_only")
def bla():
    """
    An endpoint that isn't using method view
    ---
    tags:
    - hacking
    responses:
      200:
        description: Hacked some hacks
        schema:
          $ref: '#/definitions/Hack'
    """
    # 实现代码...

外部YAML文件引用

Flasgger支持将API文档定义在外部YAML文件中,有两种引用方式:

  1. 使用装饰器引用:
@app.route('/v1/decorated/<username>')
@swag_from('username_specs.yml')
def fromfile_decorated(username):
    return jsonify({'username': username})
  1. 在文档字符串中引用:
@app.route('/v1/fileindoc/<username>')
def fromfile_indocstring(username):
    """
    file: username_specs.yml
    """
    return jsonify({'username': username})

数据模型定义

Flasgger提供了多种定义数据模型的方式:

使用装饰器定义模型

@swag.definition('Hack', tags=['v2_model'])
def hack(subitems):
    """
    Hack Object
    ---
    properties:
      hack:
        type: string
        description: it's a hack
      subitems:
        type: array
        items:
          $ref: '#/definitions/SubItem'
    """
    return {
        'hack': "string",
        'subitems': [subitem.dump() for subitem in subitems]
    }

使用类定义模型

@swag.definition('SubItem', tags=['v2_model'])
class SubItem(object):
    """
    SubItem Object
    ---
    properties:
      bla:
        type: string
        description: Bla
      blu:
        type: integer
        description: Blu
    """
    def __init__(self, bla, blu):
        self.bla = str(bla)
        self.blu = int(blu)

    def dump(self):
        return dict(vars(self).items())

复杂API示例

示例中包含了一个复杂的推荐系统API:

@app.route("/v2/recommendation/<target_type>/<item_type>", methods=['POST'])
def recommend(target_type, item_type):
    """
    Recommendation
    Get a single item_type as recommendation for the target_type
    ---
    tags:
      - recommendation
    parameters:
      - name: target_type
        in: path
        type: string
        default: candidate
      - name: item_type
        in: path
        type: string
        default: openings
      - in: body
        name: body
        schema:
          id: rec_query
          required:
            - candidate_id
            - context
          properties:
            candidate_id:
              type: integer
              default: 123456
            exclude:
              type: array
              items:
                  type: integer
            context:
              type: object
              schema:
                $ref: '#/definitions/rec_query_context'
    responses:
      200:
        description: A single recommendation item
        schema:
          id: rec_response
          properties:
            opening_id:
              type: integer
              default: 123456
      204:
         description: No recommendation found
    """
    # 实现代码...

跨域支持

示例中还展示了如何配置跨域访问:

@app.after_request
def allow_origin(response):
    response.headers['Access-Control-Allow-Origin'] = 'http://example.com'
    response.headers['Access-Control-Allow-Credentials'] = 'true'
    return response

总结

通过这个示例,我们可以看到Flasgger提供了强大的API文档生成能力,支持:

  • 多版本API文档共存
  • 多种文档定义方式(内联、外部文件)
  • 复杂数据模型定义
  • 灵活的过滤机制
  • 跨域支持

这些特性使得Flasgger成为Flask项目中API文档生成的优秀选择,特别适合需要维护多版本API的中大型项目。