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。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM