committed by
GitHub
1 changed files with 210 additions and 0 deletions
@ -0,0 +1,210 @@ |
|||
# ์๋ต ๋ชจ๋ธ |
|||
|
|||
์ด๋ค *๊ฒฝ๋ก ๋์*์ด๋ ๋งค๊ฐ๋ณ์ `response_model`๋ฅผ ์ฌ์ฉํ์ฌ ์๋ต์ ์ํ ๋ชจ๋ธ์ ์ ์ธํ ์ ์์ต๋๋ค: |
|||
|
|||
* `@app.get()` |
|||
* `@app.post()` |
|||
* `@app.put()` |
|||
* `@app.delete()` |
|||
* ๊ธฐํ. |
|||
|
|||
```Python hl_lines="17" |
|||
{!../../../docs_src/response_model/tutorial001.py!} |
|||
``` |
|||
|
|||
!!! note "์ฐธ๊ณ " |
|||
`response_model`์ "๋ฐ์ฝ๋ ์ดํฐ" ๋ฉ์๋(`get`, `post`, ๋ฑ)์ ๋งค๊ฐ๋ณ์์
๋๋ค. ๋ชจ๋ ๋งค๊ฐ๋ณ์๋ค๊ณผ ๋ณธ๋ฌธ(body)์ฒ๋ผ *๊ฒฝ๋ก ๋์ ํจ์*๊ฐ ์๋๋๋ค. |
|||
|
|||
Pydantic ๋ชจ๋ธ ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ์ ์ธํ ๊ฒ๊ณผ ๋์ผํ ํ์
์ ์์ ํ๋ฏ๋ก Pydantic ๋ชจ๋ธ์ด ๋ ์ ์์ง๋ง, `List[Item]`๊ณผ ๊ฐ์ด Pydantic ๋ชจ๋ธ๋ค์ `list`์ผ ์๋ ์์ต๋๋ค. |
|||
|
|||
FastAPI๋ ์ด `response_model`๋ฅผ ์ฌ์ฉํ์ฌ: |
|||
|
|||
* ์ถ๋ ฅ ๋ฐ์ดํฐ๋ฅผ ํ์
์ ์ธ์ผ๋ก ๋ณํ. |
|||
* ๋ฐ์ดํฐ ๊ฒ์ฆ. |
|||
* OpenAPI *๊ฒฝ๋ก ๋์*์ ์๋ต์ JSON ์คํค๋ง ์ถ๊ฐ. |
|||
* ์๋ ์์ฑ ๋ฌธ์ ์์คํ
์ ์ฌ์ฉ. |
|||
|
|||
ํ์ง๋ง ๊ฐ์ฅ ์ค์ํ ๊ฒ์: |
|||
|
|||
* ํด๋น ๋ชจ๋ธ์ ์ถ๋ ฅ ๋ฐ์ดํฐ ์ ํ. ์ด๊ฒ์ด ์ผ๋ง๋ ์ค์ํ์ง ์๋์์ ๋ณผ ๊ฒ์
๋๋ค. |
|||
|
|||
!!! note "๊ธฐ์ ์ธ๋ถ์ฌํญ" |
|||
์๋ต ๋ชจ๋ธ์ ํจ์์ ํ์
์ด๋
ธํ
์ด์
๋์ ์ด ๋งค๊ฐ๋ณ์๋ก ์ ์ธํ๋๋ฐ, ๊ฒฝ๋ก ํจ์๊ฐ ์ค์ ์๋ต ๋ชจ๋ธ์ ๋ฐํํ์ง ์๊ณ `dict`, ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ฐ์ฒด๋ ๊ธฐํ ๋ค๋ฅธ ๋ชจ๋ธ์ `response_model`์ ์ฌ์ฉํ์ฌ ํ๋ ์ ํ๊ณผ ์ง๋ ฌํ๋ฅผ ์ํํ๊ณ ๋ฐํํ ์ ์๊ธฐ ๋๋ฌธ์
๋๋ค |
|||
|
|||
## ๋์ผํ ์
๋ ฅ ๋ฐ์ดํฐ ๋ฐํ |
|||
|
|||
์ฌ๊ธฐ์ ์ฐ๋ฆฌ๋ ํ๋ฌธ ๋น๋ฐ๋ฒํธ๋ฅผ ํฌํจํ๋ `UserIn` ๋ชจ๋ธ์ ์ ์ธํฉ๋๋ค: |
|||
|
|||
```Python hl_lines="9 11" |
|||
{!../../../docs_src/response_model/tutorial002.py!} |
|||
``` |
|||
|
|||
๊ทธ๋ฆฌ๊ณ ์ด ๋ชจ๋ธ์ ์ฌ์ฉํ์ฌ ์
๋ ฅ์ ์ ์ธํ๊ณ ๊ฐ์ ๋ชจ๋ธ๋ก ์ถ๋ ฅ์ ์ ์ธํฉ๋๋ค: |
|||
|
|||
```Python hl_lines="17-18" |
|||
{!../../../docs_src/response_model/tutorial002.py!} |
|||
``` |
|||
|
|||
์ด์ ๋ธ๋ผ์ฐ์ ๊ฐ ๋น๋ฐ๋ฒํธ๋ก ์ฌ์ฉ์๋ฅผ ๋ง๋ค ๋๋ง๋ค API๋ ์๋ต์ผ๋ก ๋์ผํ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฐํํฉ๋๋ค. |
|||
|
|||
์ด ๊ฒฝ์ฐ, ์ฌ์ฉ์๊ฐ ์ค์ค๋ก ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฐ์ ํ๊ธฐ ๋๋ฌธ์ ๋ฌธ์ ๊ฐ ๋์ง ์์ ์ ์์ต๋๋ค. |
|||
|
|||
๊ทธ๋ฌ๋ ๋์ผํ ๋ชจ๋ธ์ ๋ค๋ฅธ *๊ฒฝ๋ก ๋์*์์ ์ฌ์ฉํ ๊ฒฝ์ฐ, ๋ชจ๋ ํด๋ผ์ด์ธํธ์๊ฒ ์ฌ์ฉ์์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฐ์ ํ ์ ์์ต๋๋ค. |
|||
|
|||
!!! danger "์ํ" |
|||
์ ๋๋ก ์ฌ์ฉ์์ ํ๋ฌธ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ์ฅํ๊ฑฐ๋ ์๋ต์ผ๋ก ๋ฐ์ ํ์ง ๋ง์ญ์์ค. |
|||
|
|||
## ์ถ๋ ฅ ๋ชจ๋ธ ์ถ๊ฐ |
|||
|
|||
๋์ ํ๋ฌธ ๋น๋ฐ๋ฒํธ๋ก ์
๋ ฅ ๋ชจ๋ธ์ ๋ง๋ค๊ณ ํด๋น ๋น๋ฐ๋ฒํธ ์์ด ์ถ๋ ฅ ๋ชจ๋ธ์ ๋ง๋ค ์ ์์ต๋๋ค: |
|||
|
|||
```Python hl_lines="9 11 16" |
|||
{!../../../docs_src/response_model/tutorial003.py!} |
|||
``` |
|||
|
|||
์ฌ๊ธฐ์ *๊ฒฝ๋ก ๋์ ํจ์*๊ฐ ๋น๋ฐ๋ฒํธ๋ฅผ ํฌํจํ๋ ๋์ผํ ์
๋ ฅ ์ฌ์ฉ์๋ฅผ ๋ฐํํ ์ง๋ผ๋: |
|||
|
|||
```Python hl_lines="24" |
|||
{!../../../docs_src/response_model/tutorial003.py!} |
|||
``` |
|||
|
|||
...`response_model`์ `UserOut` ๋ชจ๋ธ๋ก ์ ์ธํ๊ธฐ ๋๋ฌธ์ ๋น๋ฐ๋ฒํธ๋ฅผ ํฌํจํ์ง ์์ต๋๋ค: |
|||
|
|||
```Python hl_lines="22" |
|||
{!../../../docs_src/response_model/tutorial003.py!} |
|||
``` |
|||
|
|||
๋ฐ๋ผ์ **FastAPI**๋ ์ถ๋ ฅ ๋ชจ๋ธ์์ ์ ์ธํ์ง ์์ ๋ชจ๋ ๋ฐ์ดํฐ๋ฅผ (Pydantic์ ์ฌ์ฉํ์ฌ) ํํฐ๋งํฉ๋๋ค. |
|||
|
|||
## ๋ฌธ์์์ ๋ณด๊ธฐ |
|||
|
|||
์๋ ์์ฑ ๋ฌธ์๋ฅผ ๋ณด๋ฉด ์
๋ ฅ ๋ชจ๋ธ๊ณผ ์ถ๋ ฅ ๋ชจ๋ธ์ด ๊ฐ์์ JSON ์คํค๋ง๋ฅผ ๊ฐ์ง๊ณ ์์์ ํ์ธํ ์ ์์ต๋๋ค: |
|||
|
|||
<img src="/img/tutorial/response-model/image01.png"> |
|||
|
|||
๊ทธ๋ฆฌ๊ณ ๋ ๋ชจ๋ธ ๋ชจ๋ ๋ํํ API ๋ฌธ์์ ์ฌ์ฉ๋ฉ๋๋ค: |
|||
|
|||
<img src="/img/tutorial/response-model/image02.png"> |
|||
|
|||
## ์๋ต ๋ชจ๋ธ ์ธ์ฝ๋ฉ ๋งค๊ฐ๋ณ์ |
|||
|
|||
์๋ต ๋ชจ๋ธ์ ์๋์ ๊ฐ์ด ๊ธฐ๋ณธ๊ฐ์ ๊ฐ์ง ์ ์์ต๋๋ค: |
|||
|
|||
```Python hl_lines="11 13-14" |
|||
{!../../../docs_src/response_model/tutorial004.py!} |
|||
``` |
|||
|
|||
* `description: Optional[str] = None`์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก `None`์ ๊ฐ์ต๋๋ค. |
|||
* `tax: float = 10.5`๋ ๊ธฐ๋ณธ๊ฐ์ผ๋ก `10.5`๋ฅผ ๊ฐ์ต๋๋ค. |
|||
* `tags: List[str] = []` ๋น ๋ฆฌ์คํธ์ ๊ธฐ๋ณธ๊ฐ์ผ๋ก: `[]`. |
|||
|
|||
๊ทธ๋ฌ๋ ์ค์ ๋ก ์ ์ฅ๋์ง ์์์ ๊ฒฝ์ฐ ๊ฒฐ๊ณผ์์ ๊ฐ์ ์๋ตํ๊ณ ์ถ์ ์ ์์ต๋๋ค. |
|||
|
|||
์๋ฅผ ๋ค์ด, NoSQL ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ๋ง์ ์ ํ์ ์์ฑ์ด ์๋ ๋ชจ๋ธ์ด ์์ง๋ง, ๊ธฐ๋ณธ๊ฐ์ผ๋ก ๊ฐ๋ ์ฐฌ ๋งค์ฐ ๊ธด JSON ์๋ต์ ๋ณด๋ด๊ณ ์ถ์ง ์์ต๋๋ค. |
|||
|
|||
### `response_model_exclude_unset` ๋งค๊ฐ๋ณ์ ์ฌ์ฉ |
|||
|
|||
*๊ฒฝ๋ก ๋์ ๋ฐ์ฝ๋ ์ดํฐ* ๋งค๊ฐ๋ณ์๋ฅผ `response_model_exclude_unset=True`๋ก ์ค์ ํ ์ ์์ต๋๋ค: |
|||
|
|||
```Python hl_lines="24" |
|||
{!../../../docs_src/response_model/tutorial004.py!} |
|||
``` |
|||
|
|||
์ด๋ฌํ ๊ธฐ๋ณธ๊ฐ์ ์๋ต์ ํฌํจ๋์ง ์๊ณ ์ค์ ๋ก ์ค์ ๋ ๊ฐ๋ง ํฌํจ๋ฉ๋๋ค. |
|||
|
|||
๋ฐ๋ผ์ ํด๋น *๊ฒฝ๋ก ๋์*์ ID๊ฐ `foo`์ธ ํญ๋ชฉ(items)์ ์์ฒญ์ผ๋ก ๋ณด๋ด๋ฉด (๊ธฐ๋ณธ๊ฐ์ ์ ์ธํ) ์๋ต์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: |
|||
|
|||
```JSON |
|||
{ |
|||
"name": "Foo", |
|||
"price": 50.2 |
|||
} |
|||
``` |
|||
|
|||
!!! info "์ ๋ณด" |
|||
FastAPI๋ ์ด๋ฅผ ์ํด Pydantic ๋ชจ๋ธ์ `.dict()`์ <a href="https://pydantic-docs.helpmanual.io/usage/exporting_models/#modeldict" class="external-link" target="_blank"> `exclude_unset` ๋งค๊ฐ๋ณ์</a>๋ฅผ ์ฌ์ฉํฉ๋๋ค. |
|||
|
|||
!!! info "์ ๋ณด" |
|||
์๋ ๋ํ ์ฌ์ฉํ ์ ์์ต๋๋ค: |
|||
|
|||
* `response_model_exclude_defaults=True` |
|||
* `response_model_exclude_none=True` |
|||
|
|||
<a href="https://pydantic-docs.helpmanual.io/usage/exporting_models/#modeldict" class="external-link" target="_blank">Pydantic ๋ฌธ์</a>์์ `exclude_defaults` ๋ฐ `exclude_none`์ ๋ํด ์ค๋ช
ํ ๋๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. |
|||
|
|||
#### ๊ธฐ๋ณธ๊ฐ์ด ์๋ ํ๋๋ฅผ ๊ฐ๋ ๊ฐ์ ๋ฐ์ดํฐ |
|||
|
|||
ํ์ง๋ง ๋ชจ๋ธ์ ํ๋๊ฐ ๊ธฐ๋ณธ๊ฐ์ด ์์ด๋ ID๊ฐ `bar`์ธ ํญ๋ชฉ(items)์ฒ๋ผ ๋ฐ์ดํฐ๊ฐ ๊ฐ์ ๊ฐ๋๋ค๋ฉด: |
|||
|
|||
```Python hl_lines="3 5" |
|||
{ |
|||
"name": "Bar", |
|||
"description": "The bartenders", |
|||
"price": 62, |
|||
"tax": 20.2 |
|||
} |
|||
``` |
|||
|
|||
์๋ต์ ํด๋น ๊ฐ๋ค์ด ํฌํจ๋ฉ๋๋ค. |
|||
|
|||
#### ๊ธฐ๋ณธ๊ฐ๊ณผ ๋์ผํ ๊ฐ์ ๊ฐ๋ ๋ฐ์ดํฐ |
|||
|
|||
If the data has the same values as the default ones, like the item with ID `baz`: |
|||
ID๊ฐ `baz`์ธ ํญ๋ชฉ(items)์ฒ๋ผ ๊ธฐ๋ณธ๊ฐ๊ณผ ๋์ผํ ๊ฐ์ ๊ฐ๋๋ค๋ฉด: |
|||
|
|||
```Python hl_lines="3 5-6" |
|||
{ |
|||
"name": "Baz", |
|||
"description": None, |
|||
"price": 50.2, |
|||
"tax": 10.5, |
|||
"tags": [] |
|||
} |
|||
``` |
|||
|
|||
`description`, `tax` ๊ทธ๋ฆฌ๊ณ `tags`๊ฐ ๊ธฐ๋ณธ๊ฐ๊ณผ ๊ฐ๋๋ผ๋ (๊ธฐ๋ณธ๊ฐ์์ ๊ฐ์ ธ์ค๋ ๋์ ) ๊ฐ๋ค์ด ๋ช
์์ ์ผ๋ก ์ค์ ๋์๋ค๋ ๊ฒ์ ์ธ์งํ ์ ๋๋ก FastAPI๋ ์ถฉ๋ถํ ๋๋ํฉ๋๋ค(์ฌ์ค, Pydantic์ด ์ถฉ๋ถํ ๋๋ํฉ๋๋ค). |
|||
|
|||
๋ฐ๋ผ์ JSON ์คํค๋ง์ ํฌํจ๋ฉ๋๋ค. |
|||
|
|||
!!! tip "ํ" |
|||
`None` ๋ฟ๋ง ์๋๋ผ ๋ค๋ฅธ ์ด๋ค ๊ฒ๋ ๊ธฐ๋ณธ๊ฐ์ด ๋ ์ ์์ต๋๋ค. |
|||
|
|||
๋ฆฌ์คํธ(`[]`), `float`์ธ `10.5` ๋ฑ์ด ๋ ์ ์์ต๋๋ค. |
|||
|
|||
### `response_model_include` ๋ฐ `response_model_exclude` |
|||
|
|||
*๊ฒฝ๋ก ๋์ ๋ฐ์ฝ๋ ์ดํฐ* ๋งค๊ฐ๋ณ์ `response_model_include` ๋ฐ `response_model_exclude`๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. |
|||
|
|||
์ด๋ค์ ํฌํจ(๋๋จธ์ง ์๋ต)ํ๊ฑฐ๋ ์ ์ธ(๋๋จธ์ง ํฌํจ) ํ ์ดํธ๋ฆฌ๋ทฐํธ์ ์ด๋ฆ๊ณผ `str`์ `set`์ ๋ฐ์ต๋๋ค. |
|||
|
|||
Pydantic ๋ชจ๋ธ์ด ํ๋๋ง ์๊ณ ์ถ๋ ฅ์์ โโ์ผ๋ถ ๋ฐ์ดํฐ๋ฅผ ์ ๊ฑฐํ๋ ค๋ ๊ฒฝ์ฐ ๋น ๋ฅธ ์ง๋ฆ๊ธธ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค. |
|||
|
|||
!!! tip "ํ" |
|||
ํ์ง๋ง ์ด๋ฌํ ๋งค๊ฐ๋ณ์ ๋์ ์ฌ๋ฌ ํด๋์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ ์์ด๋์ด๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ์ถ์ฒํฉ๋๋ค. |
|||
|
|||
์ด๋ ์ผ๋ถ ์ดํธ๋ฆฌ๋ทฐํธ๋ฅผ ์๋ตํ๊ธฐ ์ํด `response_model_include` ๋๋ `response_model_exclude`๋ฅผ ์ฌ์ฉํ๋๋ผ๋ ์ฑ์ OpenAPI(๋ฐ ๋ฌธ์)๊ฐ ์์ฑํ JSON ์คํค๋ง๊ฐ ์ฌ์ ํ ์ ์ฒด ๋ชจ๋ธ์ ๋ํ ์คํค๋ง์ด๊ธฐ ๋๋ฌธ์
๋๋ค. |
|||
|
|||
๋น์ทํ๊ฒ ์๋ํ๋ `response_model_by_alias` ์ญ์ ๋ง์ฐฌ๊ฐ์ง๋ก ์ ์ฉ๋ฉ๋๋ค. |
|||
|
|||
```Python hl_lines="31 37" |
|||
{!../../../docs_src/response_model/tutorial005.py!} |
|||
``` |
|||
|
|||
!!! tip "ํ" |
|||
๋ฌธ๋ฒ `{"name", "description"}`์ ๋ ๊ฐ์ ๊ฐ๋ `set`์ ๋ง๋ญ๋๋ค. |
|||
|
|||
์ด๋ `set(["name", "description"])`๊ณผ ๋์ผํฉ๋๋ค. |
|||
|
|||
#### `set` ๋์ `list` ์ฌ์ฉํ๊ธฐ |
|||
|
|||
`list` ๋๋ `tuple` ๋์ `set`์ ์ฌ์ฉํ๋ ๋ฒ์ ์์๋๋ผ๋, FastAPI๋ `set`์ผ๋ก ๋ณํํ๊ณ ์ ์์ ์ผ๋ก ์๋ํฉ๋๋ค: |
|||
|
|||
```Python hl_lines="31 37" |
|||
{!../../../docs_src/response_model/tutorial006.py!} |
|||
``` |
|||
|
|||
## ์์ฝ |
|||
|
|||
์๋ต ๋ชจ๋ธ์ ์ ์ํ๊ณ ๊ฐ์ธ์ ๋ณด๊ฐ ํํฐ๋๋ ๊ฒ์ ๋ณด์ฅํ๊ธฐ ์ํด *๊ฒฝ๋ก ๋์ ๋ฐ์ฝ๋ ์ดํฐ*์ ๋งค๊ฐ๋ณ์ `response_model`์ ์ฌ์ฉํ์ธ์. |
|||
|
|||
๋ช
์์ ์ผ๋ก ์ค์ ๋ ๊ฐ๋ง ๋ฐํํ๋ ค๋ฉด `response_model_exclude_unset`์ ์ฌ์ฉํ์ธ์. |
Loadingโฆ
Reference in new issue