Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
131 changes: 131 additions & 0 deletions docs/ko/docs/tutorial/metadata.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@

# 메타데이터 및 λ¬Έμ„œν™” URL

**FastAPI** μ‘μš© ν”„λ‘œκ·Έλž¨μ—μ„œ λ‹€μ–‘ν•œ 메타데이터 ꡬ성을 μ‚¬μš©μž 맞좀 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

## API에 λŒ€ν•œ 메타데이터

OpenAPI λͺ…μ„Έ 및 μžλ™ν™”λœ API λ¬Έμ„œ UI에 μ‚¬μš©λ˜λŠ” λ‹€μŒ ν•„λ“œλ₯Ό μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

| λ§€κ°œλ³€μˆ˜ | νƒ€μž… | μ„€λͺ… |
|----------|------|-------|
| `title` | `str` | API의 제λͺ©μž…λ‹ˆλ‹€. |
| `summary` | `str` | API에 λŒ€ν•œ 짧은 μš”μ•½μž…λ‹ˆλ‹€. <small>OpenAPI 3.1.0, FastAPI 0.99.0λΆ€ν„° μ‚¬μš© κ°€λŠ₯</small> |
| `description` | `str` | API에 λŒ€ν•œ 짧은 μ„€λͺ…μž…λ‹ˆλ‹€. λ§ˆν¬λ‹€μš΄μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. |
| `version` | `string` | API의 λ²„μ „μž…λ‹ˆλ‹€. OpenAPI의 버전이 μ•„λ‹Œ, μ—¬λŸ¬λΆ„μ˜ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 버전을 λ‚˜νƒ€λƒ…λ‹ˆλ‹€. 예: `2.5.0` |
| `terms_of_service` | `str` | API 이용 μ•½κ΄€μ˜ URLμž…λ‹ˆλ‹€. μ œκ³΅ν•˜λŠ” 경우 URL ν˜•μ‹μ΄μ–΄μ•Ό ν•©λ‹ˆλ‹€. |
| `contact` | `dict` | λ…ΈμΆœλœ API에 λŒ€ν•œ μ—°λ½μ²˜ μ •λ³΄μž…λ‹ˆλ‹€. μ—¬λŸ¬ ν•„λ“œλ₯Ό 포함할 수 μžˆμŠ΅λ‹ˆλ‹€. <details><summary><code>contact</code> ν•„λ“œ</summary><table><thead><tr><th>λ§€κ°œλ³€μˆ˜</th><th>νƒ€μž…</th><th>μ„€λͺ…</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td>μ—°λ½μ²˜ 인물/쑰직의 식별λͺ…μž…λ‹ˆλ‹€.</td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>μ—°λ½μ²˜ 정보가 λ‹΄κΈ΄ URLμž…λ‹ˆλ‹€. URL ν˜•μ‹μ΄μ–΄μ•Ό ν•©λ‹ˆλ‹€.</td></tr><tr><td><code>email</code></td><td><code>str</code></td><td>μ—°λ½μ²˜ 인물/쑰직의 이메일 μ£Όμ†Œμž…λ‹ˆλ‹€. 이메일 μ£Όμ†Œ ν˜•μ‹μ΄μ–΄μ•Ό ν•©λ‹ˆλ‹€.</td></tr></tbody></table></details> |
| `license_info` | `dict` | λ…ΈμΆœλœ API의 λΌμ΄μ„ μŠ€ μ •λ³΄μž…λ‹ˆλ‹€. μ—¬λŸ¬ ν•„λ“œλ₯Ό 포함할 수 μžˆμŠ΅λ‹ˆλ‹€. <details><summary><code>license_info</code> ν•„λ“œ</summary><table><thead><tr><th>λ§€κ°œλ³€μˆ˜</th><th>νƒ€μž…</th><th>μ„€λͺ…</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>str</code></td><td><strong>ν•„μˆ˜</strong> (<code>license_info</code>κ°€ μ„€μ •λœ 경우). API에 μ‚¬μš©λœ λΌμ΄μ„ μŠ€ μ΄λ¦„μž…λ‹ˆλ‹€.</td></tr><tr><td><code>identifier</code></td><td><code>str</code></td><td>API에 λŒ€ν•œ <a href="https://spdx.org/licenses/" class="external-link" target="_blank">SPDX</a> λΌμ΄μ„ μŠ€ ν‘œν˜„μž…λ‹ˆλ‹€. <code>identifier</code> ν•„λ“œλŠ” <code>url</code> ν•„λ“œμ™€ μƒν˜Έ λ°°νƒ€μ μž…λ‹ˆλ‹€. <small>OpenAPI 3.1.0, FastAPI 0.99.0λΆ€ν„° μ‚¬μš© κ°€λŠ₯</small></td></tr><tr><td><code>url</code></td><td><code>str</code></td><td>API에 μ‚¬μš©λœ λΌμ΄μ„ μŠ€μ˜ URLμž…λ‹ˆλ‹€. URL ν˜•μ‹μ΄μ–΄μ•Ό ν•©λ‹ˆλ‹€.</td></tr></tbody></table></details> |

λ‹€μŒκ³Ό 같이 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

```Python hl_lines="3-16 19-32"
{!../../docs_src/metadata/tutorial001.py!}
```

/// tip

`description` ν•„λ“œμ— λ§ˆν¬λ‹€μš΄μ„ μ‚¬μš©ν•  수 있으며, 좜λ ₯μ—μ„œ λ Œλ”λ§λ©λ‹ˆλ‹€.

///

이 ꡬ성을 μ‚¬μš©ν•˜λ©΄ λ¬Έμ„œ μžλ™ν™”(둜 μƒμ„±λœ) API λ¬Έμ„œλŠ” λ‹€μŒκ³Ό 같이 λ³΄μž…λ‹ˆλ‹€:

<img src="/img/tutorial/metadata/image01.png">

## λΌμ΄μ„ μŠ€ μ‹λ³„μž

OpenAPI 3.1.0 및 FastAPI 0.99.0λΆ€ν„° `license_info`에 `identifier`λ₯Ό URL λŒ€μ‹  μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

예:

```Python hl_lines="31"
{!../../docs_src/metadata/tutorial001_1.py!}
```

## νƒœκ·Έμ— λŒ€ν•œ 메타데이터

`openapi_tags` λ§€κ°œλ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜μ—¬ 경둜 μž‘λ™μ„ κ·Έλ£Ήν™”ν•˜λŠ” 데 μ‚¬μš©λ˜λŠ” νƒœκ·Έμ— μΆ”κ°€ 메타데이터λ₯Ό μΆ”κ°€ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

λ¦¬μŠ€νŠΈλŠ” 각 νƒœκ·Έμ— λŒ€ν•΄ ν•˜λ‚˜μ˜ λ”•μ…”λ„ˆλ¦¬λ₯Ό 포함해야 ν•©λ‹ˆλ‹€.

각 λ”•μ…”λ„ˆλ¦¬μ—λŠ” λ‹€μŒμ΄ 포함될 수 μžˆμŠ΅λ‹ˆλ‹€:

* `name` (**ν•„μˆ˜**): `tags` λ§€κ°œλ³€μˆ˜μ—μ„œ *경둜 μž‘λ™*κ³Ό `APIRouter`에 μ‚¬μš©λœ νƒœκ·Έ 이름과 λ™μΌν•œ `str`μž…λ‹ˆλ‹€.
* `description`: νƒœκ·Έμ— λŒ€ν•œ κ°„λ‹¨ν•œ μ„€λͺ…을 담은 `str`μž…λ‹ˆλ‹€. λ§ˆν¬λ‹€μš΄μ„ μ‚¬μš©ν•  수 있으며 λ¬Έμ„œ UI에 ν‘œμ‹œλ©λ‹ˆλ‹€.
* `externalDocs`: μ™ΈλΆ€ λ¬Έμ„œλ₯Ό μ„€λͺ…ν•˜λŠ” `dict`이며:
* `description`: μ™ΈλΆ€ λ¬Έμ„œμ— λŒ€ν•œ κ°„λ‹¨ν•œ μ„€λͺ…을 담은 `str`μž…λ‹ˆλ‹€.
* `url` (**ν•„μˆ˜**): μ™ΈλΆ€ λ¬Έμ„œμ˜ URL을 담은 `str`μž…λ‹ˆλ‹€.

### νƒœκ·Έμ— λŒ€ν•œ 메타데이터 생성

`users` 및 `items`에 λŒ€ν•œ νƒœκ·Έ μ˜ˆμ‹œμ™€ ν•¨κ»˜ 메타데이터λ₯Ό μƒμ„±ν•˜κ³  이λ₯Ό `openapi_tags` λ§€κ°œλ³€μˆ˜λ‘œ 전달해 λ³΄κ² μŠ΅λ‹ˆλ‹€:

```Python hl_lines="3-16 18"
{!../../docs_src/metadata/tutorial004.py!}
```

μ„€λͺ… μ•ˆμ— λ§ˆν¬λ‹€μš΄μ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ "login"은 ꡡ게(**login**) ν‘œμ‹œλ˜κ³ , "fancy"λŠ” κΈ°μšΈμž„κΌ΄(_fancy_)둜 ν‘œμ‹œλ©λ‹ˆλ‹€.

/// tip

μ‚¬μš© 쀑인 λͺ¨λ“  νƒœκ·Έμ— 메타데이터λ₯Ό μΆ”κ°€ν•  ν•„μš”λŠ” μ—†μŠ΅λ‹ˆλ‹€.

///

### νƒœκ·Έ μ‚¬μš©

`tags` λ§€κ°œλ³€μˆ˜λ₯Ό *경둜 μž‘λ™* 및 `APIRouter`와 ν•¨κ»˜ μ‚¬μš©ν•˜μ—¬ νƒœκ·Έμ— ν• λ‹Ήν•  수 μžˆμŠ΅λ‹ˆλ‹€:

```Python hl_lines="21 26"
{!../../docs_src/metadata/tutorial004.py!}
```

/// info

νƒœκ·Έμ— λŒ€ν•œ μžμ„Έν•œ λ‚΄μš©μ€ [경둜 μž‘λ™ ꡬ성](path-operation-configuration.md#tags){.internal-link target=_blank}μ—μ„œ μ½μ–΄λ³΄μ„Έμš”.

///

### λ¬Έμ„œ 확인

이제 λ¬Έμ„œλ₯Ό ν™•μΈν•˜λ©΄ λͺ¨λ“  μΆ”κ°€ 메타데이터가 ν‘œμ‹œλ©λ‹ˆλ‹€:

<img src="/img/tutorial/metadata/image02.png">

### νƒœκ·Έ μˆœμ„œ

각 νƒœκ·Έ 메타데이터 λ”•μ…”λ„ˆλ¦¬μ˜ μˆœμ„œλŠ” λ¬Έμ„œ UI에 ν‘œμ‹œλ˜λŠ” μˆœμ„œλ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, μ•ŒνŒŒλ²³ μˆœμ„œμƒ `users`λŠ” `items` 뒀에 μ˜€μ§€λ§Œ, μš°λ¦¬λŠ” `users` 메타데이터λ₯Ό 리슀트의 첫 번째 λ”•μ…”λ„ˆλ¦¬λ‘œ μΆ”κ°€ν–ˆκΈ° λ•Œλ¬Έμ— λ¨Όμ € ν‘œμ‹œλ©λ‹ˆλ‹€.

## OpenAPI URL

OpenAPI κ΅¬μ‘°λŠ” 기본적으둜 `/openapi.json`μ—μ„œ μ œκ³΅λ©λ‹ˆλ‹€.

`openapi_url` λ§€κ°œλ³€μˆ˜λ₯Ό 톡해 이λ₯Ό μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, 이λ₯Ό `/api/v1/openapi.json`에 μ œκ³΅ν•˜λ„λ‘ μ„€μ •ν•˜λ €λ©΄:

```Python hl_lines="3"
{!../../docs_src/metadata/tutorial002.py!}
```

OpenAPI ꡬ쑰λ₯Ό μ™„μ „νžˆ λΉ„ν™œμ„±ν™”ν•˜λ €λ©΄ `openapi_url=None`으둜 μ„€μ •ν•  수 있으며, 이λ₯Ό μ‚¬μš©ν•˜μ—¬ λ¬Έμ„œν™” μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€λ„ λΉ„ν™œμ„±ν™”λ©λ‹ˆλ‹€.

## λ¬Έμ„œν™” URL

ν¬ν•¨λœ 두 κ°€μ§€ λ¬Έμ„œν™” μ‚¬μš©μž μΈν„°νŽ˜μ΄μŠ€λ₯Ό μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€:

* **Swagger UI**: `/docs`μ—μ„œ μ œκ³΅λ©λ‹ˆλ‹€.
* `docs_url` λ§€κ°œλ³€μˆ˜λ‘œ URL을 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
* `docs_url=None`으둜 μ„€μ •ν•˜μ—¬ λΉ„ν™œμ„±ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
* **ReDoc**: `/redoc`μ—μ„œ μ œκ³΅λ©λ‹ˆλ‹€.
* `redoc_url` λ§€κ°œλ³€μˆ˜λ‘œ URL을 μ„€μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
* `redoc_url=None`으둜 μ„€μ •ν•˜μ—¬ λΉ„ν™œμ„±ν™”ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄, Swagger UIλ₯Ό `/documentation`μ—μ„œ μ œκ³΅ν•˜κ³  ReDoc을 λΉ„ν™œμ„±ν™”ν•˜λ €λ©΄:

```Python hl_lines="3"
{!../../docs_src/metadata/tutorial003.py!}
```