本次的程式碼與目錄結構可以參考 FastAPI Tutorial : Day06 branch
昨天我們介紹了 Pydantic
的基本使用
可以透過 Schema 來定義我們 request body 的格式
今天我們要來介紹如何透過 Schema 搭配 Response model
來定義我們 response body 的格式
在 FastAPI 中,我們可以在 decorator 中加上 response_model
從 main.py
中的 create_users
這個 api endpoint 下去改
@app.post("/users" , response_model=UserSchema ) # response_model 是新加上的
def create_users(user: UserSchema):
fake_db["users"][user.id] = user
return user
可以看到更新到 Swagger UI 後,我們的 Response 會多出一個 Response body
的格式
一般來說,我們會依據 CRUD 定義對應的 Request / Response Schema
如 UserCreate
, UserUpdate
, UserRead
, UserDelete
等
schemas/user.py
class UserBase(BaseModel):
name: str
class UserCreate(UserBase):
age: int
email: str
birthday: date
class UserRead(UserBase):
email: str
可以看到 UserCreate
, UserRead
, UserDelete
都繼承了 UserBase
可以把共用的欄位放在
UserBase
中 !
接著我們更新 main.py
中 import 的 user schema 結構
# from schemas.users import User as UserSchema # 舊的
from schemas import users as UserSchema # 新的
更新 user API endpoint 的 request / response model
這次我們順便加上 delete_users
的 api endpoint
@app.post("/users" , response_model=UserSchema.UserCreate )
def create_users(user: UserSchema.UserCreate ):
fake_db["users"][user.id] = user
return user
@app.delete("/users/{user_id}" )
def delete_users(user_id: int):
user = fake_db["users"].pop(user_id)
return user
@app.get("/items/{item_id}" , response_model=ItemSchema.ItemRead)
def get_item_by_id(item_id : int , qry : str = None ):
if item_id not in fake_db["items"]:
return {"error": "Item not found"}
return fake_db['items'][item_id]
在 get user 的 api endpoint 中,我們可以看到 Response body
的格式
只剩下 name
和 email
兩個欄位
在打 API 的結果也確實只得到這兩個欄位的結果
但是我們回來看一下 fake_db
, get_users
和 UserSchema.UserRead
個別的定義
fake_db
fake_db = {
"users": {
1: {
"name": "John",
"age": 35,
"email": "[email protected]",
"birthday": "2000-01-01",
},
# ...
}
}
get_users
@app.post("/users" , response_model=UserSchema.UserCreate )
def create_users(user: UserSchema.UserCreate ):
fake_db["users"][user.id] = user
return user
UserSchema.UserRead
class UserRead(UserBase):
email: str
在 get_users
中,我們回傳的是 fake_db['users'][user_id]
那根據 fake_db
應該回傳的欄位包括:
name
age
email
birthday
但是因為我們在 get_users
中加上了 response_model=UserSchema.UserRead
而 UserSchema.UserRead
中只有 name
和 email
兩個欄位
所以在回傳結果中,只剩下:
name
email
經過這個測試,我們可以發現 response_model
除了可以定義 response body 的格式
也可以過濾掉 schema 中沒有提到的欄位
即使原本 return 的資料中有這些欄位,但是在 response 不會拿到
接著我們來更新 item
的 Schema
schemas/items.py
class ItemBase(BaseModel):
id: int
class ItemCreate(ItemBase):
name: str
price: float
brand: str
class ItemRead(ItemBase):
name: str
price: float
更新 main.py
中 import 的 item schema 結構
# from schemas.items import Item as ItemSchema # 舊的
from schemas import items as ItemSchema # 新的
更新 main.py
中的 item API endpoint
@app.get("/items/{item_id}" , response_model=ItemSchema.ItemRead)
def get_item_by_id(item_id : int , qry : str = None ):
if item_id not in fake_db["items"]:
return {"error": "Item not found"}
return fake_db['items'][item_id]
@app.post("/items" , response_model=ItemSchema.ItemCreate)
def create_items(item: ItemSchema.ItemCreate ):
fake_db["items"][item.id] = item
return item
@app.delete("/items/{item_id}")
def delete_items(item_id: int):
item = fake_db["items"].pop(item_id)
return item
- 在 FastAPI 中,我們可以在 decorator 中加上
response_model=OurSchema
- 可以透過
response_model
來定義我們 response body 的格式 - 也可以過濾掉 schema 中沒有提到的欄位 ( 即使有 return 更多資訊 )
目前進度:
/backend
目錄結構
.
├── main.py
├── run.py
├── schemas
│ ├── items.py
│ └── users.py
└── setting
├── .env.dev
├── .env.prod
├── .env.test
└── config.py
2 directories, 8 files