#61.TIL | FastAPI 공식문서 따라하기(4)

Seongjae Hwang·2023년 1월 15일
0

https://slender-danger-059.notion.site/5-Request-Body-b5a20b217d524675ba22ee7437ee5c7b

Request Body

클라이언트에서 API로 데이터를 보내고 싶다면, request body를 사용할 수 있다. request body에 대해 정의를 하고 싶으면 Pydantic과 함께 사용이 가능하다. 생성, 수정, 삭제 같은 경우에는 상황에 맞는 http method와 함께 response를 하면 된다. 물론, GET 메서드와 함께 body를 보내는 것은 이상한 행동임.

Import Pydantic's BaseModel

첫번째로 BaseModel을 pydantic으로 부터 import 한다.

from typing import Union

from fastapi import FastAPI
**from pydantic import BaseModel**

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

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item

Create your data model

BaseModel클래스를 상속받는 data model을 선언한다.

from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    return item

data model을 선언하는 과정은 query 파라미터를 선언할때와 똑같이 필수/선택, default값 등 을 속성으로 부여해 줄 수 있다.

그래서 위의 data model이 JSON으로 변환되면 아래와 같이 된다.

{
    "name": "Foo",
    "description": "An optional description",
    "price": 45.2,
    "tax": 3.5
}

하지만, description 과 tax의 값은 선택적이므로 아래와 같은 값도 가능하다.

{
    "name": "Foo",
    "price": 45.2
}

Declare it as a paramete

path와 query파라미터를 선언한것과 같이 타입을 만들었던 data model로 명시하여 API에 선언할 수 있다.

from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.post("/items/")
**async def create_item(item: Item):**
    return item

결과

파이썬의 타입 선언과 같이, FastAPI에서는

  • request body로 부터 JSON을 읽는다.
  • model 클래스를 통해 상응하는 타입으로 전환한다.
  • 데이터를 validate한다.
    • 만약 invalid한다면, 에러와 함께 어디가 틀렸는지 알려준다.
  • 파라미터로 부터 받은(여기서는 item) data를 받는다.
  • model 클래스로부터 JSON Schema를 만든다.
  • 해당 Schema는 OpenAPI schema와 API문서 등에 도움을 준다.

### 정리

**Use the model**

```python
from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.post("/items/")
async def create_item(item: Item):
    item_dict = item.dict()
    if item.tax:
        **price_with_tax = item.price + item.tax**
        item_dict.update({"price_with_tax": price_with_tax})
    return item_dict
```

API 함수 안에서는 model object의 모든 속성에 직접적으로 접근할 수 있다.

**Request body + path parameters**

```python
from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

**@app.put("/items/{item_id}")
async def create_item(item_id: int, item: Item):**
    return {"item_id": item_id, **item.dict()}
```

또한, path 파라미터와 request body를 동시에 받을 수 있다. 여기서 FastAPI는 자동적으로 함수의 파라미터에서 path로 부터 받은 것은 path 파라미터로 인식을 하고, Pydantic 모델로 선언된것은 request body로 인식한다.

**Request body + path + query parameters**

```python
from typing import Union

from fastapi import FastAPI
from pydantic import BaseModel

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

app = FastAPI()

@app.put("/items/{item_id}")
**async def create_item(item_id: int, item: Item, q: Union[str, None] = None):**
    result = {"item_id": item_id, **item.dict()}
    if q:
        result.update({"q": q})
    return result
```

path에 선언된 파라미터 → **path parameters**로 인식

path에 없고 타입이 지정된 파라미터 → **query parameters**로 인식

Pydantic model로 타입이 선언된 파라미터 → **request body**로 인식
profile
Always Awake

0개의 댓글