๐ ์ฝ 2๋ถ ์ฝ๋ ๋ฐ ์์๋ฉ๋๋ค
์ด์ ๊ธ ๋ณด๊ธฐ(FastAPI ๋ผ์ฐํ ์์ ์ ๋ณต)
โ ๋ฐ์ดํฐ๋ ์ค๊ณ , ์๋ต์ ๊ฐ๋ค: Pydantic, Request Body, Response ๋ชจ๋ธ ์์ ์ ๋ณต
โAPI์ ์ง์ง ํ์ ๋ฐ์ดํฐ์์ ๋์จ๋ค.โ
ํด๋ผ์ด์ธํธ์์ ์๋ฒ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๊ณ , ์๋ฒ๋ ๊ทธ์ ๋ง์ถฐ ์๋ต์ ๋๋ ค์ค๋ค. ์ด๊ฒ์ด API์ ๊ธฐ๋ณธ ๋ฉ์ปค๋์ฆ์ด๊ณ , FastAPI๋ ์ด๊ฑธ ๊ฐ์ฅ ์์ ํ๊ณ , ๊ฐ์ฅ ๋น ๋ฅด๊ฒ ๊ตฌํํ ์ ์๋ ํ๋ ์์ํฌ๋ค.
์ด๋ฒ ์๊ฐ์๋ FastAPI์ ์ธ ๊ฐ์ง ํต์ฌ ๊ธฐ๋ฅ์ ๋ํด ๋ฐฐ์๋ณธ๋ค:
- Pydantic์ ํ์ฉํ ๋ฐ์ดํฐ ๊ฒ์ฆ
- Request Body๋ฅผ ํตํด ํด๋ผ์ด์ธํธ๋ก๋ถํฐ ๋ฐ์ดํฐ ๋ฐ๊ธฐ
- ์๋ต์ ๋ช ํํ๊ฒ ๋ง๋๋ Response ๋ชจ๋ธ ์ ์
โ Pydantic์ ํ์ฉํ ๋ฐ์ดํฐ ๊ฒ์ฆ
FastAPI๋ ๋ด๋ถ์ ์ผ๋ก Pydantic์ด๋ผ๋ ๋ฐ์ดํฐ ๊ฒ์ฆ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋ค. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ํตํด ์ ๋ ฅ ๋ฐ์ดํฐ์ ์ ํจ์ฑ์ ์๋์ผ๋ก ๊ฒ์ฌํ๊ณ , ์ฌ๋ฐ๋ฅด์ง ์์ ๋ฐ์ดํฐ๋ 422 ์ค๋ฅ์ ํจ๊ป ์น์ ํ ๋ฉ์์ง๋ฅผ ์ ๊ณตํ๋ค.
1. ๊ธฐ๋ณธ ์ฌ์ฉ ์
from pydantic import BaseModel
class Item(BaseModel):
name: str
price: float
in_stock: bool
Item
์ด๋ผ๋ ํด๋์ค๋ฅผ ์ ์ํ์ง๋ง, ๋จ์ํ ํด๋์ค๊ฐ ์๋๋ค.- ์ด๊ฑด ๋ฐ์ดํฐ ๋ชจ๋ธ์ด์ ๋์์ ์ ๋ ฅ ๊ฒ์ฆ ๋๊ตฌ๋ค.
- ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ JSON ๋ฐ์ดํฐ๊ฐ ์ด ๋ชจ๋ธ๊ณผ ์ผ์นํ์ง ์์ผ๋ฉด ์๋์ผ๋ก ๊ฑฐ๋ถ๋๋ค.
2. ์๋ ํ์ ๊ฒ์ฌ
name
์๋ ๋ฌธ์์ด๋ง ๋ค์ด์์ผ ํ๋ค.price
์๋ ์ซ์(float)๊ฐ ์์ผ ํ๋ค.in_stock
์๋ Boolean ๊ฐ๋ง ํ์ฉ๋๋ค.
์๋ฅผ ๋ค์ด ํด๋ผ์ด์ธํธ๊ฐ "price": "cheap"
๋ผ๊ณ ๋ณด๋๋ค๋ฉด? โ FastAPI๋ ๋ฐ๋ก ์ค๋ฅ๋ฅผ ๋ฐํํ๋ค.
๐ฅ Request Body ์ฒ๋ฆฌํ๊ธฐ
์ด์ ๋ณธ๊ฒฉ์ ์ผ๋ก POST ์์ฒญ์ ํตํด ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ JSON ๋ฐ์ดํฐ๋ฅผ ๋ฐ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์.
1. POST ์์ฒญ ์์
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
description: str | None = None
@app.post("/items/")
def create_item(item: Item):
return {"received_item": item}
2. ๋์ ์๋ฆฌ
- ํด๋ผ์ด์ธํธ๊ฐ JSON ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ณด๋ด๋ฉด FastAPI๋
Item
๋ชจ๋ธ์ ๊ธฐ์ค์ผ๋ก ์ ํจ์ฑ์ ๊ฒ์ฌํ๋ค. - ์ ํจํ ๊ฒฝ์ฐ
item
์ธ์๋ก ์๋ ํ์ฑ๋์ด ํจ์์ ์ ๋ฌ๋๋ค. - ์๋ต์ ๋์ผํ ๊ตฌ์กฐ๋ก JSON์ผ๋ก ๋ฐํ๋๋ค.
3. ํ ์คํธ ๋ฐฉ๋ฒ
1. ์๋ฒ ์คํ:
uvicorn main:app --reload
2. Swagger ์ ์: http://127.0.0.1:8000/docs
3. /items/
POST ์์ฒญ ์คํ
JSON ์
๋ ฅ ์์:
{ "name": "Monitor", "price": 219.99, "description": "24-inch Full HD monitor" }
4. ์๋ต ๊ฒฐ๊ณผ:
{ "received_item": { "name": "Monitor", "price": 219.99, "description": "24-inch Full HD monitor" } }
4. ํ๋ ๊ธฐ๋ณธ๊ฐ ๋ฐ ์ ํ๊ฐ
description: str | None = None
์ ์ ํ ํญ๋ชฉ์- ์ ๋ ฅ์์ ๋น ์ ธ๋ ์ค๋ฅ ๋์ง ์์
- ํ์ ํํธ๋ฅผ ์ ํํ ์จ์ฃผ๋ฉด ์๋์ผ๋ก ๋ฌธ์ํ๋จ
๐ค Response ๋ชจ๋ธ ์ ์
API ์๋ต์ ๊ฐ๋ฐ์ ๋ง์๋๋ก ๊ตฌ์ฑํ๋ฉด ์ ์ง๋ณด์๊ฐ ์ด๋ ต๊ณ , ๋ฌธ์ํ๋ ์ด๋ ค์์ง๋ค. ๊ทธ๋์ FastAPI๋ ์๋ต ํํ๋ Pydantic ๋ชจ๋ธ๋ก ์ ์ํ ์ ์๋๋ก ์ง์ํ๋ค.
1. ์๋ต ๋ชจ๋ธ ์ง์ ์
from fastapi import FastAPI
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: str
price: float
description: str | None = None
class ItemResponse(BaseModel):
name: str
price: float
@app.post("/items/", response_model=ItemResponse)
def create_item(item: Item):
return item
2. ์๋ต ๋ชจ๋ธ์ด ํ๋ ์ผ
- ํด๋ผ์ด์ธํธ์๊ฒ๋
name
๊ณผprice
๋ง ๋ฐํ๋๊ณ ,description
์ ์ ์ธ๋จ - ๋ด๋ถ ๋ก์ง์์๋ ์ฌ์ ํ ์ ์ฒด ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ ์ ์์
์ฆ, ๋ด๋ถ์์๋ ํ์ํ ํ๋ ๋ชจ๋ ์ฒ๋ฆฌํ๋, ํด๋ผ์ด์ธํธ์๋ ํ์ํ ์ ๋ณด๋ง ์ ๋ฌํ ์ ์๊ฒ ๋๋ค.
3. ๋ณด์, UX ์ธก๋ฉด์์๋ ์ ๋ฆฌ
- ๋ฏผ๊ฐ ์ ๋ณด(ex. ๋น๋ฐ๋ฒํธ)๋ ์๋ต์์ ์๋์ผ๋ก ์ ์ธ ๊ฐ๋ฅ
- ํ๋ก ํธ์๋ ์ ์ฅ์์ ํ์ํ ์ ๋ณด๋ง ๋ฐ์ UX ๊ฐ์ ๊ฐ๋ฅ
๐ก ๋ณด๋์ค: ์๋ต ์ํ ์ฝ๋ ์ง์ ํ๊ธฐ
FastAPI๋ ๊ธฐ๋ณธ์ ์ผ๋ก 200 ๋๋ 201 ๋ฑ์ ์ํ ์ฝ๋๋ฅผ ์๋์ผ๋ก ์ฒ๋ฆฌํ์ง๋ง, ๋ช ์์ ์ผ๋ก ์ง์ ํ ์๋ ์๋ค.
from fastapi import status
@app.post("/items/", response_model=ItemResponse, status_code=status.HTTP_201_CREATED)
def create_item(item: Item):
return item
status.HTTP_201_CREATED
โ201 Created
์๋ต- ์ํ ์ฝ๋๋ฅผ ๋ช ํํ๊ฒ ์ง์ ํด์ค์ผ๋ก์จ API ์๋๋ฅผ ๋ ์ ํํํ ์ ์๋ค.
๐งพ ์ ๋ฆฌ: ๋ฐ์ดํฐ ํ๋ฆ์ ์ ์ดํ๋ ๊ฐ์ฅ ํ์คํ ๋ฐฉ๋ฒ
์ง๊ธ๊น์ง FastAPI์์ ๋ฐ์ดํฐ๊ฐ ์ด๋ป๊ฒ ๋ค์ด์ค๊ณ ๋๊ฐ๋์ง๋ฅผ ์ดํด๋ดค๋ค.
๊ฐ๋ | ๊ธฐ๋ฅ | ์ค๋ช |
---|---|---|
Pydantic | ์ ๋ ฅ ๊ฒ์ฆ | JSON ๋ฐ์ดํฐ๋ฅผ Python ๊ฐ์ฒด๋ก ์๋ ๋ณํ & ๊ฒ์ฆ |
Request Body | ์ ๋ ฅ ์ฒ๋ฆฌ | POST/PUT ๋ฑ์ ์์ฒญ ๋ณธ๋ฌธ์ ์ฒ๋ฆฌ |
Response Model | ์ถ๋ ฅ ์ ์ด | ์๋ต ๊ตฌ์กฐ๋ฅผ ์ ์ํด ์ผ๊ด์ฑ ํ๋ณด |
์ํ ์ฝ๋ | ์๋ต ์๋ฏธ | HTTP ํ์ค์ ๋ง๋ ์๋ฏธ ์ ๋ฌ |
FastAPI ๊ณต์ ๋ฌธ์ : https://fastapi.tiangolo.com/ko/
