Sanic框架路由系统详解
sanic 项目地址: https://gitcode.com/gh_mirrors/san/sanic
前言
Sanic是一个基于Python 3.7+的异步Web框架,以其高性能和易用性著称。路由系统是Web框架的核心功能之一,它决定了如何将HTTP请求映射到处理函数。本文将深入讲解Sanic框架的路由系统,帮助开发者全面掌握路由配置技巧。
基础路由配置
路由装饰器
Sanic提供了简洁的路由装饰器语法,这是最常用的路由定义方式:
@app.route("/path")
async def handler(request):
return text("Hello World")
显式添加路由
除了装饰器,还可以使用add_route
方法显式添加路由:
async def handler(request):
return text("OK")
app.add_route(handler, "/test")
HTTP方法限定
默认情况下,路由只响应GET请求。可以通过methods
参数指定多个HTTP方法:
@app.route("/test", methods=["POST", "PUT"])
async def handler(request):
return text('OK')
HTTP方法快捷装饰器
Sanic为每种标准HTTP方法提供了便捷装饰器:
@app.get("/get") # GET请求
@app.post("/post") # POST请求
@app.put("/put") # PUT请求
@app.patch("/patch") # PATCH请求
@app.delete("/delete") # DELETE请求
@app.head("/head") # HEAD请求
@app.options("/options")# OPTIONS请求
路径参数处理
基本路径参数
Sanic支持从URL路径中提取参数:
@app.get("/user/<user_id>")
async def user_handler(request, user_id):
return text(f"User ID: {user_id}")
类型化路径参数
可以为路径参数指定类型,Sanic会自动进行类型转换和验证:
@app.get("/article/<article_id:int>")
async def article_handler(request, article_id: int):
return text(f"Article ID: {article_id} (type: {type(article_id)})")
支持的类型
Sanic内置了多种路径参数类型:
-
字符串类型
str
: 匹配非空字符串strorempty
: 匹配可能为空的字符串(v22.3+)
-
数字类型
int
: 匹配整数float
: 匹配浮点数
-
特定格式
alpha
: 仅字母slug
: URL友好的字符串(如"some-news-story")uuid
: UUID格式字符串ymd
: 日期格式(YYYY-MM-DD)
-
文件扩展名
ext
: 匹配文件扩展名(v22.3+)
-
正则表达式
- 自定义正则模式匹配
文件扩展名匹配
Sanic提供了强大的文件扩展名匹配功能:
@app.route("/image/<img_id:int:ext>")
async def img_handler(request, img_id: int, ext: str):
return text(f"Image {img_id} with extension {ext}")
支持多种匹配方式:
- 通用扩展名匹配(
<file:ext>
) - 指定扩展名(
<file:ext=jpg>
) - 多扩展名选择(
<file:ext=jpg|png|gif>
) - 结合其他类型(
<file=int:ext>
)
URL生成
基本URL生成
使用app.url_for()
根据处理函数名生成URL:
@app.route("/")
async def index(request):
url = app.url_for("user_profile", user_id=123)
return redirect(url)
@app.route("/user/<user_id>")
async def user_profile(request, user_id):
...
查询参数处理
URL生成时,额外的关键字参数会成为查询字符串:
url = app.url_for("handler", arg1="value1", arg2="value2")
# 生成: /path?arg1=value1&arg2=value2
支持多值参数:
url = app.url_for("handler", arg=["a", "b"])
# 生成: /path?arg=a&arg=b
特殊参数
Sanic提供了一些特殊参数控制URL生成:
_anchor
: 添加锚点_external
: 生成绝对URL_scheme
: 指定协议_server
: 指定服务器地址
WebSocket路由
Sanic支持WebSocket路由,语法与HTTP路由类似:
@app.websocket("/ws")
async def ws_handler(request, ws):
while True:
data = await ws.recv()
await ws.send(f"Received: {data}")
静态文件服务
基本静态文件服务
使用app.static()
方法提供静态文件服务:
app.static("/static/", "/path/to/static/files/")
命名静态路由
为静态路由命名便于URL生成:
app.static("/assets/", "./assets", name="assets")
url = app.url_for("static", name="assets", filename="style.css")
# 生成: /assets/style.css
目录索引和浏览
从v23.3开始,Sanic支持:
- 自动索引页面服务
- 目录浏览功能
app.static("/files/", "/path/to/files", index="index.html", directory_view=True)
路由配置进阶
严格斜杠控制
控制是否严格匹配URL末尾的斜杠:
app = Sanic(__file__, strict_slashes=True) # 全局设置
@app.get("/path", strict_slashes=False) # 路由级别覆盖
async def handler(request):
...
路由上下文
路由可以附加元数据,用于中间件或其他扩展:
@app.route("/", ctx={"auth": False})
async def public_handler(request):
...
最佳实践
- 命名路由:为重要路由命名,便于维护和URL生成
- 类型安全:尽可能使用类型化路径参数
- 静态文件命名:为静态路由命名避免冲突
- 路由组织:合理使用蓝图(Blueprint)组织大型应用路由
- 安全考虑:谨慎使用
path
类型参数,防止路径遍历攻击
总结
Sanic的路由系统提供了强大而灵活的功能,从简单的路径匹配到复杂的参数处理,再到静态文件服务和WebSocket支持。通过合理利用这些特性,开发者可以构建出结构清晰、易于维护的Web应用程序。掌握Sanic的路由系统是开发高效Web应用的重要一步。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考