본문 바로가기
Fast API/fastapi배우기

Fast API 배우기 6부 - Body 클래스

by 붕어사랑 티스토리 2021. 10. 21.
반응형

앞서 Query와 Path를 좀더 심도있게 배웠다. 이번에는 Request Body를 좀더 심도있게 다뤄보자

 

 

 

Query, Path, Request Body 함께 사용하기

Query와 Path 파라미터를 함께 사용한것처럼 Request Body도 함수인자에 조합하여 사용 가능하다

 

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

위 예제에서 Request Body로 Item을 요구했다.

고로 우리는 아래와 같은 양식으로 json 데이터를 보내야 한다

curl -X 'PUT' \
  'http://127.0.0.1:8000/items/1' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "name": "Foo",
    "description": "The pretender",
    "price": 42.0,
    "tax": 3.2
}'

 

 

 

Multiple Request Body Parameters

 

아래처럼 Request Body를 함수 인풋에 여러개를 줄 수도 있다. (Item, User)

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

 

그럼 Request Body는 아래와 같이 변한다.

curl -X 'PUT' \
  'http://127.0.0.1:8000/items/1' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    }
}'

 

반응형

 

 

 

Body 클래스를 통한 단일값 선언

Query와 Path 클래스 처럼. Request Body도 Body라는 클래스를 통해 데이터를 선언 할 수 있다.

 

from typing import Optional

from fastapi import Body, 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, importance: int = Body(...)

):
    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
    return results

위 예제에서 아래와 같은 코드로 단일 request 데이터를 요구 할 수 있다. ( ... 이니깐 required인건 알겠쥬?)

importance: int = Body(...)

그러면 리퀘스트 바디를 아래와 같이 구성해야 한다

curl -X 'PUT' \
  'http://127.0.0.1:8000/items/1' \
  -H 'accept: application/json' \
  -H 'Content-Type: application/json' \
  -d '{
    "item": {
        "name": "Foo",
        "description": "The pretender",
        "price": 42.0,
        "tax": 3.2
    },
    "user": {
        "username": "dave",
        "full_name": "Dave Grohl"
    },
    "importance": 5
}'

 

 

 

 

 

단일 Request Body에 key값 부여하기

 

맨처음 본 예제에서 request body의 모습과 두번째의 request body의 차이점은 key값의 여부이다.

 

fast api는 리퀘스트 바디가 하나밖에 없으면 키값을 생략하고 리퀘스트 바디 안의 데이터만 해석하도록 되어있다.

 

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

 

 

함수인자로 Request Body가 하나일경우 위에처럼 "item" 키 값이 붙지 않는다.

 

만약 리퀘스트 바디의 key값을 넣어주고 싶다면 embed = True 를 이용하면 된다.

 

from typing import Optional

from fastapi import Body, FastAPI
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
item: Item = Body(..., embed=True)

 

 

그럼 리퀘스트 바디를 아래처럼 작성해야 한다.

 

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

댓글