Mixed Path, Query, Request Body parameter

이제 모든 parameter들의 선언 방법에 대해 알아보았으니, 아래의 코드를 보며 어떤 parameter인지 보자.

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

@app.put("/items/{item_id}")
async def update_item(
    *,
    item_id: int = Path(..., title="The ID of the item to get", ge=0, le=1000),
    q: Optional[str] = None,
    item: Optional[Item] = None,
):
    results = {"item_id": item_id}
    if q:
        results.update({"q": q})
    if item:
        results.update({"item": item})
    return results

Multiple Body Parameters

request body에 필요한 parameter들이 여러개일때는 아래와 같이 선언할 수 있다.

class Item(BaseModel):
    name: str
    description: Optional[str] = None
    price: float
    tax: Optional[float] = None

class User(BaseModel):
    username: str
    full_name: Optional[str] = None

@app.put("/items/{item_id}")
async def update_item(item_id: int, item: Item, user: User):
    results = {"item_id": item_id, "item": item, "user": user}
    return resul

위와 같이 선언되면, request body의 내용은 아래와 같은 형식이 되어야한다.

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    }
}

Fast API는 해당 json 형식을 파악하여 자동으로 ItemUser model로 converting과 validation check을 하며 바꾸게 된다.

Singular Values in Body

Request Body는 Pydantic 모델을 설정하여 해당 Type을 명시하여 받는 것으로 Body parameter로 판단했다.

하지만 여러개의 변수를 캡슐화한 Pydantic 모델이 아닌, 단일 변수로 받고 싶을 때는 어떻게 해야될까?

이를 위해 Fast API는 Body라는 것이 존재한다.

from fastapi import Body, FastAPI

@app.put("/items/{item_id}")
async def update_item(
    *,
    item_id: int,
    item: Item,
    user: User,
    importance: int = Body(..., gt=0),
    q: Optional[str] = None
):
    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
    if q:
        results.update({"q": q})
    return results

Query/Path와 똑같이 metadata 또한 설정할 수 있다. 위와 같이 선언될 경우 request body는 아래와 같은 형식이다.

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    },
    "importance": 5
}