๋ณธ๋ฌธ - ์์ ¶
PUT
์ ์ด์ฉํ ์์ ¶
ํญ๋ชฉ์ ์์ ํ๊ธฐ ์ํด HTTP PUT
์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
jsonable_encoder
๋ฅผ ์ฌ์ฉํ์ฌ ์
๋ ฅ ๋ฐ์ดํฐ๋ฅผ (์๋ฅผ ๋ค์ด, NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ฌ์ฉ ๊ฐ๋ฅํ) JSON์ผ๋ก ์ ์ฅ ๊ฐ๋ฅํ๊ฒ ๋ณํํ ์ ์์ต๋๋ค. ์๋ฅผ ๋ค๋ฉด, datetime
์๋ฃํ์ str
๋ก ๋ณํํ๊ฒ ๋ฉ๋๋ค.
from typing import List, Union
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: Union[str, None] = None
description: Union[str, None] = None
price: Union[float, None] = None
tax: float = 10.5
tags: List[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
return items[item_id]
@app.put("/items/{item_id}", response_model=Item)
async def update_item(item_id: str, item: Item):
update_item_encoded = jsonable_encoder(item)
items[item_id] = update_item_encoded
return update_item_encoded
PUT
์ ๊ธฐ์กด ๋ฐ์ดํฐ๋ฅผ ๋์ฒดํ๊ธฐ ์ํ ํญ๋ชฉ์ ์์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
๋ฐ์ดํฐ ๋์ฒด ๊ฒฝ๊ณ ¶
๋ณธ๋ฌธ์ด ํฌํจ๋ PUT
์ ์ฌ์ฉํ์ฌ bar
ํญ๋ชฉ์ ์์ ํ๋ ค๋ฉด:
{
"name": "Barz",
"price": 3,
"description": None,
}
์ด๋ฏธ ์ ์ฅ๋ ์์ฑ "tax": 20.2
๋ฅผ ํฌํจํ์ง ์๊ธฐ ๋๋ฌธ์ ๊ธฐ๋ณธ๊ฐ "tax": 10.5
๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ฐ์ดํฐ๋ 10.5
๋ผ๋ "์๋ก์ด" tax
๋ก ์ ์ฅ๋ฉ๋๋ค.
PATCH
๋ฅผ ์ด์ฉํ ๋ถ๋ถ ์์ ¶
๋ฐ์ดํฐ๋ฅผ ๋ถ๋ถ์ ์ผ๋ก ์์ ํ๊ธฐ ์ํด HTTP PATCH
๋ฅผ ์ฌ์ฉํ ์๋ ์์ต๋๋ค.
์ฆ, ์์ ํ๋ ค๋ ๋ฐ์ดํฐ๋ง ๋ณด๋ด๊ณ , ๋๋จธ์ง๋ ๊ทธ๋๋ก ๋ ์ ์์ต๋๋ค.
์ฐธ๊ณ
์ผ๋ฐ์ ์ผ๋ก PATCH
๋ณด๋ค PUT
์ด ๋ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉ๋๊ณ , ์ ์๋ ค์ ธ ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ง์ ํ์ด ๋ถ๋ถ ์์ ์ ํ ๋๋, PUT
๋ง ์ฌ์ฉํฉ๋๋ค.
์ํ๋ ๋๋ก ์์ ๋กญ๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค, FastAPI๋ ์ด๋ฅผ ์ ํํ์ง ์์ต๋๋ค.
ํ์ง๋ง ์ด ์ง์นจ์๋ ๊ฐ ๋ฉ์๋๊ฐ ์ด๋ป๊ฒ ์ฌ์ฉ๋๋ ์ง๋ฅผ ๋ณด์ฌ์ค๋๋ค.
Pydantic์ exclude_unset
๋งค๊ฐ ๋ณ์ ์ฌ์ฉ¶
Pydantic ๋ชจ๋ธ์ .dict()
์์ exclude_unset
๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๋ถ๋ถ ์์ ์ ์ํด ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
์ด๊ฒ์ item.dict(exclude_unset=True)
์ ๊ฐ์ต๋๋ค.
์ด๋ ๊ฒ ํ๋ฉด ๊ธฐ๋ณธ๊ฐ์ ์ ์ธํ๊ณ item
๋ชจ๋ธ์ ๋ง๋ค ๋ ์ค์ ํ ๋ฐ์ดํฐ๋ง ์๋ dict
๊ฐ ์์ฑ๋ฉ๋๋ค.
์ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฉํ์ฌ ์ค์ ๋ (์์ฒญ์์ ์ ์ก๋) ๋ฐ์ดํฐ๋ง์ผ๋ก dict
๋ฅผ ์์ฑํ๊ณ ๊ธฐ๋ณธ๊ฐ์ ์๋ตํ ์ ์์ต๋๋ค:
from typing import List, Union
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: Union[str, None] = None
description: Union[str, None] = None
price: Union[float, None] = None
tax: float = 10.5
tags: List[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
return items[item_id]
@app.patch("/items/{item_id}", response_model=Item)
async def update_item(item_id: str, item: Item):
stored_item_data = items[item_id]
stored_item_model = Item(**stored_item_data)
update_data = item.dict(exclude_unset=True)
updated_item = stored_item_model.copy(update=update_data)
items[item_id] = jsonable_encoder(updated_item)
return updated_item
Pydantic์ update
๋งค๊ฐ ๋ณ์ ์ฌ์ฉ¶
์ด์ .copy()
๋ฅผ ์ด์ฉํ์ฌ ๊ธฐ์กด ๋ชจ๋ธ์ ๋ณต์ฌ๋ณธ์ ๋ง๋ค๊ณ ์์ ํ ๋ฐ์ดํฐ๊ฐ ํฌํจ๋ dict
์ ํจ๊ป update
๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค.
์์) stored_item_model.copy(update=update_data)
:
from typing import List, Union
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: Union[str, None] = None
description: Union[str, None] = None
price: Union[float, None] = None
tax: float = 10.5
tags: List[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
return items[item_id]
@app.patch("/items/{item_id}", response_model=Item)
async def update_item(item_id: str, item: Item):
stored_item_data = items[item_id]
stored_item_model = Item(**stored_item_data)
update_data = item.dict(exclude_unset=True)
updated_item = stored_item_model.copy(update=update_data)
items[item_id] = jsonable_encoder(updated_item)
return updated_item
๋ถ๋ถ ์์ ์์ฝ¶
๋ถ๋ถ ์์ ์ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์ฝํ๋ฉด:
- (์ ํ)
PUT
๋์PATCH
๋ฅผ ์ฌ์ฉํฉ๋๋ค. - ์ ์ฅ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฒ์ํฉ๋๋ค.
- ์ ๋ฐ์ดํฐ๋ฅผ Pydantic ๋ชจ๋ธ์ ๋ฃ์ต๋๋ค.
- ์ ๋ชจ๋ธ์์ (
exclude_unset
์ ์ฌ์ฉํ์ฌ) ๊ธฐ๋ณธ๊ฐ ์๋dict
๋ฅผ ์์ฑํฉ๋๋ค.- ์ด๋ ๊ฒ ํ๋ฉด ๋ชจ๋ธ์ ์ด๋ฏธ ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ ์ฅ๋ ๊ฐ์ ์ฌ์ ์ํ๋ ๋์ ํด๋ผ์ด์ธํธ๊ฐ ์ค์ ๋ก ์ค์ ํ ๊ฐ๋ง ์์ ํ ์ ์์ต๋๋ค.
- ์ ์ฅ๋ ๋ชจ๋ธ์ ๋ณต์ฌ๋ณธ์ ๋ง๋ค๊ณ , (
update
๋งค๊ฐ๋ณ์๋ฅผ ์ฌ์ฉํ์ฌ) ์์ ๋ ๋ถ๋ถ ๋ฐ์ดํฐ๋ก ์์ฑ์ ์์ ํฉ๋๋ค. - (์๋ฅผ ๋ค๋ฉด,
jsonable_encoder
๋ฅผ ์ฌ์ฉํ ๊ฒ๊ณผ ๊ฐ์ด) ๋ณต์ฌ๋ ๋ชจ๋ธ์ DB์ ์ ์ฅํ ์ ์๋ ํํ๋ก ๋ณํํฉ๋๋ค.- ์ด๊ฒ์ ๋ชจ๋ธ์
.dict()
๋ฉ์๋๋ฅผ ๋ค์ ์ฌ์ฉํ๋ ๊ฒ๊ณผ ๋น์ทํ์ง๋ง, ์๋ฅผ ๋ค์ด,datetime
์str
๋ก ๋ณํํ๋ฏ, ๊ฐ์ JSON์ผ๋ก ๋ณํ๋ ์ ์๋ ๋ฐ์ดํฐ ์๋ฃํ์ผ๋ก ํ์ธ (๋ฐ ๋ณํ) ํฉ๋๋ค.
- ์ด๊ฒ์ ๋ชจ๋ธ์
- DB์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํฉ๋๋ค.
- ์์ ๋ ๋ฐ์ดํฐ ๋ชจ๋ธ์ ๋ฐํํฉ๋๋ค.
from typing import List, Union
from fastapi import FastAPI
from fastapi.encoders import jsonable_encoder
from pydantic import BaseModel
app = FastAPI()
class Item(BaseModel):
name: Union[str, None] = None
description: Union[str, None] = None
price: Union[float, None] = None
tax: float = 10.5
tags: List[str] = []
items = {
"foo": {"name": "Foo", "price": 50.2},
"bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
"baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
}
@app.get("/items/{item_id}", response_model=Item)
async def read_item(item_id: str):
return items[item_id]
@app.patch("/items/{item_id}", response_model=Item)
async def update_item(item_id: str, item: Item):
stored_item_data = items[item_id]
stored_item_model = Item(**stored_item_data)
update_data = item.dict(exclude_unset=True)
updated_item = stored_item_model.copy(update=update_data)
items[item_id] = jsonable_encoder(updated_item)
return updated_item
ํ
์ค์ ๋ก HTTP PUT
๋ฉ์๋๋ฅผ ์ด์ฉํ์ฌ ์ด์ ๋์ผํ ๊ธฐ์ ์ ์ฌ์ฉํ ์ ์์ต๋๋ค.
๊ทธ๋ฌ๋ ์ด ์์ ๋ ์ด๋ ๊ฒ ์ฌ์ฉํ ์ ์๋ค. ์ ๋๋ง ๋ณด์ฌ์ฃผ๊ธฐ ์ํด ๋ง๋ค์ด์ก์ผ๋ฏ๋ก PATCH
๋ฅผ ์ด์ฉํ๋ ๊ฒ์ด ๋ฐ๋์งํฉ๋๋ค.
์ฐธ๊ณ
์ ๋ ฅ ๋ชจ๋ธ์ ๊ฒ์ฆ์ ์ฌ์ ํ ์ด๋ค์ง๋๋ค.
๋ฐ๋ผ์, ๋ชจ๋ ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ์๋ตํ ์ ์๋ ๋ถ๋ถ ์์ ์ ์ํด์๋ ๋ชจ๋ ์ดํธ๋ฆฌ๋ทฐํธ๊ฐ (๊ธฐ๋ณธ๊ฐ์ ์ง์ ํ๊ฑฐ๋ ํน์ None
์ ์ฌ์ฉํ์ฌ) ์ ํ์ฌํญ์ผ๋ก ํ์๋ ๋ชจ๋ธ์ด ์์ด์ผ ํฉ๋๋ค.
์์ ์ ์ํด ๋ชจ๋ ์ ํ์ ๊ฐ์ด ์๋ ๋ชจ๋ธ๊ณผ ์์ฑ์ ์ํด ํ์์ ์ผ๋ก ์๊ตฌ๋๋ ๊ฐ์ด ์๋ ๋ชจ๋ธ์ ๊ตฌ๋ณํ๊ธฐ ์ํด์๋, ์ถ๊ฐ ๋ชจ๋ธ์ ์๋ ๋ฐฉ๋ฒ์ ์ด์ฉํ ์ ์์ต๋๋ค.