Skip to content

8. Body - Multiple Parameters


1. Body - Multiple Parameters

  • 앞에서 PathQuery를 사용하는 방법을 살펴보았으므로, 이제 request body 선언의 고급 사용법을 살펴보자.


2. Mix Path, Query, and body parameters

  • Path, Query, 그리고 request body 매개변수를 섞어서 선언할 수 있다.
  • 또한 기본값을 None으로 설정하여 body 매개변수를 optional로 선언할 수도 있다.


from typing import Optional
from fastapi import FastAPI, Path
from pydantic import BaseModel

app = FastAPI()

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


Note

  • 위의 예제의 경우 body에서 가져올 item은 optional인데, None 기본값이 있기 때문이다.


3. Multiple body parameters

  • 위의 예제에서 path operations는 다음과 같이 Item의 속성이 있는 JSON body를 예상하게 된다.


{
  "name": "Foo",
  "description": "The pretender",
  "price": 42.0,
  "tax": 3.2
}


  • 또한, 다음과 같이 여러 body 매개변수를 선언할 수도 있다.


from typing import Optional
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

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 results


  • 위의 예제와 같은 경우 FastAPI는 함수에 둘 이상의 body 매개변수가 있음을 알게 된다.


  • 따라서 매개변수 이름을 body의 키(필드 이름)로 사용하고 다음과 같이 body를 예상하게 된다.


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


Note

  • item이 이전의 예제와 같은 방식으로 선언되었지만, 이제 키 item의 형태로 body 내부에 있어야 한다.


4. Singular values in body

  • query 및 path 매개변수에 대한 추가 데이터를 정의하는 QueryPath가 있는 것과 같이, FastAPI는 이에 상응하는 Body를 제공한다.
  • 예를 들어, 이전 모델을 확장하여 동일한 body에 itemuser 외에 다른 키 importance를 갖도록 할 수 있다.
  • 단일 값이기 때문에 그대로 선언한다면, FastAPI는 query 매개변수로 가정하게 된다.


  • 하지만 다음과 같이 Body를 사용하여 FastAPI에 다른 body의 키로 처리하도록 지시할 수 있다.


from typing import Optional
from fastapi import FastAPI, Body
from pydantic import BaseModel

app = FastAPI()

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, importance: int = Body(...)
):
    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}

    return results


  • 위의 예제를 실행하면, FastAPI는 다음과 같은 body를 예상하게 된다.


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


5. Multiple body params and query

  • 필요할 때마다 body 매개변수 외에 추가적으로 query 매개변수를 선언할 수도 있다.


  • 기본적으로 단일 값은 query 매개변수로 해석되므로, 다음과 같이 Query를 명시적으로 추가할 필요는 없다.


q: Optional[str] = None


  • 다음과 같이 작성할 수 있다.


from typing import Optional
from fastapi import FastAPI, Body
from pydantic import BaseModel

app = FastAPI()

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,
    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


6. Embed a single body parameter

  • Pydantic 모델 Item의 단일 item body 매개변수가 하나만 있다고 가정해 보자.
  • 기본적으로 FastAPI는 이 item body 매개변수를 body 전체로 인식하게 된다.


  • 하지만 추가적인 body 매개변수를 선언할 때와 같이 키 item과 그 내부에 모델 콘텐츠가 있는 JSON을 예상하려면, 다음과 같이 Body의 매개변수 embed를 사용하면 된다.


item: Item = Body(..., embed=True)


  • 다음과 같이 작성할 수 있다.


from typing import Optional
from fastapi import FastAPI, Body
from pydantic import BaseModel

app = FastAPI()

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, item: Item = Body(..., embed=True),
):
    results = {"item_id": item_id, "item": item}

    return results


  • 위의 예제를 실행하면, FastAPI는 다음과 같은 body를 예상하게 된다.


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


  • 다음의 예제는 embed=True 매개변수가 없는 예제이다.


{
  "name": "Foo",
  "description": "The pretender",
  "price": 42.0,
  "tax": 3.2
}

References