Browse Source

๐ŸŒ Add Korean translation for `/docs/ko/docs/tutorial/schema-extra-example.md` (#11121)

pull/11126/head
Kani Kim 1 year ago
committed by GitHub
parent
commit
383870a275
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 326
      docs/ko/docs/tutorial/schema-extra-example.md

326
docs/ko/docs/tutorial/schema-extra-example.md

@ -0,0 +1,326 @@
# ์š”์ฒญ ์˜ˆ์ œ ๋ฐ์ดํ„ฐ ์„ ์–ธ
์—ฌ๋Ÿฌ๋ถ„์˜ ์•ฑ์ด ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ๋ฐ์ดํ„ฐ ์˜ˆ์ œ๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๊ธฐ ์ด๋ฅผ ์œ„ํ•œ ๋ช‡๊ฐ€์ง€ ๋ฐฉ์‹์ด ์žˆ์Šต๋‹ˆ๋‹ค.
## Pydantic ๋ชจ๋ธ ์† ์ถ”๊ฐ€ JSON ์Šคํ‚ค๋งˆ ๋ฐ์ดํ„ฐ
์ƒ์„ฑ๋œ JSON ์Šคํ‚ค๋งˆ์— ์ถ”๊ฐ€๋  Pydantic ๋ชจ๋ธ์„ ์œ„ํ•œ `examples`์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
=== "Python 3.10+ Pydantic v2"
```Python hl_lines="13-24"
{!> ../../../docs_src/schema_extra_example/tutorial001_py310.py!}
```
=== "Python 3.10+ Pydantic v1"
```Python hl_lines="13-23"
{!> ../../../docs_src/schema_extra_example/tutorial001_py310_pv1.py!}
```
=== "Python 3.8+ Pydantic v2"
```Python hl_lines="15-26"
{!> ../../../docs_src/schema_extra_example/tutorial001.py!}
```
=== "Python 3.8+ Pydantic v1"
```Python hl_lines="15-25"
{!> ../../../docs_src/schema_extra_example/tutorial001_pv1.py!}
```
์ถ”๊ฐ€ ์ •๋ณด๋Š” ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ํ•ด๋‹น ๋ชจ๋ธ์˜ **JSON ์Šคํ‚ค๋งˆ** ๊ฒฐ๊ณผ์— ์ถ”๊ฐ€๋˜๊ณ , API ๋ฌธ์„œ์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
=== "Pydantic v2"
Pydantic ๋ฒ„์ „ 2์—์„œ <a href="https://docs.pydantic.dev/latest/usage/model_config/" class="external-link" target="_blank">Pydantic ๊ณต์‹ ๋ฌธ์„œ: Model Config</a>์— ๋‚˜์™€ ์žˆ๋Š” ๊ฒƒ์ฒ˜๋Ÿผ `dict`๋ฅผ ๋ฐ›๋Š” `model_config` ์–ดํŠธ๋ฆฌ๋ทฐํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
`"json_schema_extra"`๋ฅผ ์ƒ์„ฑ๋œ JSON ์Šคํ‚ค๋งˆ์—์„œ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ ๋ณ„๋„์˜ ๋ฐ์ดํ„ฐ์™€ `examples`๋ฅผ ํฌํ•จํ•˜๋Š” `dict`์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
=== "Pydantic v1"
Pydantic v1์—์„œ <a href="https://docs.pydantic.dev/1.10/usage/schema/#schema-customization" class="external-link" target="_blank">Pydantic ๊ณต์‹ ๋ฌธ์„œ: Schema customization</a>์—์„œ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ, ๋‚ด๋ถ€ ํด๋ž˜์Šค์ธ `Config`์™€ `schema_extra`๋ฅผ ์‚ฌ์šฉํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
`schema_extra`๋ฅผ ์ƒ์„ฑ๋œ JSON ์Šคํ‚ค๋งˆ์—์„œ ๋ณด์—ฌ์ฃผ๊ณ  ์‹ถ์€ ๋ณ„๋„์˜ ๋ฐ์ดํ„ฐ์™€ `examples`๋ฅผ ํฌํ•จํ•˜๋Š” `dict`์œผ๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
!!! tip "ํŒ"
JSON ์Šคํ‚ค๋งˆ๋ฅผ ํ™•์žฅํ•˜๊ณ  ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ณ„๋„์˜ ์ž์ฒด ๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ™์€ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค๋ฉด, ํ”„๋ก ํŠธ์—”๋“œ ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์— ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋“ฑ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
!!! info "์ •๋ณด"
(FastAPI 0.99.0๋ถ€ํ„ฐ ์“ฐ์ด๊ธฐ ์‹œ์ž‘ํ•œ) OpenAPI 3.1.0์€ **JSON ์Šคํ‚ค๋งˆ** ํ‘œ์ค€์˜ ์ผ๋ถ€์ธ `examples`์— ๋Œ€ํ•œ ์ง€์›์„ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ ์ „์—๋Š”, ํ•˜๋‚˜์˜ ์˜ˆ์ œ๋งŒ ๊ฐ€๋Šฅํ•œ `example` ํ‚ค์›Œ๋“œ๋งŒ ์ง€์›ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ์•„์ง OpenAPI 3.1.0์—์„œ ์ง€์›ํ•˜์ง€๋งŒ, ์ง€์›์ด ์ข…๋ฃŒ๋  ๊ฒƒ์ด๋ฉฐ JSON ์Šคํ‚ค๋งˆ ํ‘œ์ค€์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ์— `example`์„ `examples`์œผ๋กœ ์ด์ „ํ•˜๋Š” ๊ฒƒ์„ ์ถ”์ฒœํ•ฉ๋‹ˆ๋‹ค. ๐Ÿค“
์ด ๋ฌธ์„œ ๋์— ๋” ๋งŽ์€ ์ฝ์„๊ฑฐ๋ฆฌ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
## `Field` ์ถ”๊ฐ€ ์ธ์ž
Pydantic ๋ชจ๋ธ๊ณผ ๊ฐ™์ด `Field()`๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ์ถ”๊ฐ€์ ์ธ `examples`๋ฅผ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
=== "Python 3.10+"
```Python hl_lines="2 8-11"
{!> ../../../docs_src/schema_extra_example/tutorial002_py310.py!}
```
=== "Python 3.8+"
```Python hl_lines="4 10-13"
{!> ../../../docs_src/schema_extra_example/tutorial002.py!}
```
## JSON Schema์—์„œ์˜ `examples` - OpenAPI
์ด๋“ค ์ค‘์—์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค:
* `Path()`
* `Query()`
* `Header()`
* `Cookie()`
* `Body()`
* `Form()`
* `File()`
**OpenAPI**์˜ **JSON ์Šคํ‚ค๋งˆ**์— ์ถ”๊ฐ€๋  ๋ถ€๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ํฌํ•จํ•œ `examples` ๋ชจ์Œ์„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
### `examples`๋ฅผ ํฌํ•จํ•œ `Body`
์—ฌ๊ธฐ, `Body()`์— ์˜ˆ์ƒ๋˜๋Š” ์˜ˆ์ œ ๋ฐ์ดํ„ฐ ํ•˜๋‚˜๋ฅผ ํฌํ•จํ•œ `examples`๋ฅผ ๋„˜๊ฒผ์Šต๋‹ˆ๋‹ค:
=== "Python 3.10+"
```Python hl_lines="22-29"
{!> ../../../docs_src/schema_extra_example/tutorial003_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="22-29"
{!> ../../../docs_src/schema_extra_example/tutorial003_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="23-30"
{!> ../../../docs_src/schema_extra_example/tutorial003_an.py!}
```
=== "Python 3.10+ Annotated๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ"
!!! tip "ํŒ"
๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด `Annotated`๊ฐ€ ๋‹ฌ๋ฆฐ ๋ฒ„์ „์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
```Python hl_lines="18-25"
{!> ../../../docs_src/schema_extra_example/tutorial003_py310.py!}
```
=== "Python 3.8+ Annotated๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ"
!!! tip "ํŒ"
๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด `Annotated`๊ฐ€ ๋‹ฌ๋ฆฐ ๋ฒ„์ „์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
```Python hl_lines="20-27"
{!> ../../../docs_src/schema_extra_example/tutorial003.py!}
```
### ๋ฌธ์„œ UI ์˜ˆ์‹œ
์œ„์˜ ์–ด๋Š ๋ฐฉ๋ฒ•๊ณผ ํ•จ๊ป˜๋ผ๋ฉด `/docs`์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:
<img src="/img/tutorial/body-fields/image01.png">
### ๋‹ค์ค‘ `examples`๋ฅผ ํฌํ•จํ•œ `Body`
๋ฌผ๋ก  ์—ฌ๋Ÿฌ `examples`๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
=== "Python 3.10+"
```Python hl_lines="23-38"
{!> ../../../docs_src/schema_extra_example/tutorial004_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="23-38"
{!> ../../../docs_src/schema_extra_example/tutorial004_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="24-39"
{!> ../../../docs_src/schema_extra_example/tutorial004_an.py!}
```
=== "Python 3.10+ Annotated๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ"
!!! tip "ํŒ"
๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด `Annotated`๊ฐ€ ๋‹ฌ๋ฆฐ ๋ฒ„์ „์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
```Python hl_lines="19-34"
{!> ../../../docs_src/schema_extra_example/tutorial004_py310.py!}
```
=== "Python 3.8+ Annotated๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ"
!!! tip "ํŒ"
๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด `Annotated`๊ฐ€ ๋‹ฌ๋ฆฐ ๋ฒ„์ „์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
```Python hl_lines="21-36"
{!> ../../../docs_src/schema_extra_example/tutorial004.py!}
```
์ด์™€ ๊ฐ™์ด ํ•˜๋ฉด ์ด ์˜ˆ์ œ๋Š” ๊ทธ ๋ณธ๋ฌธ ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ๋‚ด๋ถ€ **JSON ์Šคํ‚ค๋งˆ**์˜ ์ผ๋ถ€๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ , ์ง€๊ธˆ <abbr title="2023-08-26">์ด ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์‹œ๊ฐ„</abbr>์—, ๋ฌธ์„œ UI๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ์—ญํ• ์„ ๋งก์€ Swagger UI๋Š” **JSON ์Šคํ‚ค๋งˆ** ์† ๋ฐ์ดํ„ฐ๋ฅผ ์œ„ํ•œ ์—ฌ๋Ÿฌ ์˜ˆ์ œ์˜ ํ‘œํ˜„์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ํ•ด๊ฒฐ ๋ฐฉ์•ˆ์„ ๋ฐ‘์—์„œ ์ฝ์–ด๋ณด์„ธ์š”.
### OpenAPI-ํŠนํ™” `examples`
**JSON ์Šคํ‚ค๋งˆ**๊ฐ€ `examples`๋ฅผ ์ง€์›ํ•˜๊ธฐ ์ „ ๋ถ€ํ„ฐ, OpenAPI๋Š” `examples`์ด๋ผ ๋ถˆ๋ฆฌ๋Š” ๋‹ค๋ฅธ ํ•„๋“œ๋ฅผ ์ง€์›ํ•ด ์™”์Šต๋‹ˆ๋‹ค.
์ด **OpenAPI-ํŠนํ™”** `examples`๋Š” OpenAPI ๋ช…์„ธ์„œ์˜ ๋‹ค๋ฅธ ๊ตฌ์—ญ์œผ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. ๊ฐ JSON ์Šคํ‚ค๋งˆ ๋‚ด๋ถ€๊ฐ€ ์•„๋‹ˆ๋ผ **๊ฐ *๊ฒฝ๋กœ ์ž‘๋™* ์„ธ๋ถ€ ์ •๋ณด**์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  Swagger UI๋Š” ์ด ํŠน์ •ํ•œ `examples` ํ•„๋“œ๋ฅผ ํ•œ๋™์•ˆ ์ง€์›ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ, ์ด๋ฅผ ๋‹ค๋ฅธ **๋ฌธ์„œ UI์— ์žˆ๋Š” ์˜ˆ์ œ**๋ฅผ **ํ‘œ์‹œ**ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด OpenAPI-ํŠนํ™” ํ•„๋“œ์ธ `examples`์˜ ํ˜•ํƒœ๋Š” (`list`๋Œ€์‹ ์—) **๋‹ค์ค‘ ์˜ˆ์ œ**๊ฐ€ ํฌํ•จ๋œ `dict`์ด๋ฉฐ, ๊ฐ๊ฐ์˜ ๋ณ„๋„ ์ •๋ณด ๋˜ํ•œ **OpenAPI**์— ์ถ”๊ฐ€๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด๋Š” OpenAPI์— ํฌํ•จ๋œ JSON ์Šคํ‚ค๋งˆ ์•ˆ์œผ๋กœ ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฉฐ, *๊ฒฝ๋กœ ์ž‘๋™*์— ์ง์ ‘์ ์œผ๋กœ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
### `openapi_examples` ๋งค๊ฐœ๋ณ€์ˆ˜ ์‚ฌ์šฉํ•˜๊ธฐ
๋‹ค์Œ ์˜ˆ์‹œ ์†์— OpenAPI-ํŠนํ™” `examples`๋ฅผ FastAPI ์•ˆ์—์„œ ๋งค๊ฐœ๋ณ€์ˆ˜ `openapi_examples` ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ํ•จ๊ป˜ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* `Path()`
* `Query()`
* `Header()`
* `Cookie()`
* `Body()`
* `Form()`
* `File()`
`dict`์˜ ํ‚ค๊ฐ€ ๋˜ ๋‹ค๋ฅธ `dict`์ธ ๊ฐ ์˜ˆ์ œ์™€ ๊ฐ’์„ ๊ตฌ๋ณ„ํ•ฉ๋‹ˆ๋‹ค.
๊ฐ๊ฐ์˜ ํŠน์ • `examples` ์† `dict` ์˜ˆ์ œ๋Š” ๋‹ค์Œ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* `summary`: ์˜ˆ์ œ์— ๋Œ€ํ•œ ์งง์€ ์„ค๋ช…๋ฌธ.
* `description`: ๋งˆํฌ๋‹ค์šด ํ…์ŠคํŠธ๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” ๊ธด ์„ค๋ช…๋ฌธ.
* `value`: ์‹ค์ œ๋กœ ๋ณด์—ฌ์ง€๋Š” ์˜ˆ์‹œ, ์˜ˆ๋ฅผ ๋“ค๋ฉด `dict`.
* `externalValue`: `value`์˜ ๋Œ€์•ˆ์ด๋ฉฐ ์˜ˆ์ œ๋ฅผ ๊ฐ€๋ฅดํ‚ค๋Š” URL. ๋น„๋ก `value`์ฒ˜๋Ÿผ ๋งŽ์€ ๋„๊ตฌ๋ฅผ ์ง€์›ํ•˜์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
=== "Python 3.10+"
```Python hl_lines="23-49"
{!> ../../../docs_src/schema_extra_example/tutorial005_an_py310.py!}
```
=== "Python 3.9+"
```Python hl_lines="23-49"
{!> ../../../docs_src/schema_extra_example/tutorial005_an_py39.py!}
```
=== "Python 3.8+"
```Python hl_lines="24-50"
{!> ../../../docs_src/schema_extra_example/tutorial005_an.py!}
```
=== "Python 3.10+ Annotated๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ"
!!! tip "ํŒ"
๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด `Annotated`๊ฐ€ ๋‹ฌ๋ฆฐ ๋ฒ„์ „์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
```Python hl_lines="19-45"
{!> ../../../docs_src/schema_extra_example/tutorial005_py310.py!}
```
=== "Python 3.8+ Annotated๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ"
!!! tip "ํŒ"
๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด `Annotated`๊ฐ€ ๋‹ฌ๋ฆฐ ๋ฒ„์ „์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
```Python hl_lines="21-47"
{!> ../../../docs_src/schema_extra_example/tutorial005.py!}
```
### ๋ฌธ์„œ UI์—์„œ์˜ OpenAPI ์˜ˆ์‹œ
`Body()`์— ์ถ”๊ฐ€๋œ `openapi_examples`๋ฅผ ํฌํ•จํ•œ `/docs`๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:
<img src="/img/tutorial/body-fields/image02.png">
## ๊ธฐ์ˆ ์  ์„ธ๋ถ€ ์‚ฌํ•ญ
!!! tip "ํŒ"
์ด๋ฏธ **FastAPI**์˜ **0.99.0 ํ˜น์€ ๊ทธ ์ด์ƒ** ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค๋ฉด, ์ด ์„ธ๋ถ€ ์‚ฌํ•ญ์„ **์Šคํ‚ต**ํ•ด๋„ ์ƒ๊ด€ ์—†์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์„ธ๋ถ€ ์‚ฌํ•ญ์€ OpenAPI 3.1.0์ด ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๊ธฐ ์ „, ์˜ˆ์ „ ๋ฒ„์ „๊ณผ ๋” ๊ด€๋ จ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฐ„๋žตํ•œ OpenAPI์™€ JSON ์Šคํ‚ค๋งˆ **์—ญ์‚ฌ ๊ฐ•์˜**๋กœ ์ƒ๊ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿค“
!!! warning "๊ฒฝ๊ณ "
ํ‘œ์ค€ **JSON ์Šคํ‚ค๋งˆ**์™€ **OpenAPI**์— ๋Œ€ํ•œ ์•„์ฃผ ๊ธฐ์ˆ ์ ์ธ ์„ธ๋ถ€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.
๋งŒ์•ฝ ์œ„์˜ ์ƒ๊ฐ์ด ์ž‘๋™ํ•œ๋‹ค๋ฉด, ๊ทธ๊ฒƒ์œผ๋กœ ์ถฉ๋ถ„ํ•˜๋ฉฐ ์ด ์„ธ๋ถ€ ์‚ฌํ•ญ์€ ํ•„์š”์—†์„ ๊ฒƒ์ด๋‹ˆ, ๋งˆ์Œ ํŽธํ•˜๊ฒŒ ์Šคํ‚ตํ•˜์…”๋„ ๋ฉ๋‹ˆ๋‹ค.
OpenAPI 3.1.0 ์ „์— OpenAPI๋Š” ์˜ค๋ž˜๋œ **JSON ์Šคํ‚ค๋งˆ**์˜ ์ˆ˜์ •๋œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
JSON ์Šคํ‚ค๋งˆ๋Š” `examples`๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์•˜๊ณ , ๋”ฐ๋ผ์„œ OpenAPI๋Š” ๊ทธ๋“ค๋งŒ์˜ `example` ํ•„๋“œ๋ฅผ ์ˆ˜์ •๋œ ๋ฒ„์ „์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
OpenAPI๋Š” ๋˜ํ•œ `example`๊ณผ `examples` ํ•„๋“œ๋ฅผ ๋ช…์„ธ์„œ์˜ ๋‹ค๋ฅธ ๋ถ€๋ถ„์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค:
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#parameter-object" class="external-link" target="_blank">`(๋ช…์„ธ์„œ์— ์žˆ๋Š”) Parameter Object`</a>๋Š” FastAPI์˜ ๋‹ค์Œ ๊ธฐ๋Šฅ์—์„œ ์“ฐ์˜€์Šต๋‹ˆ๋‹ค:
* `Path()`
* `Query()`
* `Header()`
* `Cookie()`
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object" class="external-link" target="_blank">(๋ช…์„ธ์„œ์— ์žˆ๋Š”)`Media Type Object`์† `content`์— ์žˆ๋Š” `Request Body Object`</a>๋Š” FastAPI์˜ ๋‹ค์Œ ๊ธฐ๋Šฅ์—์„œ ์“ฐ์˜€์Šต๋‹ˆ๋‹ค:
* `Body()`
* `File()`
* `Form()`
!!! info "์ •๋ณด"
์ด ์˜ˆ์ „ OpenAPI-ํŠนํ™” `examples` ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์ด์ œ FastAPI `0.103.0`๋ถ€ํ„ฐ `openapi_examples`์ž…๋‹ˆ๋‹ค.
### JSON ์Šคํ‚ค๋งˆ์˜ `examples` ํ•„๋“œ
ํ•˜์ง€๋งŒ, ํ›„์— JSON ์Šคํ‚ค๋งˆ๋Š” <a href="https://json-schema.org/draft/2019-09/json-schema-validation.html#rfc.section.9.5" class="external-link" target="_blank">`examples`</a>ํ•„๋“œ๋ฅผ ๋ช…์„ธ์„œ์˜ ์ƒˆ ๋ฒ„์ „์— ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ƒˆ๋กœ์šด OpenAPI 3.1.0์€ ์ด ์ƒˆ๋กœ์šด `examples` ํ•„๋“œ๊ฐ€ ํฌํ•จ๋œ ์ตœ์‹  ๋ฒ„์ „ (JSON ์Šคํ‚ค๋งˆ 2020-12)์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค.
์ด์ œ ์ƒˆ๋กœ์šด `examples` ํ•„๋“œ๋Š” ์ด์ „์˜ ๋‹จ์ผ (๊ทธ๋ฆฌ๊ณ  ์ปค์Šคํ…€) `example` ํ•„๋“œ๋ณด๋‹ค ์šฐ์„ ๋˜๋ฉฐ, `example`์€ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.
JSON ์Šคํ‚ค๋งˆ์˜ ์ƒˆ๋กœ์šด `examples` ํ•„๋“œ๋Š” ์˜ˆ์ œ ์† **๋‹จ์ˆœํ•œ `list`**์ด๋ฉฐ, (์œ„์—์„œ ์ƒ์ˆ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ) OpenAPI์˜ ๋‹ค๋ฅธ ๊ณณ์— ์กด์žฌํ•˜๋Š” dict์œผ๋กœ ๋œ ์ถ”๊ฐ€์ ์ธ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.
!!! info "์ •๋ณด"
๋” ์‰ฝ๊ณ  ์ƒˆ๋กœ์šด JSON ์Šคํ‚ค๋งˆ์™€์˜ ํ†ตํ•ฉ๊ณผ ํ•จ๊ป˜ OpenAPI 3.1.0๊ฐ€ ๋ฐฐํฌ๋˜์—ˆ์ง€๋งŒ, ์ž ์‹œ๋™์•ˆ ์ž๋™ ๋ฌธ์„œ ์ƒ์„ฑ์„ ์ œ๊ณตํ•˜๋Š” ๋„๊ตฌ์ธ Swagger UI๋Š” OpenAPI 3.1.0์„ ์ง€์›ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค (5.0.0 ๋ฒ„์ „๋ถ€ํ„ฐ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค ๐ŸŽ‰).
์ด๋กœ์ธํ•ด, FastAPI 0.99.0 ์ด์ „ ๋ฒ„์ „์€ ์•„์ง OpenAPI 3.1.0 ๋ณด๋‹ค ๋‚ฎ์€ ๋ฒ„์ „์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.
### Pydantic๊ณผ FastAPI `examples`
`examples`๋ฅผ Pydantic ๋ชจ๋ธ ์†์— ์ถ”๊ฐ€ํ•  ๋•Œ, `schema_extra` ํ˜น์€ `Field(examples=["something"])`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Pydantic ๋ชจ๋ธ์˜ **JSON ์Šคํ‚ค๋งˆ**์— ํ•ด๋‹น ์˜ˆ์‹œ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  Pydantic ๋ชจ๋ธ์˜ **JSON ์Šคํ‚ค๋งˆ**๋Š” API์˜ **OpenAPI**์— ํฌํ•จ๋˜๊ณ , ๊ทธ ํ›„ ๋ฌธ์„œ UI ์†์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
FastAPI 0.99.0 ์ด์ „ ๋ฒ„์ „์—์„œ (0.99.0 ์ด์ƒ ๋ฒ„์ „์€ ์ƒˆ๋กœ์šด OpenAPI 3.1.0์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค), `example` ํ˜น์€ `examples`๋ฅผ ๋‹ค๋ฅธ ์œ ํ‹ธ๋ฆฌํ‹ฐ(`Query()`, `Body()` ๋“ฑ)์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ–ˆ์„ ๋•Œ, ์ €๋Ÿฌํ•œ ์˜ˆ์‹œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์„ค๋ช…ํ•˜๋Š” JSON ์Šคํ‚ค๋งˆ์— ์ถ”๊ฐ€๋˜์ง€ ์•Š์œผ๋ฉฐ (์‹ฌ์ง€์–ด OpenAPI์˜ ์ž์ฒด JSON ์Šคํ‚ค๋งˆ์—๋„ ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค), OpenAPI์˜ *๊ฒฝ๋กœ ์ž‘๋™* ์„ ์–ธ์— ์ง์ ‘์ ์œผ๋กœ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค (JSON ์Šคํ‚ค๋งˆ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” OpenAPI ๋ถ€๋ถ„ ์™ธ์—๋„).
ํ•˜์ง€๋งŒ ์ง€๊ธˆ์€ FastAPI 0.99.0 ๋ฐ ์ดํ›„ ๋ฒ„์ „์—์„œ๋Š” JSON ์Šคํ‚ค๋งˆ 2020-12๋ฅผ ์‚ฌ์šฉํ•˜๋Š” OpenAPI 3.1.0๊ณผ Swagger UI 5.0.0 ๋ฐ ์ดํ›„ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๋ชจ๋“  ๊ฒƒ์ด ๋” ์ผ๊ด€์„ฑ์„ ๋„๊ณ  ์˜ˆ์‹œ๋Š” JSON ์Šคํ‚ค๋งˆ์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
### Swagger UI์™€ OpenAPI-ํŠนํ™” `examples`
ํ˜„์žฌ (2023-08-26), Swagger UI๊ฐ€ ๋‹ค์ค‘ JSON ์Šคํ‚ค๋งˆ ์˜ˆ์‹œ๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ์‚ฌ์šฉ์ž๋Š” ๋‹ค์ค‘ ์˜ˆ์‹œ๋ฅผ ๋ฌธ์„œ์— ํ‘œ์‹œํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์—†์—ˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด, FastAPI `0.103.0`์€ ์ƒˆ๋กœ์šด ๋งค๊ฐœ๋ณ€์ˆ˜์ธ `openapi_examples`๋ฅผ ํฌํ•จํ•˜๋Š” ์˜ˆ์ „ **OpenAPI-ํŠนํ™”** `examples` ํ•„๋“œ๋ฅผ ์„ ์–ธํ•˜๊ธฐ ์œ„ํ•œ **์ง€์›์„ ์ถ”๊ฐ€**ํ–ˆ์Šต๋‹ˆ๋‹ค. ๐Ÿค“
### ์š”์•ฝ
์ €๋Š” ์—ญ์‚ฌ๋ฅผ ๊ทธ๋‹ค์ง€ ์ข‹์•„ํ•˜๋Š” ํŽธ์ด ์•„๋‹ˆ๋ผ๊ณ  ๋งํ•˜๊ณ ๋Š” ํ–ˆ์ง€๋งŒ... "๊ธฐ์ˆ  ์—ญ์‚ฌ" ๊ฐ•์˜๋ฅผ ๊ฐ€๋ฅด์น˜๋Š” ์ง€๊ธˆ์˜ ์ €๋ฅผ ๋ณด์„ธ์š”.
์š”์•ฝํ•˜์ž๋ฉด **FastAPI 0.99.0 ํ˜น์€ ๊ทธ ์ด์ƒ์˜ ๋ฒ„์ „**์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ๊ฒƒ์€ ๋งŽ์€ ๊ฒƒ๋“ค์ด ๋” **์‰ฝ๊ณ , ์ผ๊ด€์ ์ด๋ฉฐ ์ง๊ด€์ ์ด๊ฒŒ** ๋˜๋ฉฐ, ์—ฌ๋Ÿฌ๋ถ„์€ ์ด ๋ชจ๋“  ์—ญ์‚ฌ์  ์„ธ๋ถ€ ์‚ฌํ•ญ์„ ์•Œ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ๐Ÿ˜Ž
Loadingโ€ฆ
Cancel
Save