1.基础用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import gzip from fastapi import FastAPI, Request, Response from fastapi.routing import APIRoute
class GzipRequest(Request): async def body(self) -> bytes: if not hasattr(self, "_body"): body = await super().body() if "gzip" in self.headers.getlist("Content-Encoding"): body = gzip.decompress(body) self._body = body return self._body
class GzipRoute(APIRoute): def get_route_handler(self) -> Callable: original_route_handler = super().get_route_handler() async def custom_route_handler(request: Request) -> Response: request = GzipRequest(request.scope, request.receive) return await original_route_handler(request) return custom_route_handler
app = FastAPI() app.router.route_class = GzipRoute
|
2.核心配置
2.1 异常处理集成
1 2 3 4 5 6 7 8 9 10 11
| class ValidationErrorLoggingRoute(APIRoute): def get_route_handler(self) -> Callable: original_route_handler = super().get_route_handler() async def custom_route_handler(request: Request) -> Response: try: return await original_route_handler(request) except RequestValidationError as exc: body = await request.body() logger.error(f"请求体解析错误: {body}") raise exc return custom_route_handler
|
- 在异常处理中捕获原始请求体,实现调试日志记录
- 支持在
HTTPException处理前访问原始请求数据
2.2 多阶段请求处理
- 请求体预解析:在FastAPI默认解析前处理原始字节流
- 动态编码支持:根据请求头自动选择解码器(如msgpack/protobuf)
- 数据转换:将非JSON格式转换为标准数据结构
3.生产环境建议
安全加固:
- 限制解压后数据大小(防止内存溢出攻击)
- 校验Content-Encoding头合法性
性能优化:
1
| app = FastAPI(debug=False)
|
- 使用
lru_cache缓存解码器实例
- 对高频请求禁用复杂解码
监控体系:
- 记录异常请求的原始字节流用于审计
- 统计各编码格式请求的耗时指标
版本管理:
- 通过路由类继承实现多版本API共存
- 使用装饰器标注支持的编码格式版本
完整实现参考:
FastAPI官方文档 - 自定义请求与路由类
测试命令示例:
1 2 3 4
| echo '[1,2,3]' | gzip | curl -X POST http://localhost:8000/sum \ -H "Content-Encoding: gzip" \ --data-binary @-
|