Flask-RESTX命名空间注册顺序引发路由异常问题咨询
Flask-RESTX 路由顺序异常问题底层逻辑
核心原理
Flask 路由匹配规则
- 完全相同路径的路由,先注册的优先级更高,后注册的同路径路由会被直接覆盖
- 精准静态路由(比如
/main、/test)优先级始终高于带路径变量的通配符路由(比如/<path:path>),和注册顺序无关
Flask-RESTX Api 实例的默认注册行为
当你将Flask应用实例传入Api构造函数完成绑定时,Api会自动注册两个关键路由:
- 根路径
/的路由:默认逻辑是重定向到你配置的Swagger文档(doc参数对应的路径) /<path:path>通配符路由:负责分发所有namespace对应的API请求
对应现象解释
1. 先注册自定义/路由,后初始化Api、注册namespace
/路径正常响应:你自定义的/路由先完成注册,Api后续要注册的同路径/路由被覆盖,请求直接走你写的逻辑/test路径返回404:你使用的Flask-RESTX版本存在特性限制:Api绑定Flask应用后再调用add_namespace注册的命名空间,不会被正确纳入Api的路由分发表,所以通配符路由接收到/test请求时找不到对应处理逻辑,返回404
2. 先初始化Api、注册namespace,后注册自定义路由
/路径返回404:Api先完成了根路径/路由的注册,你后续写的自定义/路由因为同路径、后注册被覆盖,请求走Api的根路径逻辑,如果你没有配置对应处理就会返回404/test路径正常响应:namespace在Api绑定应用时已经被纳入分发表,通配符路由可以正常匹配分发/main路径正常响应:/main属于精准静态路由,优先级高于Api注册的通配符路由,不管注册顺序如何,都会被优先匹配到自定义的处理逻辑
解决方案
方案1(最推荐):给Api指定专属前缀
初始化Api时添加prefix参数,让所有API路径都统一带前缀,完全避免和普通路由冲突:
from flask import Flask from flask_restx import Api from test import test app = Flask(__name__) # 所有API路径统一添加/api前缀 api = Api( app, doc="/doc/", version="0.1", title="test", prefix='/api' ) api.add_namespace(test, '/test') # 最终访问路径为/api/test @app.route('/') def index(): return 'index' if __name__ == '__main__': app.run(debug=True)
方案2:使用Api延迟绑定逻辑
先完成所有namespace和自定义路由的注册,最后再将Api绑定到Flask应用:
from flask import Flask from flask_restx import Api from test import test app = Flask(__name__) # 初始化Api时不传入app api = Api( doc="/doc/", version="0.1", title="test", ) # 先注册所有namespace api.add_namespace(test, '/test') # 再注册自定义普通路由 @app.route('/') def index(): return 'index' # 最后将Api绑定到app api.init_app(app) if __name__ == '__main__': app.run(debug=True)
内容的提问来源于stack exchange,提问作者Kang Soon-cheol
相关产品推荐
相关产品推荐

