Fork me on GitHub

FastAPI中间价系列系列(一) 中间件简介及常用中间件

一、什么是中间件

(一)概念

 中间件是一个函数,它在它在每个请求被特定的路径操作处理前,以及每个响应返回之前工作,所以:

  • Request Middleware接收你应用程序的每一个请求
  • 然后它可以对这个请求做一些操作,完成一些功能
  • 处理完成后,Request Middleware将请求转发给Application
  • Response Middleware接收到Application的响应
  • 然后可以对响应做一些操作,完成一些功能
  • 处理完成后,Response Middleware将响应进行返回给客户端

(二)使用

  •  创建中间件
import time
from fastapi import FastAPI, Request

app = FastAPI()


@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    start_time = time.time()
    response = await call_next(request)
    process_time = time.time() - start_time
    response.headers["X-Process-Time"] = str(process_time)
    return response

上面创建了一个add_process_time_header的中间件,它的功能就是添加一个响应头,并且响应头的值就是处理这个响应的耗时时间。创建一个中间件你需要在

 对应的函数顶部使用@app.middleware("http")装饰器,然后中间件函数需要接收两个参数:

  • request   
  • callnext   这个函数将request传递给对应的路径操作,然后得到响应的response

  上述的中间件函数就是在调用callnext前后分别计算出时间,也就是响应开始和结束的时间,最后将响应再加一个自定义的响应头,注意一般自定义的响应头以"X-"为前缀,与内置的进行区分。

  • 使用中间件
...
@app.get("/items/")
async def get_items():
    items = [
        {"name": "apple", "price": "1.12"},
        {"name": "pear", "price": "3.14"}
    ]
    return items
...

中间件是针对全局的,相当于一个全局的钩子,只要用同一个FastAPI实例,每一个请求都会走这个中间件。

二、常见中间件

(一)CORS Middleware

在使用前后台分离开发的过程中,跨域是避免不了的,所以该中间件针对的就是跨域资源共享。

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins = [
        "http://127.0.0.1",
        "http://127.0.0.1:8000",
    ],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"]
)


@app.get("/items/")
async def get_items():
    items = [
        {"name": "apple", "price": "1.12"},
        {"name": "pear", "price": "3.14"}
    ]
    return items

这就添加了一个跨域的中间件,详细参数可参考源码:

class CORSMiddleware:
    def __init__(
        self,
        app: ASGIApp,
        allow_origins: typing.Sequence[str] = (),
        allow_methods: typing.Sequence[str] = ("GET",),
        allow_headers: typing.Sequence[str] = (),
        allow_credentials: bool = False,
        allow_origin_regex: str = None,
        expose_headers: typing.Sequence[str] = (),
        max_age: int = 600,
    ) -> None:
...

(二)HTTPSRedirectMiddleware

强制所有的请求必需是http或者wss协议。

from fastapi import FastAPI
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware

app = FastAPI()

app.add_middleware(HTTPSRedirectMiddleware)


@app.get("/items/")
async def get_items():
    items = [
        {"name": "apple", "price": "1.12"},
        {"name": "pear", "price": "3.14"}
    ]
    return items

(三)TrustedHostMiddleware

强制所有的请求都设置了正确的Host头部信息,为了防止HTTP Host的头部攻击。

from fastapi import FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware

app = FastAPI()

app.add_middleware(
    TrustedHostMiddleware,
    allowed_hosts=["*.example.com"]
)


@app.get("/items/")
async def get_items():
    items = [
        {"name": "apple", "price": "1.12"},
        {"name": "pear", "price": "3.14"}
    ]
    return items

(四)GZipMiddleware

当请求的请求头中Accept-Encoding字段值包含“gzip”时,该中间件负责处理这个结果并进行响应。这个中间件将会处理标准以及流响应。

from fastapi import FastAPI
from fastapi.middleware.gzip import GZipMiddleware

app = FastAPI()

app.add_middleware(
    GZipMiddleware,
    minimum_size=1000
)


@app.get("/items/")
async def get_items():
    items = [
        {"name": "apple", "price": "1.12"},
        {"name": "pear", "price": "3.14"}
    ]
    return items

如果不指定minimum_size的大小,将会使用其默认值500。

 

posted @ 2021-06-07 22:41  iveBoy  阅读(1565)  评论(0编辑  收藏  举报
TOP