#63.TIL | FastAPI 공식문서 따라하기(6)

Seongjae Hwang·2023년 1월 15일
0

https://slender-danger-059.notion.site/7-Body-Multiple-Parameters-2686cabe55f04a7f803ed8111b9bc74c

Body - Multiple Parameters

Mix Path, Query and body parameters

당연히 path, query, request body 파라미터를 동시에 받을 수 있다. 또한, 다른 파라미터와 동일하게 request body도 선택적으로 받을 수 있다.

from typing import Union

from fastapi import FastAPI, Path
from pydantic import BaseModel

app = FastAPI()

class Item(BaseModel):
    name: str
    description: Union[str, None] = None
    price: float
    tax: Union[float, None] = 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: Union[str, None] = None,
    item: Union[Item, None] = 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를 받는 API만 예시에 있었지만, 두개 이상도 가능하다.

from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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

class User(BaseModel):
    username: str
    full_name: Union[str, None] = 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 results

파라미터에 두개의 Pydantic 모델이 있기 때문에 FastAPI는 두개의 request body를 받는다는 것을 인지할 수 있다.

예상되는 request body는 아래와 같다:

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

Singular values in body

만약 request body 중 한개의 value를 받는 경우 query 혹인 path 파라미터와 같이 타입을 지정해줄 수 있다. 하지만, FastAPI에서 구분을 할 수 없으므로 Body라는 key를 추가해야 된다.

from typing import Union

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()

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

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

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

이러한 경우 request body의 형태는 아래와 같다.

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

Embed a single body parameter

만약 함수 파라미터에 Pydantic 모델이 한개만 있다고 하면, FastAPI는 즉각적으로 아래와 같은 request body를 확인할 수 있을것이다. 하지만, JSON에다가 key값이 있는 구조가 있다고 예측이 된다면 embed 기능을 통해 사용이 가능하다.

{
    "name": "Foo",
    "description": "The pretender",
    "price": 42.0,
    "tax": 3.2
}
from typing import Union

from fastapi import Body, FastAPI
from pydantic import BaseModel

app = FastAPI()

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

@app.put("/items/{item_id}")
**async def update_item(item_id: int, item: Item = Body(embed=True)):**
    results = {"item_id": item_id, "item": item}
    return results

결과

{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    }
}
profile
Always Awake

0개의 댓글