Browse Source

๐ŸŒ Update translations for ko (update-outdated)

pull/15170/head
github-actions[bot] 4 months ago
committed by Yurii Motov
parent
commit
0987cdfc1a
  1. 4
      docs/ko/docs/advanced/additional-responses.md
  2. 2
      docs/ko/docs/advanced/additional-status-codes.md
  3. 4
      docs/ko/docs/advanced/advanced-dependencies.md
  4. 8
      docs/ko/docs/advanced/async-tests.md
  5. 34
      docs/ko/docs/advanced/behind-a-proxy.md
  6. 152
      docs/ko/docs/advanced/custom-response.md
  7. 8
      docs/ko/docs/advanced/dataclasses.md
  8. 6
      docs/ko/docs/advanced/events.md
  9. 32
      docs/ko/docs/advanced/generate-clients.md
  10. 4
      docs/ko/docs/advanced/index.md
  11. 10
      docs/ko/docs/advanced/middleware.md
  12. 10
      docs/ko/docs/advanced/openapi-callbacks.md
  13. 2
      docs/ko/docs/advanced/openapi-webhooks.md
  14. 6
      docs/ko/docs/advanced/path-operation-advanced-configuration.md
  15. 2
      docs/ko/docs/advanced/response-change-status-code.md
  16. 6
      docs/ko/docs/advanced/response-cookies.md
  17. 34
      docs/ko/docs/advanced/response-directly.md
  18. 6
      docs/ko/docs/advanced/response-headers.md
  19. 4
      docs/ko/docs/advanced/security/http-basic-auth.md
  20. 4
      docs/ko/docs/advanced/security/index.md
  21. 16
      docs/ko/docs/advanced/settings.md
  22. 34
      docs/ko/docs/advanced/sub-applications.md
  23. 4
      docs/ko/docs/advanced/templates.md
  24. 4
      docs/ko/docs/advanced/testing-websockets.md
  25. 4
      docs/ko/docs/advanced/using-request-directly.md
  26. 24
      docs/ko/docs/advanced/websockets.md
  27. 6
      docs/ko/docs/advanced/wsgi.md
  28. 8
      docs/ko/docs/how-to/custom-request-and-route.md
  29. 4
      docs/ko/docs/tutorial/metadata.md

4
docs/ko/docs/advanced/additional-responses.md

@ -243,5 +243,5 @@ new_dict = {**old_dict, "new key": "new value"}
์‘๋‹ต์— ์ •ํ™•ํžˆ ๋ฌด์—‡์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ๋ณด๋ ค๋ฉด, OpenAPI ์‚ฌ์–‘์˜ ๋‹ค์Œ ์„น์…˜์„ ํ™•์ธํ•˜์„ธ์š”:
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object" class="external-link" target="_blank">OpenAPI Responses Object</a>: `Response Object`๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
* <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object" class="external-link" target="_blank">OpenAPI Response Object</a>: `responses` ํŒŒ๋ผ๋ฏธํ„ฐ ์•ˆ์˜ ๊ฐ ์‘๋‹ต์— ์ด๊ฒƒ์˜ ์–ด๋–ค ํ•ญ๋ชฉ์ด๋“  ์ง์ ‘ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `description`, `headers`, `content`(์—ฌ๊ธฐ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฏธ๋””์–ด ํƒ€์ž…๊ณผ JSON Schema๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค), `links` ๋“ฑ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
* [OpenAPI Responses Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#responses-object): `Response Object`๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.
* [OpenAPI Response Object](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#response-object): `responses` ํŒŒ๋ผ๋ฏธํ„ฐ ์•ˆ์˜ ๊ฐ ์‘๋‹ต์— ์ด๊ฒƒ์˜ ์–ด๋–ค ํ•ญ๋ชฉ์ด๋“  ์ง์ ‘ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `description`, `headers`, `content`(์—ฌ๊ธฐ์—์„œ ์„œ๋กœ ๋‹ค๋ฅธ ๋ฏธ๋””์–ด ํƒ€์ž…๊ณผ JSON Schema๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค), `links` ๋“ฑ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2
docs/ko/docs/advanced/additional-status-codes.md

@ -38,4 +38,4 @@
์ถ”๊ฐ€ ์ƒํƒœ ์ฝ”๋“œ์™€ ์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ, FastAPI๋Š” ๋ฐ˜ํ™˜ํ•  ๋‚ด์šฉ์„ ๋ฏธ๋ฆฌ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— OpenAPI ์Šคํ‚ค๋งˆ(API ๋ฌธ์„œ)์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ์— ์ด๋ฅผ ๋ฌธ์„œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: [์ถ”๊ฐ€ ์‘๋‹ต](additional-responses.md){.internal-link target=_blank}.
ํ•˜์ง€๋งŒ ๋‹ค์Œ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ์— ์ด๋ฅผ ๋ฌธ์„œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค: [์ถ”๊ฐ€ ์‘๋‹ต](additional-responses.md).

4
docs/ko/docs/advanced/advanced-dependencies.md

@ -133,7 +133,7 @@ SQLModel(๋˜๋Š” SQLAlchemy)์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ด๋Ÿฐ ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€
๊ทธ๋Ÿฌ๋ฉด ์„ธ์…˜์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ฐ๊ฒฐ์„ ํ•ด์ œํ•˜์—ฌ, ๋‹ค๋ฅธ ์š”์ฒญ๋“ค์ด ์ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
`yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ๊ฐ€ ํ•„์š”ํ•œ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ๋‹ค๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ตฌ์ฒด์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์™€ `yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ์— ๋Œ€ํ•œ ์กฐ๊ธฐ ์ข…๋ฃŒ๊ฐ€ ์–ด๋–ค ์ ์—์„œ ์ด๋“์ด ๋˜๋Š”์ง€๋ฅผ ํฌํ•จํ•ด <a href="https://github.com/fastapi/fastapi/discussions/new?category=questions" class="external-link" target="_blank">GitHub Discussions ์งˆ๋ฌธ</a>์„ ์ƒ์„ฑํ•ด ์ฃผ์„ธ์š”.
`yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ๊ฐ€ ํ•„์š”ํ•œ ๋‹ค๋ฅธ ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ๋‹ค๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์˜ ๊ตฌ์ฒด์ ์ธ ์‚ฌ์šฉ ์‚ฌ๋ก€์™€ `yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ์— ๋Œ€ํ•œ ์กฐ๊ธฐ ์ข…๋ฃŒ๊ฐ€ ์–ด๋–ค ์ ์—์„œ ์ด๋“์ด ๋˜๋Š”์ง€๋ฅผ ํฌํ•จํ•ด [GitHub Discussions ์งˆ๋ฌธ](https://github.com/fastapi/fastapi/discussions/new?category=questions)์„ ์ƒ์„ฑํ•ด ์ฃผ์„ธ์š”.
`yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ์—์„œ ์กฐ๊ธฐ ์ข…๋ฃŒ์— ๋Œ€ํ•œ ์„ค๋“๋ ฅ ์žˆ๋Š” ์‚ฌ์šฉ ์‚ฌ๋ก€๊ฐ€ ์žˆ๋‹ค๋ฉด, ์กฐ๊ธฐ ์ข…๋ฃŒ๋ฅผ ์„ ํƒ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋Š” ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ์„ ๊ณ ๋ คํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.
@ -145,7 +145,7 @@ FastAPI 0.110.0 ์ด์ „์—๋Š” `yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ์„ ์‚ฌ์šฉํ•œ ๋‹ค์Œ ๊ทธ
### ๋ฐฑ๊ทธ๋ผ์šด๋“œ ํƒœ์Šคํฌ์™€ `yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ, ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ { #background-tasks-and-dependencies-with-yield-technical-details }
FastAPI 0.106.0 ์ด์ „์—๋Š” `yield` ์ดํ›„์— ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. `yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ์˜ ์ข…๋ฃŒ ์ฝ”๋“œ๋Š” ์‘๋‹ต์ด ์ „์†ก๋œ *ํ›„์—* ์‹คํ–‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, [์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ](../tutorial/handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}๊ฐ€ ์ด๋ฏธ ์‹คํ–‰๋œ ๋’ค์˜€์Šต๋‹ˆ๋‹ค.
FastAPI 0.106.0 ์ด์ „์—๋Š” `yield` ์ดํ›„์— ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ–ˆ์Šต๋‹ˆ๋‹ค. `yield`๊ฐ€ ์žˆ๋Š” ์˜์กด์„ฑ์˜ ์ข…๋ฃŒ ์ฝ”๋“œ๋Š” ์‘๋‹ต์ด ์ „์†ก๋œ *ํ›„์—* ์‹คํ–‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, [์˜ˆ์™ธ ํ•ธ๋“ค๋Ÿฌ](../tutorial/handling-errors.md#install-custom-exception-handlers)๊ฐ€ ์ด๋ฏธ ์‹คํ–‰๋œ ๋’ค์˜€์Šต๋‹ˆ๋‹ค.
์ด๋Š” ์ฃผ๋กœ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ํƒœ์Šคํฌ ์•ˆ์—์„œ ์˜์กด์„ฑ์ด "yield"ํ•œ ๋™์ผํ•œ ๊ฐ์ฒด๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•œ ์„ค๊ณ„์˜€์Šต๋‹ˆ๋‹ค. ๋ฐฑ๊ทธ๋ผ์šด๋“œ ํƒœ์Šคํฌ๊ฐ€ ๋๋‚œ ๋’ค์— ์ข…๋ฃŒ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

8
docs/ko/docs/advanced/async-tests.md

@ -16,11 +16,11 @@
`TestClient`๋Š” ํ‘œ์ค€ pytest๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ, ์ผ๋ฐ˜ `def` ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์•ˆ์—์„œ ๋น„๋™๊ธฐ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํ˜ธ์ถœํ•˜๋„๋ก ๋‚ด๋ถ€์—์„œ ๋งˆ๋ฒ• ๊ฐ™์€ ์ฒ˜๋ฆฌ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ์•ˆ์—์„œ ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ทธ ๋งˆ๋ฒ•์€ ๋” ์ด์ƒ ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ๋น„๋™๊ธฐ๋กœ ์‹คํ–‰ํ•˜๋ฉด, ํ…Œ์ŠคํŠธ ํ•จ์ˆ˜ ์•ˆ์—์„œ `TestClient`๋ฅผ ๋” ์ด์ƒ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
`TestClient`๋Š” <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, ๋‹คํ–‰ํžˆ HTTPX๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•ด API๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`TestClient`๋Š” [HTTPX](https://www.python-httpx.org)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, ๋‹คํ–‰ํžˆ HTTPX๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•ด API๋ฅผ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
## ์˜ˆ์‹œ { #example }
๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋กœ, [๋” ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜](../tutorial/bigger-applications.md){.internal-link target=_blank}๊ณผ [ํ…Œ์ŠคํŠธ](../tutorial/testing.md){.internal-link target=_blank}์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ๊ณผ ๋น„์Šทํ•œ ํŒŒ์ผ ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:
๊ฐ„๋‹จํ•œ ์˜ˆ์‹œ๋กœ, [๋” ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜](../tutorial/bigger-applications.md)๊ณผ [ํ…Œ์ŠคํŠธ](../tutorial/testing.md)์—์„œ ์„ค๋ช…ํ•œ ๊ฒƒ๊ณผ ๋น„์Šทํ•œ ํŒŒ์ผ ๊ตฌ์กฐ๋ฅผ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค:
```
.
@ -84,7 +84,7 @@ response = client.get('/')
/// warning | ๊ฒฝ๊ณ 
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด lifespan ์ด๋ฒคํŠธ์— ์˜์กดํ•œ๋‹ค๋ฉด, `AsyncClient`๋Š” ์ด๋Ÿฌํ•œ ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋˜๋„๋ก ํ•˜๋ ค๋ฉด <a href="https://github.com/florimondmanca/asgi-lifespan#usage" class="external-link" target="_blank">florimondmanca/asgi-lifespan</a>์˜ `LifespanManager`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด lifespan ์ด๋ฒคํŠธ์— ์˜์กดํ•œ๋‹ค๋ฉด, `AsyncClient`๋Š” ์ด๋Ÿฌํ•œ ์ด๋ฒคํŠธ๋ฅผ ํŠธ๋ฆฌ๊ฑฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ๊ฐ€ ํŠธ๋ฆฌ๊ฑฐ๋˜๋„๋ก ํ•˜๋ ค๋ฉด [florimondmanca/asgi-lifespan](https://github.com/florimondmanca/asgi-lifespan#usage)์˜ `LifespanManager`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
///
@ -94,6 +94,6 @@ response = client.get('/')
/// tip | ํŒ
ํ…Œ์ŠคํŠธ์— ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ํ†ตํ•ฉํ•  ๋•Œ(์˜ˆ: <a href="https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop" class="external-link" target="_blank">MongoDB์˜ MotorClient</a>๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ) `RuntimeError: Task attached to a different loop`๋ฅผ ๋งˆ์ฃผ์นœ๋‹ค๋ฉด, ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ํ•„์š”ํ•œ ๊ฐ์ฒด๋Š” async ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ์ธ์Šคํ„ด์Šคํ™”ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด `@app.on_event("startup")` ์ฝœ๋ฐฑ์—์„œ ์ธ์Šคํ„ด์Šคํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ…Œ์ŠคํŠธ์— ๋น„๋™๊ธฐ ํ•จ์ˆ˜ ํ˜ธ์ถœ์„ ํ†ตํ•ฉํ•  ๋•Œ(์˜ˆ: [MongoDB์˜ MotorClient](https://stackoverflow.com/questions/41584243/runtimeerror-task-attached-to-a-different-loop)๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ) `RuntimeError: Task attached to a different loop`๋ฅผ ๋งˆ์ฃผ์นœ๋‹ค๋ฉด, ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ํ•„์š”ํ•œ ๊ฐ์ฒด๋Š” async ํ•จ์ˆ˜ ์•ˆ์—์„œ๋งŒ ์ธ์Šคํ„ด์Šคํ™”ํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”. ์˜ˆ๋ฅผ ๋“ค์–ด `@app.on_event("startup")` ์ฝœ๋ฐฑ์—์„œ ์ธ์Šคํ„ด์Šคํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
///

34
docs/ko/docs/advanced/behind-a-proxy.md

@ -16,9 +16,9 @@
ํ”„๋ก์‹œ ํ—ค๋”๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For" class="external-link" target="_blank">X-Forwarded-For</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto" class="external-link" target="_blank">X-Forwarded-Proto</a>
* <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host" class="external-link" target="_blank">X-Forwarded-Host</a>
* [X-Forwarded-For](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-For)
* [X-Forwarded-Proto](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Proto)
* [X-Forwarded-Host](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/X-Forwarded-Host)
///
@ -60,7 +60,7 @@ https://mysuperapp.com/items/
/// tip | ํŒ
HTTPS์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด๋ ค๋ฉด ๊ฐ€์ด๋“œ [HTTPS์— ๋Œ€ํ•˜์—ฌ](../deployment/https.md){.internal-link target=_blank}๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
HTTPS์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด๋ ค๋ฉด ๊ฐ€์ด๋“œ [HTTPS์— ๋Œ€ํ•˜์—ฌ](../deployment/https.md)๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
///
@ -149,14 +149,14 @@ IP `0.0.0.0`์€ ๋ณดํ†ต ํ•ด๋‹น ๋จธ์‹ /์„œ๋ฒ„์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  IP์—
```JSON hl_lines="4-8"
{
"openapi": "3.1.0",
// More stuff here
// ์—ฌ๊ธฐ์— ๋‹ค๋ฅธ ๋‚ด์šฉ์ด ๋” ์žˆ์Šต๋‹ˆ๋‹ค
"servers": [
{
"url": "/api/v1"
}
],
"paths": {
// More stuff here
// ์—ฌ๊ธฐ์— ๋‹ค๋ฅธ ๋‚ด์šฉ์ด ๋” ์žˆ์Šต๋‹ˆ๋‹ค
}
}
```
@ -228,7 +228,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
์„œ๋ฒ„(Uvicorn)๋Š” ๊ทธ `root_path`๋ฅผ ์•ฑ์— ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ ์™ธ์—๋Š” ๋‹ค๋ฅธ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.
ํ•˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €๋กœ <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>์— ์ ‘์†ํ•˜๋ฉด ์ •์ƒ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
ํ•˜์ง€๋งŒ ๋ธŒ๋ผ์šฐ์ €๋กœ [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app)์— ์ ‘์†ํ•˜๋ฉด ์ •์ƒ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```JSON
{
@ -251,9 +251,9 @@ Uvicorn์€ ํ”„๋ก์‹œ๊ฐ€ `http://127.0.0.1:8000/app`์—์„œ Uvicorn์— ์ ‘๊ทผํ• 
## Traefik์œผ๋กœ ๋กœ์ปฌ ํ…Œ์ŠคํŠธํ•˜๊ธฐ { #testing-locally-with-traefik }
<a href="https://docs.traefik.io/" class="external-link" target="_blank">Traefik</a>์„ ์‚ฌ์šฉํ•˜๋ฉด, ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ๊ฐ€ ์ œ๊ฑฐ๋˜๋Š” ๊ตฌ์„ฑ์„ ๋กœ์ปฌ์—์„œ ์‰ฝ๊ฒŒ ์‹คํ—˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[Traefik](https://docs.traefik.io/)์„ ์‚ฌ์šฉํ•˜๋ฉด, ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ๊ฐ€ ์ œ๊ฑฐ๋˜๋Š” ๊ตฌ์„ฑ์„ ๋กœ์ปฌ์—์„œ ์‰ฝ๊ฒŒ ์‹คํ—˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
<a href="https://github.com/containous/traefik/releases" class="external-link" target="_blank">Traefik ๋‹ค์šด๋กœ๋“œ</a>๋Š” ๋‹จ์ผ ๋ฐ”์ด๋„ˆ๋ฆฌ์ด๋ฉฐ, ์••์ถ• ํŒŒ์ผ์„ ํ’€๊ณ  ํ„ฐ๋ฏธ๋„์—์„œ ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[Traefik ๋‹ค์šด๋กœ๋“œ](https://github.com/containous/traefik/releases)๋Š” ๋‹จ์ผ ๋ฐ”์ด๋„ˆ๋ฆฌ์ด๋ฉฐ, ์••์ถ• ํŒŒ์ผ์„ ํ’€๊ณ  ํ„ฐ๋ฏธ๋„์—์„œ ๋ฐ”๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ ๋‹ค์Œ ๋‹ค์Œ ๋‚ด์šฉ์„ ๊ฐ€์ง„ `traefik.toml` ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜์„ธ์š”:
@ -330,7 +330,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
### ์‘๋‹ต ํ™•์ธํ•˜๊ธฐ { #check-the-responses }
์ด์ œ Uvicorn์˜ ํฌํŠธ๋กœ ๋œ URL์ธ <a href="http://127.0.0.1:8000/app" class="external-link" target="_blank">http://127.0.0.1:8000/app</a>๋กœ ์ ‘์†ํ•˜๋ฉด ์ •์ƒ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
์ด์ œ Uvicorn์˜ ํฌํŠธ๋กœ ๋œ URL์ธ [http://127.0.0.1:8000/app](http://127.0.0.1:8000/app)๋กœ ์ ‘์†ํ•˜๋ฉด ์ •์ƒ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```JSON
{
@ -345,7 +345,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
///
์ด์ œ Traefik์˜ ํฌํŠธ๊ฐ€ ํฌํ•จ๋˜๊ณ  ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ๊ฐ€ ํฌํ•จ๋œ URL <a href="http://127.0.0.1:9999/api/v1/app" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/app</a>์„ ์—ฌ์„ธ์š”.
์ด์ œ Traefik์˜ ํฌํŠธ๊ฐ€ ํฌํ•จ๋˜๊ณ  ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ๊ฐ€ ํฌํ•จ๋œ URL [http://127.0.0.1:9999/api/v1/app](http://127.0.0.1:9999/api/v1/app)์„ ์—ฌ์„ธ์š”.
๋™์ผํ•œ ์‘๋‹ต์„ ์–ป์Šต๋‹ˆ๋‹ค:
@ -370,13 +370,13 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
์•ฑ์— ์ ‘๊ทผํ•˜๋Š” "๊ณต์‹" ๋ฐฉ๋ฒ•์€ ์šฐ๋ฆฌ๊ฐ€ ์ •์˜ํ•œ ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ๋ฅผ ๊ฐ€์ง„ ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด์„œ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ธฐ๋Œ€ํ•˜๋Š” ๋Œ€๋กœ, URL์— ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ๊ฐ€ ์—†๋Š” ์ƒํƒœ์—์„œ Uvicorn์ด ์ง์ ‘ ์ œ๊ณตํ•˜๋Š” docs UI๋ฅผ ์‹œ๋„ํ•˜๋ฉด, ํ”„๋ก์‹œ๋ฅผ ํ†ตํ•ด ์ ‘๊ทผ๋œ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
<a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
[http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
<img src="/img/tutorial/behind-a-proxy/image01.png">
ํ•˜์ง€๋งŒ ํ”„๋ก์‹œ(ํฌํŠธ `9999`)๋ฅผ ์‚ฌ์šฉํ•ด "๊ณต์‹" URL์ธ `/api/v1/docs`์—์„œ docs UI์— ์ ‘๊ทผํ•˜๋ฉด, ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค! ๐ŸŽ‰
<a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a>์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
[http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
<img src="/img/tutorial/behind-a-proxy/image02.png">
@ -407,7 +407,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
```JSON hl_lines="5-7"
{
"openapi": "3.1.0",
// More stuff here
// ์—ฌ๊ธฐ์— ๋‹ค๋ฅธ ๋‚ด์šฉ์ด ๋” ์žˆ์Šต๋‹ˆ๋‹ค
"servers": [
{
"url": "/api/v1"
@ -422,7 +422,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
}
],
"paths": {
// More stuff here
// ์—ฌ๊ธฐ์— ๋‹ค๋ฅธ ๋‚ด์šฉ์ด ๋” ์žˆ์Šต๋‹ˆ๋‹ค
}
}
```
@ -433,7 +433,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
///
<a href="http://127.0.0.1:9999/api/v1/docs" class="external-link" target="_blank">http://127.0.0.1:9999/api/v1/docs</a>์˜ docs UI์—์„œ๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค:
[http://127.0.0.1:9999/api/v1/docs](http://127.0.0.1:9999/api/v1/docs)์˜ docs UI์—์„œ๋Š” ๋‹ค์Œ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค:
<img src="/img/tutorial/behind-a-proxy/image03.png">
@ -461,6 +461,6 @@ OpenAPI ์‚ฌ์–‘์—์„œ `servers` ์†์„ฑ์€ ์„ ํƒ ์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค.
## ์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งˆ์šดํŠธํ•˜๊ธฐ { #mounting-a-sub-application }
ํ”„๋ก์‹œ์—์„œ `root_path`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ๋„, [์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ๋งˆ์šดํŠธ](sub-applications.md){.internal-link target=_blank}์— ์„ค๋ช…๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งˆ์šดํŠธํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๊ธฐ๋Œ€ํ•˜๋Š” ๋Œ€๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ”„๋ก์‹œ์—์„œ `root_path`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ๋„, [์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ๋งˆ์šดํŠธ](sub-applications.md)์— ์„ค๋ช…๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งˆ์šดํŠธํ•ด์•ผ ํ•œ๋‹ค๋ฉด, ๊ธฐ๋Œ€ํ•˜๋Š” ๋Œ€๋กœ ์ผ๋ฐ˜์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
FastAPI๊ฐ€ ๋‚ด๋ถ€์ ์œผ๋กœ `root_path`๋ฅผ ๋˜‘๋˜‘ํ•˜๊ฒŒ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ๊ทธ๋ƒฅ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. โœจ

152
docs/ko/docs/advanced/custom-response.md

@ -1,16 +1,14 @@
# ์‚ฌ์šฉ์ž ์ •์˜ ์‘๋‹ต - HTML, Stream, ํŒŒ์ผ, ๊ธฐํƒ€ { #custom-response-html-stream-file-others }
๊ธฐ๋ณธ์ ์œผ๋กœ, **FastAPI** ์‘๋‹ต์„ `JSONResponse`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ **FastAPI**๋Š” JSON ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฅผ ์žฌ์ •์˜ ํ•˜๋ ค๋ฉด [์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md){.internal-link target=_blank}์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ `Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.
[์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md){.internal-link target=_blank}์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ `Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์ด๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ `Response` (๋˜๋Š” `JSONResponse`์™€ ๊ฐ™์€ ํ•˜์œ„ ํด๋ž˜์Šค)๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋ฉด, ๋ฐ์ดํ„ฐ๊ฐ€ ์ž๋™์œผ๋กœ ๋ณ€ํ™˜๋˜์ง€ ์•Š์œผ๋ฉฐ (์‹ฌ์ง€์–ด `response_model`์„ ์„ ์–ธํ–ˆ๋”๋ผ๋„), ๋ฌธ์„œํ™”๊ฐ€ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์˜ˆ๋ฅผ ๋“ค์–ด, ์ƒ์„ฑ๋œ OpenAPI์˜ ์ผ๋ถ€๋กœ HTTP ํ—ค๋” `Content-Type`์— ํŠน์ • "๋ฏธ๋””์–ด ํƒ€์ž…"์„ ํฌํ•จํ•˜๋Š” ๊ฒฝ์šฐ).
๊ทธ๋Ÿฌ๋‚˜ `Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋ฉด(๋˜๋Š” `JSONResponse`์™€ ๊ฐ™์€ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉด) ๋ฐ์ดํ„ฐ๊ฐ€ ์ž๋™์œผ๋กœ ๋ณ€ํ™˜๋˜์ง€ ์•Š์œผ๋ฉฐ(๋น„๋ก `response_model`์„ ์„ ์–ธํ–ˆ๋‹ค ํ•˜๋”๋ผ๋„), ๋ฌธ์„œ๋„ ์ž๋™์œผ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์˜ˆ๋ฅผ ๋“ค์–ด, ์ƒ์„ฑ๋œ OpenAPI์˜ ์ผ๋ถ€๋กœ HTTP ํ—ค๋” `Content-Type`์— ํŠน์ • "๋ฏธ๋””์–ด ํƒ€์ž…"์„ ํฌํ•จํ•˜๋Š” ๊ฒƒ ๋“ฑ).
ํ•˜์ง€๋งŒ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ `response_class` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์›ํ•˜๋Š” `Response`(์˜ˆ: ๋ชจ๋“  `Response` ํ•˜์œ„ ํด๋ž˜์Šค)๋ฅผ ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ `response_class` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•  `Response`(์˜ˆ: ์–ด๋–ค `Response` ํ•˜์œ„ ํด๋ž˜์Šค๋“ )๋ฅผ ์„ ์–ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‚ด์šฉ์€ ํ•ด๋‹น `Response`์•ˆ์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ ๊ทธ `Response`๊ฐ€ `JSONResponse`์™€ `UJSONResponse`์˜ ๊ฒฝ์šฐ ์ฒ˜๋Ÿผ JSON ๋ฏธ๋””์–ด ํƒ€์ž…(`application/json`)์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ ์„ ์–ธํ•œ Pydantic์˜ `response_model`์„ ์‚ฌ์šฉํ•ด ์ž๋™์œผ๋กœ ๋ณ€ํ™˜(๋ฐ ํ•„ํ„ฐ๋ง) ๋ฉ๋‹ˆ๋‹ค.
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์—์„œ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‚ด์šฉ์€ ํ•ด๋‹น `Response` ์•ˆ์— ๋‹ด๊น๋‹ˆ๋‹ค.
/// note | ์ฐธ๊ณ 
@ -18,41 +16,27 @@
///
## `ORJSONResponse` ์‚ฌ์šฉํ•˜๊ธฐ { #use-orjsonresponse }
์˜ˆ๋ฅผ ๋“ค์–ด, ์„ฑ๋Šฅ์„ ๊ทน๋Œ€ํ™”ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ, <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>์„ ์„ค์น˜ํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ณ  ์‘๋‹ต์„ `ORJSONResponse`๋กœ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” `Response` ํด๋ž˜์Šค(ํ•˜์œ„ ํด๋ž˜์Šค)๋ฅผ ์ž„ํฌํŠธํ•œ ํ›„, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ ์„ ์–ธํ•˜์„ธ์š”.
๋Œ€๊ทœ๋ชจ ์‘๋‹ต์˜ ๊ฒฝ์šฐ, ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค `Response`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ํ›จ์”ฌ ๋น ๋ฆ…๋‹ˆ๋‹ค.
์ด์œ ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ, FastAPI๊ฐ€ ๋‚ด๋ถ€์˜ ๋ชจ๋“  ํ•ญ๋ชฉ์„ ๊ฒ€์‚ฌํ•˜๊ณ  JSON์œผ๋กœ ์ง๋ ฌํ™”ํ•  ์ˆ˜ ์žˆ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ์—์„œ ์„ค๋ช…๋œ [JSON ํ˜ธํ™˜ ๊ฐ€๋Šฅ ์ธ์ฝ”๋”](../tutorial/encoder.md){.internal-link target=_blank}๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ๊ณผ ๊ฐ™์€ **์ž„์˜์˜ ๊ฐ์ฒด**๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋‚ด์šฉ์ด **JSON์œผ๋กœ ์ง๋ ฌํ™” ๊ฐ€๋Šฅ**ํ•˜๋‹ค๊ณ  ํ™•์‹ ํ•˜๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ๋‚ด์šฉ์„ ์‘๋‹ต ํด๋ž˜์Šค์— ์ง์ ‘ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, FastAPI๊ฐ€ ๋ฐ˜ํ™˜ ๋‚ด์šฉ์„ `jsonable_encoder`๋ฅผ ํ†ตํ•ด ์ฒ˜๋ฆฌํ•œ ๋’ค ์‘๋‹ต ํด๋ž˜์Šค์— ์ „๋‹ฌํ•˜๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
## JSON ์‘๋‹ต { #json-responses }
{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
๊ธฐ๋ณธ์ ์œผ๋กœ FastAPI๋Š” JSON ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
/// info | ์ •๋ณด
`response_class` ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” ์‘๋‹ต์˜ "๋ฏธ๋””์–ด ํƒ€์ž…"์„ ์ •์˜ํ•˜๋Š” ๋ฐ์—๋„ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
[์‘๋‹ต ๋ชจ๋ธ](../tutorial/response-model.md){.internal-link target=_blank}์„ ์„ ์–ธํ•˜๋ฉด FastAPI๋Š” Pydantic์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ, HTTP ํ—ค๋” `Content-Type`์€ `application/json`์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
์‘๋‹ต ๋ชจ๋ธ์„ ์„ ์–ธํ•˜์ง€ ์•Š์œผ๋ฉด FastAPI๋Š” [JSON ํ˜ธํ™˜ ๊ฐ€๋Šฅ ์ธ์ฝ”๋”](../tutorial/encoder.md){.internal-link target=_blank}์—์„œ ์„ค๋ช…ํ•œ `jsonable_encoder`๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜ํ•œ ๋’ค `JSONResponse`์— ๋„ฃ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด๋Š” OpenAPI์— ๊ทธ๋Œ€๋กœ ๋ฌธ์„œํ™”๋ฉ๋‹ˆ๋‹ค.
`JSONResponse`์ฒ˜๋Ÿผ JSON ๋ฏธ๋””์–ด ํƒ€์ž…(`application/json`)์„ ๊ฐ€์ง„ `response_class`๋ฅผ ์„ ์–ธํ•˜๋ฉด, ์—ฌ๋Ÿฌ๋ถ„์ด *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์—์„œ ์„ ์–ธํ•œ Pydantic์˜ `response_model`๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ์ž๋™ ๋ณ€ํ™˜(๋ฐ ํ•„ํ„ฐ๋ง)๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ๋ฐ์ดํ„ฐ์˜ JSON ๋ฐ”์ดํŠธ ์ง๋ ฌํ™” ์ž์ฒด๋Š” Pydantic์ด ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š๊ณ , `jsonable_encoder`๋กœ ๋ณ€ํ™˜ํ•œ ํ›„ `JSONResponse` ํด๋ž˜์Šค์— ์ „๋‹ฌํ•˜๋ฉฐ, ๊ทธ ํด๋ž˜์Šค๊ฐ€ Python ํ‘œ์ค€ JSON ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ”์ดํŠธ๋กœ ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค.
///
### JSON ์„ฑ๋Šฅ { #json-performance }
/// tip | ํŒ
์š”์•ฝํ•˜๋ฉด, ์ตœ๋Œ€ ์„ฑ๋Šฅ์ด ํ•„์š”ํ•˜๋‹ค๋ฉด [์‘๋‹ต ๋ชจ๋ธ](../tutorial/response-model.md){.internal-link target=_blank}์„ ์‚ฌ์šฉํ•˜๊ณ , *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์— `response_class`๋ฅผ ์„ ์–ธํ•˜์ง€ ๋งˆ์„ธ์š”.
`ORJSONResponse`๋Š” FastAPI์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  Starlette์—์„œ๋Š” ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
///
{* ../../docs_src/response_model/tutorial001_01_py310.py ln[15:17] hl[16] *}
## HTML ์‘๋‹ต { #html-response }
**FastAPI**์—์„œ HTML ์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋ ค๋ฉด `HTMLResponse`๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
* `HTMLResponse`๋ฅผ ์ž„ํฌํŠธ ํ•ฉ๋‹ˆ๋‹ค.
* `HTMLResponse`๋ฅผ ์ž„ํฌํŠธํ•ฉ๋‹ˆ๋‹ค.
* *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ๋ฐ์ฝ”๋ ˆ์ดํ„ฐ*์˜ `response_class` ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ `HTMLResponse`๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
@ -63,13 +47,13 @@
์ด ๊ฒฝ์šฐ, HTTP ํ—ค๋” `Content-Type`์€ `text/html`๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด๋Š” OpenAPI์— ๊ทธ๋Œ€๋กœ ๋ฌธ์„œํ™” ๋ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ์ด๋Š” OpenAPI์— ๊ทธ๋Œ€๋กœ ๋ฌธ์„œํ™”๋ฉ๋‹ˆ๋‹ค.
///
### `Response` ๋ฐ˜ํ™˜ํ•˜๊ธฐ { #return-a-response }
[์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md){.internal-link target=_blank}์—์„œ ๋ณธ ๊ฒƒ ์ฒ˜๋Ÿผ, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ ์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์žฌ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
[์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md){.internal-link target=_blank}์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ ์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜์—ฌ ์žฌ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
์œ„์˜ ์˜ˆ์ œ์™€ ๋™์ผํ•˜๊ฒŒ `HTMLResponse`๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -77,7 +61,7 @@
/// warning | ๊ฒฝ๊ณ 
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์—์„œ ์ง์ ‘ ๋ฐ˜ํ™˜๋œ `Response`๋Š” OpenAPI์— ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์˜ˆ๋ฅผ๋“ค์–ด, `Content-Type`์ด ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์Œ) ์ž๋™ ๋Œ€ํ™”ํ˜• ๋ฌธ์„œ์—์„œ๋„ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์—์„œ ์ง์ ‘ ๋ฐ˜ํ™˜๋œ `Response`๋Š” OpenAPI์— ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค(์˜ˆ๋ฅผ ๋“ค์–ด, `Content-Type`์ด ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์Œ) ๊ทธ๋ฆฌ๊ณ  ์ž๋™ ๋Œ€ํ™”ํ˜• ๋ฌธ์„œ์—๋„ ํ‘œ์‹œ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
///
@ -87,54 +71,54 @@
///
### OpenAPI์— ๋ฌธ์„œํ™”ํ•˜๊ณ  `Response` ์žฌ์ •์˜ ํ•˜๊ธฐ { #document-in-openapi-and-override-response }
### OpenAPI์— ๋ฌธ์„œํ™”ํ•˜๊ณ  `Response` ์žฌ์ •์˜ํ•˜๊ธฐ { #document-in-openapi-and-override-response }
ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์‘๋‹ต์„ ์žฌ์ •์˜ํ•˜๋ฉด์„œ ๋™์‹œ์— OpenAPI์—์„œ "๋ฏธ๋””์–ด ํƒ€์ž…"์„ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, `response_class` ๋งค๊ฒŒ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ `Response` ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•จ์ˆ˜ ๋‚ด๋ถ€์—์„œ ์‘๋‹ต์„ ์žฌ์ •์˜ํ•˜๋ฉด์„œ ๋™์‹œ์— OpenAPI์—์„œ "๋ฏธ๋””์–ด ํƒ€์ž…"์„ ๋ฌธ์„œํ™”ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, `response_class` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ `Response` ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ `response_class`๋Š” OpenAPI *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ๋ฌธ์„œํ™”ํ•˜๋Š” ๋ฐ๋งŒ ์‚ฌ์šฉ๋˜๊ณ , ์‹ค์ œ๋กœ๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด ๋ฐ˜ํ™˜ํ•œ `Response`๊ฐ€ ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
#### `HTMLResponse`์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ { #return-an-htmlresponse-directly }
#### `HTMLResponse` ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ { #return-an-htmlresponse-directly }
์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
์ด ์˜ˆ์ œ์—์„œ, `generate_html_response()` ํ•จ์ˆ˜๋Š” HTML์„ `str`๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋Œ€์‹  ์ด๋ฏธ `Response`๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์ด ์˜ˆ์ œ์—์„œ `generate_html_response()` ํ•จ์ˆ˜๋Š” HTML์„ `str`๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋Œ€์‹  ์ด๋ฏธ `Response`๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
`generate_html_response()`๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•จ์œผ๋กœ์จ, ๊ธฐ๋ณธ์ ์ธ **FastAPI** ๊ธฐ๋ณธ ๋™์ž‘์„ ์žฌ์ •์˜ ํ•˜๋Š” `Response`๋ฅผ ์ด๋ฏธ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
`generate_html_response()`๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•จ์œผ๋กœ์จ, ๊ธฐ๋ณธ์ ์ธ **FastAPI** ๋™์ž‘์„ ์žฌ์ •์˜ํ•˜๋Š” `Response`๋ฅผ ์ด๋ฏธ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ `response_class`์— `HTMLResponse`๋ฅผ ํ•จ๊ป˜ ์ „๋‹ฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, **FastAPI**๋Š” ์ด๋ฅผ OpenAPI ๋ฐ ๋Œ€ํ™”ํ˜• ๋ฌธ์„œ์—์„œ `text/html`๋กœ HTML์„ ๋ฌธ์„œํ™” ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ `response_class`์— `HTMLResponse`๋ฅผ ํ•จ๊ป˜ ์ „๋‹ฌํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, **FastAPI**๋Š” ์ด๋ฅผ OpenAPI ๋ฐ ๋Œ€ํ™”ํ˜• ๋ฌธ์„œ์—์„œ `text/html`์˜ HTML๋กœ ๋ฌธ์„œํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
<img src="/img/tutorial/custom-response/image01.png">
## ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์‘๋‹ต๋“ค { #available-responses }
๋‹ค์Œ์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡๊ฐ€์ง€ ์‘๋‹ต๋“ค ์ž…๋‹ˆ๋‹ค.
๋‹ค์Œ์€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์‘๋‹ต๋“ค์ž…๋‹ˆ๋‹ค.
`Response`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ๋„ ๋ฐ˜ํ™˜ ํ• ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ง์ ‘ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
`Response`๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค๋ฅธ ์–ด๋–ค ๊ฒƒ๋„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ง์ ‘ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
`from starlette.responses import HTMLResponse`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
**FastAPI**๋Š” ๊ฐœ๋ฐœ์ž์ธ ์—ฌ๋Ÿฌ๋ถ„์˜ ํŽธ์˜๋ฅผ ์œ„ํ•ด `starlette.responses`๋ฅผ `fastapi.responses`๋กœ ์ œ๊ณต ํ•˜์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์‘๋‹ต์€ Starlette์—์„œ ์ง์ ‘ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
**FastAPI**๋Š” ๊ฐœ๋ฐœ์ž์ธ ์—ฌ๋Ÿฌ๋ถ„์˜ ํŽธ์˜๋ฅผ ์œ„ํ•ด `starlette.responses`๋ฅผ `fastapi.responses`๋กœ ๋™์ผํ•˜๊ฒŒ ์ œ๊ณตํ•˜์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์‘๋‹ต์€ Starlette์—์„œ ์ง์ ‘ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค.
///
### `Response` { #response }
๊ธฐ๋ณธ `Response` ํด๋ž˜์Šค๋Š” ๋‹ค๋ฅธ ๋ชจ๋“  ์‘๋‹ต ํด๋ž˜์Šค์˜ ๋ถ€๋ชจ ํด๋ž˜์Šค ์ž…๋‹ˆ๋‹ค.
๊ธฐ๋ณธ `Response` ํด๋ž˜์Šค์ด๋ฉฐ, ๋‹ค๋ฅธ ๋ชจ๋“  ์‘๋‹ต ํด๋ž˜์Šค๊ฐ€ ์ด๋ฅผ ์ƒ์†ํ•ฉ๋‹ˆ๋‹ค.
์ด ํด๋ž˜์Šค๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค์Œ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* `content` - `str` ๋˜๋Š” `bytes`.
* `status_code` - HTTP ์ƒํƒœ์ฝ”๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” `int`.
* `status_code` - HTTP ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” `int`.
* `headers` - ๋ฌธ์ž์—ด๋กœ ์ด๋ฃจ์–ด์ง„ `dict`.
* `media_type` - ๋ฏธ๋””์–ด ํƒ€์ž…์„ ๋‚˜ํƒ€๋‚ด๋Š” `str` ์˜ˆ: `"text/html"`.
FastAPI (์‹ค์ œ๋กœ๋Š” Starlette)๊ฐ€ ์ž๋™์œผ๋กœ Content-Length ํ—ค๋”๋ฅผ ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค. ๋˜ํ•œ `media_type`์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ Content-Type ํ—ค๋”๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ํ…์ŠคํŠธ ํƒ€์ž…์˜ ๊ฒฝ์šฐ ๋ฌธ์ž ์ง‘ํ•ฉ์„ ์ถ”๊ฐ€ ํ•ฉ๋‹ˆ๋‹ค.
FastAPI(์ •ํ™•ํžˆ๋Š” Starlette)๊ฐ€ ์ž๋™์œผ๋กœ Content-Length ํ—ค๋”๋ฅผ ํฌํ•จ์‹œํ‚ต๋‹ˆ๋‹ค. ๋˜ํ•œ `media_type`์— ๊ธฐ๋ฐ˜ํ•˜์—ฌ Content-Type ํ—ค๋”๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ํ…์ŠคํŠธ ํƒ€์ž…์˜ ๊ฒฝ์šฐ ๋ฌธ์ž ์ง‘ํ•ฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
@ -154,37 +138,11 @@ FastAPI (์‹ค์ œ๋กœ๋Š” Starlette)๊ฐ€ ์ž๋™์œผ๋กœ Content-Length ํ—ค๋”๋ฅผ ํฌํ•จ
์ด๋Š” ์œ„์—์„œ ์„ค๋ช…ํ–ˆ๋“ฏ์ด **FastAPI**์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์‘๋‹ต ํ˜•์‹์ž…๋‹ˆ๋‹ค.
### `ORJSONResponse` { #orjsonresponse }
<a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>์„ ์‚ฌ์šฉํ•˜์—ฌ ๋น ๋ฅธ JSON ์‘๋‹ต์„ ์ œ๊ณตํ•˜๋Š” ๋Œ€์•ˆ์ž…๋‹ˆ๋‹ค. ์œ„์—์„œ ์„ค๋ช…ํ•œ ๋‚ด์šฉ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
/// info | ์ •๋ณด
์ด๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด `orjson`์„ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ: `pip install orjson`.
///
### `UJSONResponse` { #ujsonresponse }
<a href="https://github.com/ultrajson/ultrajson" class="external-link" target="_blank">`ujson`</a>์„ ์‚ฌ์šฉํ•œ ๋˜ ๋‹ค๋ฅธ JSON ์‘๋‹ต ํ˜•์‹์ž…๋‹ˆ๋‹ค.
/// info | ์ •๋ณด
์ด ์‘๋‹ต์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด `ujson`์„ ์„ค์น˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ: `pip install ujson`.
///
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
/// warning | ๊ฒฝ๊ณ 
ํ•˜์ง€๋งŒ ์‘๋‹ต ๋ชจ๋ธ ๋˜๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์„ ์–ธํ•œ ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ชจ๋ธ์ด ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”ํ•˜๋Š” ๋ฐ ์ง์ ‘ ์‚ฌ์šฉ๋˜๋ฉฐ, ์˜ฌ๋ฐ”๋ฅธ JSON ๋ฏธ๋””์–ด ํƒ€์ž…์˜ ์‘๋‹ต์ด `JSONResponse` ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.
`ujson` ์€ ์ผ๋ถ€ ์˜ˆ์™ธ ๊ฒฝ์šฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์žˆ์–ด Python ๋‚ด์žฅ ๊ตฌํ˜„๋ณด๋‹ค ๋œ ์—„๊ฒฉํ•ฉ๋‹ˆ๋‹ค.
///
{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
/// tip | ํŒ
`ORJSONResponse`๊ฐ€ ๋” ๋น ๋ฅธ ๋Œ€์•ˆ์ผ ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๋ฐฉ์‹์ด ์ตœ์ƒ์˜ ์„ฑ๋Šฅ์„ ์–ป๋Š” ์ด์ƒ์ ์ธ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค.
///
@ -192,7 +150,7 @@ FastAPI (์‹ค์ œ๋กœ๋Š” Starlette)๊ฐ€ ์ž๋™์œผ๋กœ Content-Length ํ—ค๋”๋ฅผ ํฌํ•จ
HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 307(์ž„์‹œ ๋ฆฌ๋””๋ ‰์…˜)์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.
`RedirectResponse`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`RedirectResponse`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
@ -205,7 +163,7 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
์ด ๊ฒฝ์šฐ, *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ํ•จ์ˆ˜์—์„œ URL์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ, ์‚ฌ์šฉ๋˜๋Š” `status_code`๋Š” `RedirectResponse`์˜ ๊ธฐ๋ณธ๊ฐ’์ธ `307` ์ž…๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ, ์‚ฌ์šฉ๋˜๋Š” `status_code`๋Š” `RedirectResponse`์˜ ๊ธฐ๋ณธ๊ฐ’์ธ `307`์ž…๋‹ˆ๋‹ค.
---
@ -215,31 +173,25 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
### `StreamingResponse` { #streamingresponse }
๋น„๋™๊ธฐ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๋˜๋Š” ์ผ๋ฐ˜ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ/์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ ์‘๋‹ต ๋ณธ๋ฌธ์„ ์ŠคํŠธ๋ฆฌ๋ฐ ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
#### ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•œ `StreamingResponse` { #using-streamingresponse-with-file-like-objects }
๋น„๋™๊ธฐ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๋˜๋Š” ์ผ๋ฐ˜ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ/์ดํ„ฐ๋ ˆ์ดํ„ฐ(`yield`๊ฐ€ ์žˆ๋Š” ํ•จ์ˆ˜)๋ฅผ ๋ฐ›์•„ ์‘๋‹ต ๋ณธ๋ฌธ์„ ์ŠคํŠธ๋ฆฌ๋ฐํ•ฉ๋‹ˆ๋‹ค.
<a href="https://docs.python.org/3/glossary.html#term-file-like-object" class="external-link" target="_blank">file-like</a> ๊ฐ์ฒด(์˜ˆ: `open()`์œผ๋กœ ๋ฐ˜ํ™˜๋œ ๊ฐ์ฒด)๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น file-like ๊ฐ์ฒด๋ฅผ ๋ฐ˜๋ณต(iterate)ํ•˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial007_py310.py hl[3,16] *}
์ด ๋ฐฉ์‹์œผ๋กœ, ํŒŒ์ผ ์ „์ฒด๋ฅผ ๋ฉ”๋ชจ๋ฆฌ์— ๋จผ์ € ์ฝ์–ด๋“ค์ผ ํ•„์š” ์—†์ด, ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๋ฅผ `StreamingResponse`์— ์ „๋‹ฌํ•˜์—ฌ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๋ฐฉ์‹์€ ํด๋ผ์šฐ๋“œ ์Šคํ† ๋ฆฌ์ง€, ๋น„๋””์˜ค ์ฒ˜๋ฆฌ ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
`async` ์ž‘์—…์€ `await`์— ๋„๋‹ฌํ–ˆ์„ ๋•Œ๋งŒ ์ทจ์†Œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. `await`๊ฐ€ ์—†์œผ๋ฉด ์ œ๋„ˆ๋ ˆ์ดํ„ฐ(`yield`๊ฐ€ ์žˆ๋Š” ํ•จ์ˆ˜)๋Š” ์ œ๋Œ€๋กœ ์ทจ์†Œ๋  ์ˆ˜ ์—†๊ณ , ์ทจ์†Œ๊ฐ€ ์š”์ฒญ๋œ ํ›„์—๋„ ๊ณ„์† ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
1. ์ด๊ฒƒ์ด ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค. `yield` ๋ฌธ์„ ํฌํ•จํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ "์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜"์ž…๋‹ˆ๋‹ค.
2. `with` ๋ธ”๋ก์„ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ, ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๊ฐ€ ์™„๋ฃŒ๋œ ํ›„ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ๋‹ซํžˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์‘๋‹ต ์ „์†ก์ด ๋๋‚œ ํ›„ ๋‹ซํž™๋‹ˆ๋‹ค.
3. ์ด `yield from`์€ ํ•จ์ˆ˜๊ฐ€ `file_like`๋ผ๋Š” ๊ฐ์ฒด๋ฅผ ๋ฐ˜๋ณต(iterate)ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ณต๋œ ๊ฐ ๋ถ€๋ถ„์€ ์ด ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜(`iterfile`)์—์„œ ์ƒ์„ฑ๋œ ๊ฒƒ์ฒ˜๋Ÿผ `yield` ๋ฉ๋‹ˆ๋‹ค.
์ด ์ž‘์€ ์˜ˆ์ œ๋Š” ์–ด๋–ค `await`๋„ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์ด๋ฒคํŠธ ๋ฃจํ”„๊ฐ€ ์ทจ์†Œ๋ฅผ ์ฒ˜๋ฆฌํ•  ๊ธฐํšŒ๋ฅผ ์ฃผ๊ธฐ ์œ„ํ•ด `await anyio.sleep(0)`๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด "์ƒ์„ฑ(generating)" ์ž‘์—…์„ ๋‚ด๋ถ€์ ์œผ๋กœ ๋‹ค๋ฅธ ๋ฌด์–ธ๊ฐ€์— ์œ„์ž„ํ•˜๋Š” ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ํ•จ์ˆ˜๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
๋Œ€๊ทœ๋ชจ ๋˜๋Š” ๋ฌดํ•œ ์ŠคํŠธ๋ฆผ์—์„œ๋Š” ๋”์šฑ ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.
์ด ๋ฐฉ์‹์„ ์‚ฌ์šฉํ•˜๋ฉด `with` ๋ธ”๋ก ์•ˆ์—์„œ ํŒŒ์ผ์„ ์—ด ์ˆ˜ ์žˆ์–ด, ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„ ํŒŒ์ผ๊ณผ ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ ๋‹ซํžˆ๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
///
/// tip | ํŒ
์—ฌ๊ธฐ์„œ ํ‘œ์ค€ `open()`์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— `async`์™€ `await`๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ๋Š” ์ผ๋ฐ˜ `def`๋กœ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค.
`StreamingResponse`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋Œ€์‹ , [๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆฌ๋ฐ](./stream-data.md){.internal-link target=_blank}์—์„œ์˜ ์Šคํƒ€์ผ์„ ๋”ฐ๋ฅด๋Š” ๊ฒƒ์ด ๋” ํŽธ๋ฆฌํ•˜๋ฉฐ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ทจ์†Œ ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ค๋‹ˆ๋‹ค.
JSON Lines๋ฅผ ์ŠคํŠธ๋ฆฌ๋ฐํ•œ๋‹ค๋ฉด, [JSON Lines ์ŠคํŠธ๋ฆฌ๋ฐ](../tutorial/stream-json-lines.md){.internal-link target=_blank} ํŠœํ† ๋ฆฌ์–ผ์„ ํ™•์ธํ•˜์„ธ์š”.
///
@ -268,9 +220,9 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
`Response`๋ฅผ ์ƒ์†๋ฐ›์•„ ์‚ฌ์šฉ์ž ์ •์˜ ์‘๋‹ต ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ํฌํ•จ๋œ `ORJSONResponse` ํด๋ž˜์Šค์—์„œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์„ค์ •์œผ๋กœ <a href="https://github.com/ijl/orjson" class="external-link" target="_blank">`orjson`</a>์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, [`orjson`](https://github.com/ijl/orjson){.external-link target=_blank}์„ ์ผ๋ถ€ ์„ค์ •๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ด…์‹œ๋‹ค.
๋งŒ์•ฝ ๋“ค์—ฌ์“ฐ๊ธฐ ๋ฐ ํฌ๋งท๋œ JSON์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, `orjson.OPT_INDENT_2` ์˜ต์…˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋“ค์—ฌ์“ฐ๊ธฐ ๋ฐ ํฌ๋งท๋œ JSON์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด, orjson ์˜ต์…˜ `orjson.OPT_INDENT_2`๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`CustomORJSONResponse`๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ํ•ต์‹ฌ์€ `Response.render(content)` ๋ฉ”์„œ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋‚ด์šฉ์„ `bytes`๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค:
@ -292,13 +244,21 @@ HTTP ๋ฆฌ๋””๋ ‰์…˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒํƒœ ์ฝ”๋“œ๋Š” 30
๋ฌผ๋ก  JSON ํฌ๋งทํŒ…๋ณด๋‹ค ๋” ์œ ์šฉํ•˜๊ฒŒ ํ™œ์šฉํ•  ๋ฐฉ๋ฒ•์„ ์ฐพ์„ ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๐Ÿ˜‰
### `orjson` ๋˜๋Š” ์‘๋‹ต ๋ชจ๋ธ { #orjson-or-response-model }
์„ฑ๋Šฅ์ด ๋ชฉ์ ์ด๋ผ๋ฉด, `orjson` ์‘๋‹ต์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค [์‘๋‹ต ๋ชจ๋ธ](../tutorial/response-model.md){.internal-link target=_blank}์„ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ๋” ๋‚˜์„ ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
์‘๋‹ต ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜๋ฉด FastAPI๋Š” ์ค‘๊ฐ„ ๋‹จ๊ณ„(์˜ˆ: `jsonable_encoder`๋กœ์˜ ๋ณ€ํ™˜) ์—†์ด Pydantic์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์ค‘๊ฐ„ ๋‹จ๊ณ„๋Š” ๋‹ค๋ฅธ ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋‚ด๋ถ€์ ์œผ๋กœ Pydantic์€ JSON ์ง๋ ฌํ™”๋ฅผ ์œ„ํ•ด `orjson`๊ณผ ๋™์ผํ•œ Rust ๊ธฐ๋ฐ˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ, ์‘๋‹ต ๋ชจ๋ธ๋งŒ์œผ๋กœ๋„ ์ด๋ฏธ ์ตœ์ƒ์˜ ์„ฑ๋Šฅ์„ ์–ป๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
## ๊ธฐ๋ณธ ์‘๋‹ต ํด๋ž˜์Šค { #default-response-class }
**FastAPI** ํด๋ž˜์Šค ๊ฐ์ฒด ๋˜๋Š” `APIRouter`๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์‘๋‹ต ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
**FastAPI** ํด๋ž˜์Šค ์ธ์Šคํ„ด์Šค ๋˜๋Š” `APIRouter`๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๊ธฐ๋ณธ์œผ๋กœ ์‚ฌ์šฉํ•  ์‘๋‹ต ํด๋ž˜์Šค๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์ •์˜ํ•˜๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜๋Š” `default_response_class`์ž…๋‹ˆ๋‹ค.
์•„๋ž˜ ์˜ˆ์ œ์—์„œ **FastAPI**๋Š” ๋ชจ๋“  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ ๊ธฐ๋ณธ์ ์œผ๋กœ `JSONResponse` ๋Œ€์‹  `ORJSONResponse`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์•„๋ž˜ ์˜ˆ์ œ์—์„œ **FastAPI**๋Š” ๋ชจ๋“  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ JSON ๋Œ€์‹  ๊ธฐ๋ณธ์ ์œผ๋กœ `HTMLResponse`๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}

8
docs/ko/docs/advanced/dataclasses.md

@ -2,11 +2,11 @@
FastAPI๋Š” **Pydantic** ์œ„์— ๊ตฌ์ถ•๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ง€๊ธˆ๊นŒ์ง€๋Š” Pydantic ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด ์š”์ฒญ๊ณผ ์‘๋‹ต์„ ์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ๋“œ๋ ธ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ FastAPI๋Š” <a href="https://docs.python.org/3/library/dataclasses.html" class="external-link" target="_blank">`dataclasses`</a>๋„ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:
ํ•˜์ง€๋งŒ FastAPI๋Š” [`dataclasses`](https://docs.python.org/3/library/dataclasses.html)๋„ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/dataclasses_/tutorial001_py310.py hl[1,6:11,18:19] *}
์ด๋Š” **Pydantic** ๋•๋ถ„์— ์—ฌ์ „ํžˆ ์ง€์›๋˜๋Š”๋ฐ, Pydantic์ด <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel" class="external-link" target="_blank">`dataclasses`์— ๋Œ€ํ•œ ๋‚ด๋ถ€ ์ง€์›</a>์„ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
์ด๋Š” **Pydantic** ๋•๋ถ„์— ์—ฌ์ „ํžˆ ์ง€์›๋˜๋Š”๋ฐ, Pydantic์ด [`dataclasses`์— ๋Œ€ํ•œ ๋‚ด๋ถ€ ์ง€์›](https://docs.pydantic.dev/latest/concepts/dataclasses/#use-of-stdlib-dataclasses-with-basemodel)์„ ์ œ๊ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์œ„ ์ฝ”๋“œ์ฒ˜๋Ÿผ Pydantic์„ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋”๋ผ๋„, FastAPI๋Š” Pydantic์„ ์‚ฌ์šฉํ•ด ํ‘œ์ค€ dataclasses๋ฅผ Pydantic์˜ dataclasses ๋ณ€ํ˜•์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
@ -18,7 +18,7 @@ FastAPI๋Š” **Pydantic** ์œ„์— ๊ตฌ์ถ•๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ง€๊ธˆ๊นŒ์ง€๋Š” Pydantic
์ด๋Š” Pydantic ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•  ๋•Œ์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์‹ค์ œ๋กœ๋„ ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” Pydantic์„ ์‚ฌ์šฉํ•ด ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„๋ฉ๋‹ˆ๋‹ค.
/// info | ์ •๋ณด
/// info
dataclasses๋Š” Pydantic ๋ชจ๋ธ์ด ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์„ ํ•  ์ˆ˜๋Š” ์—†๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.
@ -88,7 +88,7 @@ dataclass๋Š” ์ž๋™์œผ๋กœ Pydantic dataclass๋กœ ๋ณ€ํ™˜๋ฉ๋‹ˆ๋‹ค.
`dataclasses`๋ฅผ ๋‹ค๋ฅธ Pydantic ๋ชจ๋ธ๊ณผ ์กฐํ•ฉํ•˜๊ฑฐ๋‚˜, ์ด๋ฅผ ์ƒ์†ํ•˜๊ฑฐ๋‚˜, ์—ฌ๋Ÿฌ๋ถ„์˜ ๋ชจ๋ธ์— ํฌํ•จํ•˜๋Š” ๋“ฑ์˜ ์ž‘์—…๋„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ž์„ธํ•œ ๋‚ด์šฉ์€ <a href="https://docs.pydantic.dev/latest/concepts/dataclasses/" class="external-link" target="_blank">dataclasses์— ๊ด€ํ•œ Pydantic ๋ฌธ์„œ</a>๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
์ž์„ธํ•œ ๋‚ด์šฉ์€ [dataclasses์— ๊ด€ํ•œ Pydantic ๋ฌธ์„œ](https://docs.pydantic.dev/latest/concepts/dataclasses/)๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
## ๋ฒ„์ „ { #version }

6
docs/ko/docs/advanced/events.md

@ -150,11 +150,11 @@ async with lifespan(app):
ํ˜ธ๊ธฐ์‹ฌ ๋งŽ์€ ๋ถ„๋“ค์„ ์œ„ํ•œ ๊ธฐ์ˆ ์ ์ธ ์„ธ๋ถ€์‚ฌํ•ญ์ž…๋‹ˆ๋‹ค. ๐Ÿค“
๋‚ด๋ถ€์ ์œผ๋กœ ASGI ๊ธฐ์ˆ  ์‚ฌ์–‘์—์„œ๋Š” ์ด๊ฒƒ์ด <a href="https://asgi.readthedocs.io/en/latest/specs/lifespan.html" class="external-link" target="_blank">Lifespan Protocol</a>์˜ ์ผ๋ถ€์ด๋ฉฐ, `startup`๊ณผ `shutdown`์ด๋ผ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
๋‚ด๋ถ€์ ์œผ๋กœ ASGI ๊ธฐ์ˆ  ์‚ฌ์–‘์—์„œ๋Š” ์ด๊ฒƒ์ด [Lifespan Protocol](https://asgi.readthedocs.io/en/latest/specs/lifespan.html)์˜ ์ผ๋ถ€์ด๋ฉฐ, `startup`๊ณผ `shutdown`์ด๋ผ๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
/// info | ์ •๋ณด
Starlette `lifespan` ํ•ธ๋“ค๋Ÿฌ์— ๋Œ€ํ•ด์„œ๋Š” <a href="https://www.starlette.dev/lifespan/" class="external-link" target="_blank">Starlette์˜ Lifespan ๋ฌธ์„œ</a>์—์„œ ๋” ์ฝ์–ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
Starlette `lifespan` ํ•ธ๋“ค๋Ÿฌ์— ๋Œ€ํ•ด์„œ๋Š” [Starlette์˜ Lifespan ๋ฌธ์„œ](https://www.starlette.dev/lifespan/)์—์„œ ๋” ์ฝ์–ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ์ฝ”๋“œ์˜ ๋‹ค๋ฅธ ์˜์—ญ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” lifespan ์ƒํƒœ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
@ -162,4 +162,4 @@ Starlette `lifespan` ํ•ธ๋“ค๋Ÿฌ์— ๋Œ€ํ•ด์„œ๋Š” <a href="https://www.starlette.de
## ์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ { #sub-applications }
๐Ÿšจ ์ด lifespan ์ด๋ฒคํŠธ(startup ๋ฐ shutdown)๋Š” ๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•ด์„œ๋งŒ ์‹คํ–‰๋˜๋ฉฐ, [์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - Mounts](sub-applications.md){.internal-link target=_blank}์—๋Š” ์‹คํ–‰๋˜์ง€ ์•Š์Œ์„ ์œ ์˜ํ•˜์„ธ์š”.
๐Ÿšจ ์ด lifespan ์ด๋ฒคํŠธ(startup ๋ฐ shutdown)๋Š” ๋ฉ”์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•ด์„œ๋งŒ ์‹คํ–‰๋˜๋ฉฐ, [์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - Mounts](sub-applications.md)์—๋Š” ์‹คํ–‰๋˜์ง€ ์•Š์Œ์„ ์œ ์˜ํ•˜์„ธ์š”.

32
docs/ko/docs/advanced/generate-clients.md

@ -8,11 +8,11 @@
## ์˜คํ”ˆ ์†Œ์Šค SDK ์ƒ์„ฑ๊ธฐ { #open-source-sdk-generators }
๋‹ค์–‘ํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์œผ๋กœ <a href="https://openapi-generator.tech/" class="external-link" target="_blank">OpenAPI Generator</a>๊ฐ€ ์žˆ์œผ๋ฉฐ, **๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด**๋ฅผ ์ง€์›ํ•˜๊ณ  OpenAPI ์‚ฌ์–‘์œผ๋กœ๋ถ€ํ„ฐ SDK๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋‹ค์–‘ํ•˜๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์˜ต์…˜์œผ๋กœ [OpenAPI Generator](https://openapi-generator.tech/)๊ฐ€ ์žˆ์œผ๋ฉฐ, **๋‹ค์–‘ํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด**๋ฅผ ์ง€์›ํ•˜๊ณ  OpenAPI ์‚ฌ์–‘์œผ๋กœ๋ถ€ํ„ฐ SDK๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
**TypeScript ํด๋ผ์ด์–ธํŠธ**์˜ ๊ฒฝ์šฐ <a href="https://heyapi.dev/" class="external-link" target="_blank">Hey API</a>๋Š” TypeScript ์ƒํƒœ๊ณ„์— ์ตœ์ ํ™”๋œ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ๋ชฉ์ ์— ๋งž๊ฒŒ ์„ค๊ณ„๋œ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค.
**TypeScript ํด๋ผ์ด์–ธํŠธ**์˜ ๊ฒฝ์šฐ [Hey API](https://heyapi.dev/)๋Š” TypeScript ์ƒํƒœ๊ณ„์— ์ตœ์ ํ™”๋œ ๊ฒฝํ—˜์„ ์ œ๊ณตํ•˜๋Š” ๋ชฉ์ ์— ๋งž๊ฒŒ ์„ค๊ณ„๋œ ์†”๋ฃจ์…˜์ž…๋‹ˆ๋‹ค.
๋” ๋งŽ์€ SDK ์ƒ์„ฑ๊ธฐ๋Š” <a href="https://openapi.tools/#sdk" class="external-link" target="_blank">OpenAPI.Tools</a>์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋” ๋งŽ์€ SDK ์ƒ์„ฑ๊ธฐ๋Š” [OpenAPI.Tools](https://openapi.tools/#sdk)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
/// tip | ํŒ
@ -24,15 +24,15 @@ FastAPI๋Š” **OpenAPI 3.1** ์‚ฌ์–‘์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋ฏ€๋กœ, ์‚ฌ์šฉํ•˜๋Š”
์ด ์„น์…˜์—์„œ๋Š” FastAPI๋ฅผ ํ›„์›ํ•˜๋Š” ํšŒ์‚ฌ๋“ค์ด ์ œ๊ณตํ•˜๋Š” **๋ฒค์ฒ˜ ํˆฌ์ž ๊ธฐ๋ฐ˜** ๋ฐ **๊ธฐ์—… ์ง€์›** ์†”๋ฃจ์…˜์„ ์†Œ๊ฐœํ•ฉ๋‹ˆ๋‹ค. ์ด ์ œํ’ˆ๋“ค์€ ๊ณ ํ’ˆ์งˆ๋กœ ์ƒ์„ฑ๋œ SDK์— ๋”ํ•ด **์ถ”๊ฐ€ ๊ธฐ๋Šฅ**๊ณผ **ํ†ตํ•ฉ**์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
โœจ [**FastAPI ํ›„์›ํ•˜๊ธฐ**](../help-fastapi.md#sponsor-the-author){.internal-link target=_blank} โœจ๋ฅผ ํ†ตํ•ด, ์ด ํšŒ์‚ฌ๋“ค์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ทธ **์ƒํƒœ๊ณ„**๊ฐ€ ๊ฑด๊ฐ•ํ•˜๊ณ  **์ง€์† ๊ฐ€๋Šฅ**ํ•˜๊ฒŒ ์œ ์ง€๋˜๋„๋ก ๋•์Šต๋‹ˆ๋‹ค.
โœจ [**FastAPI ํ›„์›ํ•˜๊ธฐ**](../help-fastapi.md#sponsor-the-author) โœจ๋ฅผ ํ†ตํ•ด, ์ด ํšŒ์‚ฌ๋“ค์€ ํ”„๋ ˆ์ž„์›Œํฌ์™€ ๊ทธ **์ƒํƒœ๊ณ„**๊ฐ€ ๊ฑด๊ฐ•ํ•˜๊ณ  **์ง€์† ๊ฐ€๋Šฅ**ํ•˜๊ฒŒ ์œ ์ง€๋˜๋„๋ก ๋•์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ์ด๋“ค์˜ ํ›„์›์€ FastAPI **์ปค๋ฎค๋‹ˆํ‹ฐ**(์—ฌ๋Ÿฌ๋ถ„)์— ๋Œ€ํ•œ ๊ฐ•ํ•œ ํ—Œ์‹ ์„ ๋ณด์—ฌ์ฃผ๋ฉฐ, **์ข‹์€ ์„œ๋น„์Šค**๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฒƒ๋ฟ ์•„๋‹ˆ๋ผ, ๊ฒฌ๊ณ ํ•˜๊ณ  ํ™œ๋ฐœํ•œ ํ”„๋ ˆ์ž„์›Œํฌ์ธ FastAPI๋ฅผ ์ง€์›ํ•˜๋Š” ๋ฐ์—๋„ ๊ด€์‹ฌ์ด ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๐Ÿ™‡
์˜ˆ๋ฅผ ๋“ค์–ด ๋‹ค์Œ์„ ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
* <a href="https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship" class="external-link" target="_blank">Speakeasy</a>
* <a href="https://www.stainless.com/?utm_source=fastapi&utm_medium=referral" class="external-link" target="_blank">Stainless</a>
* <a href="https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi" class="external-link" target="_blank">liblab</a>
* [Speakeasy](https://speakeasy.com/editor?utm_source=fastapi+repo&utm_medium=github+sponsorship)
* [Stainless](https://www.stainless.com/?utm_source=fastapi&utm_medium=referral)
* [liblab](https://developers.liblab.com/tutorials/sdk-for-fastapi?utm_source=fastapi)
์ด ์ค‘ ์ผ๋ถ€๋Š” ์˜คํ”ˆ ์†Œ์Šค์ด๊ฑฐ๋‚˜ ๋ฌด๋ฃŒ ํ‹ฐ์–ด๋ฅผ ์ œ๊ณตํ•˜๋ฏ€๋กœ, ๋น„์šฉ ๋ถ€๋‹ด ์—†์ด ์‚ฌ์šฉํ•ด ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ƒ์šฉ SDK ์ƒ์„ฑ๊ธฐ๋„ ์žˆ์œผ๋ฉฐ ์˜จ๋ผ์ธ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿค“
@ -42,7 +42,7 @@ FastAPI๋Š” **OpenAPI 3.1** ์‚ฌ์–‘์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๋ฏ€๋กœ, ์‚ฌ์šฉํ•˜๋Š”
{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
*path operation*์—์„œ ์š”์ฒญ ํŽ˜์ด๋กœ๋“œ์™€ ์‘๋‹ต ํŽ˜์ด๋กœ๋“œ์— ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋ธ์„ `Item`, `ResponseMessage` ๋ชจ๋ธ๋กœ ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•˜์„ธ์š”.
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ ์š”์ฒญ ํŽ˜์ด๋กœ๋“œ์™€ ์‘๋‹ต ํŽ˜์ด๋กœ๋“œ์— ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋ธ์„ `Item`, `ResponseMessage` ๋ชจ๋ธ๋กœ ์ •์˜ํ•˜๊ณ  ์žˆ๋‹ค๋Š” ์ ์— ์ฃผ๋ชฉํ•˜์„ธ์š”.
### API ๋ฌธ์„œ { #api-docs }
@ -66,7 +66,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
์ด ๋ช…๋ น์€ `./src/client`์— TypeScript SDK๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
<a href="https://heyapi.dev/openapi-ts/get-started" class="external-link" target="_blank">`@hey-api/openapi-ts` ์„ค์น˜ ๋ฐฉ๋ฒ•</a>๊ณผ <a href="https://heyapi.dev/openapi-ts/output" class="external-link" target="_blank">์ƒ์„ฑ๋œ ๊ฒฐ๊ณผ๋ฌผ</a>์€ ํ•ด๋‹น ์›น์‚ฌ์ดํŠธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[`@hey-api/openapi-ts` ์„ค์น˜ ๋ฐฉ๋ฒ•](https://heyapi.dev/openapi-ts/get-started)๊ณผ [์ƒ์„ฑ๋œ ๊ฒฐ๊ณผ๋ฌผ](https://heyapi.dev/openapi-ts/output)์€ ํ•ด๋‹น ์›น์‚ฌ์ดํŠธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
### SDK ์‚ฌ์šฉํ•˜๊ธฐ { #using-the-sdk }
@ -94,7 +94,7 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
## ํƒœ๊ทธ๊ฐ€ ์žˆ๋Š” FastAPI ์•ฑ { #fastapi-app-with-tags }
๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ FastAPI ์•ฑ์€ ๋” ์ปค์ง€๊ณ , ์„œ๋กœ ๋‹ค๋ฅธ *path operations* ๊ทธ๋ฃน์„ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ FastAPI ์•ฑ์€ ๋” ์ปค์ง€๊ณ , ์„œ๋กœ ๋‹ค๋ฅธ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ๊ทธ๋ฃน์„ ๋ถ„๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋  ๊ฐ€๋Šฅ์„ฑ์ด ํฝ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด **items** ์„น์…˜๊ณผ **users** ์„น์…˜์ด ์žˆ๊ณ , ์ด๋ฅผ ํƒœ๊ทธ๋กœ ๋ถ„๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -121,9 +121,9 @@ npx @hey-api/openapi-ts -i http://localhost:8000/openapi.json -o src/client
ItemsService.createItemItemsPost({name: "Plumbus", price: 5})
```
...์ด๋Š” ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ๊ธฐ๊ฐ€ ๊ฐ *path operation*์— ๋Œ€ํ•ด OpenAPI ๋‚ด๋ถ€์˜ **operation ID**๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
...์ด๋Š” ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ๊ธฐ๊ฐ€ ๊ฐ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์— ๋Œ€ํ•ด OpenAPI ๋‚ด๋ถ€์˜ **operation ID**๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.
OpenAPI๋Š” ๋ชจ๋“  *path operations* ์ „์ฒด์—์„œ operation ID๊ฐ€ ๊ฐ๊ฐ ์œ ์ผํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ FastAPI๋Š” operation ID๊ฐ€ ์œ ์ผํ•˜๋„๋ก **ํ•จ์ˆ˜ ์ด๋ฆ„**, **๊ฒฝ๋กœ**, **HTTP method/operation**์„ ์กฐํ•ฉํ•ด operation ID๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
OpenAPI๋Š” ๋ชจ๋“  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ์ „์ฒด์—์„œ operation ID๊ฐ€ ๊ฐ๊ฐ ์œ ์ผํ•ด์•ผ ํ•œ๋‹ค๊ณ  ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ FastAPI๋Š” operation ID๊ฐ€ ์œ ์ผํ•˜๋„๋ก **ํ•จ์ˆ˜ ์ด๋ฆ„**, **๊ฒฝ๋กœ**, **HTTP method/operation**์„ ์กฐํ•ฉํ•ด operation ID๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๋‹ค์Œ์—์„œ ์ด๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿค“
@ -133,15 +133,15 @@ OpenAPI๋Š” ๋ชจ๋“  *path operations* ์ „์ฒด์—์„œ operation ID๊ฐ€ ๊ฐ๊ฐ ์œ ์ผ
์ด ๊ฒฝ์šฐ operation ID๊ฐ€ ๋‹ค๋ฅธ ๋ฐฉ์‹์œผ๋กœ๋„ **์œ ์ผ**ํ•˜๋„๋ก ๋ณด์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ *path operation*์ด ํƒœ๊ทธ๋ฅผ ๊ฐ–๋„๋ก ํ•œ ๋‹ค์Œ, **ํƒœ๊ทธ**์™€ *path operation* **์ด๋ฆ„**(ํ•จ์ˆ˜ ์ด๋ฆ„)์„ ๊ธฐ๋ฐ˜์œผ๋กœ operation ID๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์ด ํƒœ๊ทธ๋ฅผ ๊ฐ–๋„๋ก ํ•œ ๋‹ค์Œ, **ํƒœ๊ทธ**์™€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* **์ด๋ฆ„**(ํ•จ์ˆ˜ ์ด๋ฆ„)์„ ๊ธฐ๋ฐ˜์œผ๋กœ operation ID๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
### ์œ ์ผ ID ์ƒ์„ฑ ํ•จ์ˆ˜ ์ปค์Šคํ„ฐ๋งˆ์ด์ง• { #custom-generate-unique-id-function }
FastAPI๋Š” ๊ฐ *path operation*์— ๋Œ€ํ•ด **์œ ์ผ ID**๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์ด๋Š” **operation ID** ๋ฐ ์š”์ฒญ/์‘๋‹ต์— ํ•„์š”ํ•œ ์ปค์Šคํ…€ ๋ชจ๋ธ ์ด๋ฆ„์—๋„ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
FastAPI๋Š” ๊ฐ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์— ๋Œ€ํ•ด **์œ ์ผ ID**๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์ด๋Š” **operation ID** ๋ฐ ์š”์ฒญ/์‘๋‹ต์— ํ•„์š”ํ•œ ์ปค์Šคํ…€ ๋ชจ๋ธ ์ด๋ฆ„์—๋„ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.
์ด ํ•จ์ˆ˜๋ฅผ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ•จ์ˆ˜๋Š” `APIRoute`๋ฅผ ๋ฐ›์•„ ๋ฌธ์ž์—ด์„ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์—์„œ๋Š” ์ฒซ ๋ฒˆ์งธ ํƒœ๊ทธ(๋Œ€๋ถ€๋ถ„ ํƒœ๊ทธ๋Š” ํ•˜๋‚˜๋งŒ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค)์™€ *path operation* ์ด๋ฆ„(ํ•จ์ˆ˜ ์ด๋ฆ„)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด ์•„๋ž˜์—์„œ๋Š” ์ฒซ ๋ฒˆ์งธ ํƒœ๊ทธ(๋Œ€๋ถ€๋ถ„ ํƒœ๊ทธ๋Š” ํ•˜๋‚˜๋งŒ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค)์™€ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ* ์ด๋ฆ„(ํ•จ์ˆ˜ ์ด๋ฆ„)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
๊ทธ ๋‹ค์Œ ์ด ์ปค์Šคํ…€ ํ•จ์ˆ˜๋ฅผ `generate_unique_id_function` ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ **FastAPI**์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -201,7 +201,7 @@ npx @hey-api/openapi-ts -i ./openapi.json -o src/client
๋˜ํ•œ ๋ชจ๋“  ๊ฒƒ์— ๋Œ€ํ•ด **์ธ๋ผ์ธ ์˜ค๋ฅ˜**๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋ฐฑ์—”๋“œ ์ฝ”๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ ๋’ค ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ **์žฌ์ƒ์„ฑ(regenerate)**ํ•˜๋ฉด, ์ƒˆ *path operations*๊ฐ€ ๋ฉ”์„œ๋“œ๋กœ ์ถ”๊ฐ€๋˜๊ณ  ๊ธฐ์กด ๊ฒƒ์€ ์ œ๊ฑฐ๋˜๋ฉฐ, ๊ทธ ๋ฐ–์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋„ ์ƒ์„ฑ๋œ ์ฝ”๋“œ์— ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๐Ÿค“
๊ทธ๋ฆฌ๊ณ  ๋ฐฑ์—”๋“œ ์ฝ”๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•œ ๋’ค ํ”„๋ก ํŠธ์—”๋“œ๋ฅผ **์žฌ์ƒ์„ฑ(regenerate)**ํ•˜๋ฉด, ์ƒˆ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๊ฐ€ ๋ฉ”์„œ๋“œ๋กœ ์ถ”๊ฐ€๋˜๊ณ  ๊ธฐ์กด ๊ฒƒ์€ ์ œ๊ฑฐ๋˜๋ฉฐ, ๊ทธ ๋ฐ–์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋„ ์ƒ์„ฑ๋œ ์ฝ”๋“œ์— ๋ฐ˜์˜๋ฉ๋‹ˆ๋‹ค. ๐Ÿค“
์ด๋Š” ๋ฌด์–ธ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด ๊ทธ ๋ณ€๊ฒฝ์ด ํด๋ผ์ด์–ธํŠธ ์ฝ”๋“œ์—๋„ ์ž๋™์œผ๋กœ **๋ฐ˜์˜**๋œ๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ๋˜ํ•œ ํด๋ผ์ด์–ธํŠธ๋ฅผ **๋นŒ๋“œ(build)**ํ•˜๋ฉด ์‚ฌ์šฉ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ **๋ถˆ์ผ์น˜(mismatch)**ํ•  ๊ฒฝ์šฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

4
docs/ko/docs/advanced/index.md

@ -2,7 +2,7 @@
## ์ถ”๊ฐ€ ๊ธฐ๋Šฅ { #additional-features }
๋ฉ”์ธ [์ž์Šต์„œ - ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ](../tutorial/index.md){.internal-link target=_blank}๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด **FastAPI**์˜ ๋ชจ๋“  ์ฃผ์š” ๊ธฐ๋Šฅ์„ ๋‘˜๋Ÿฌ๋ณด์‹œ๊ธฐ์— ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
๋ฉ”์ธ [์ž์Šต์„œ - ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ](../tutorial/index.md)๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด **FastAPI**์˜ ๋ชจ๋“  ์ฃผ์š” ๊ธฐ๋Šฅ์„ ๋‘˜๋Ÿฌ๋ณด์‹œ๊ธฐ์— ์ถฉ๋ถ„ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ด์–ด์ง€๋Š” ์žฅ์—์„œ๋Š” ์—ฌ๋Ÿฌ๋ถ„์ด ๋‹ค๋ฅธ ์˜ต์…˜, ๊ตฌ์„ฑ ๋ฐ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -16,6 +16,6 @@
## ์ž์Šต์„œ๋ฅผ ๋จผ์ € ์ฝ์œผ์‹ญ์‹œ์˜ค { #read-the-tutorial-first }
์—ฌ๋Ÿฌ๋ถ„์€ ๋ฉ”์ธ [์ž์Šต์„œ - ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ](../tutorial/index.md){.internal-link target=_blank}์˜ ์ง€์‹์œผ๋กœ **FastAPI**์˜ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๋Ÿฌ๋ถ„์€ ๋ฉ”์ธ [์ž์Šต์„œ - ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ](../tutorial/index.md)์˜ ์ง€์‹์œผ๋กœ **FastAPI**์˜ ๋Œ€๋ถ€๋ถ„์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด์–ด์ง€๋Š” ์žฅ๋“ค์€ ์—ฌ๋Ÿฌ๋ถ„์ด ๋ฉ”์ธ ์ž์Šต์„œ - ์‚ฌ์šฉ์ž ์•ˆ๋‚ด์„œ๋ฅผ ์ด๋ฏธ ์ฝ์œผ์…จ์œผ๋ฉฐ ์ฃผ์š” ์•„์ด๋””์–ด๋ฅผ ์•Œ๊ณ  ๊ณ„์‹ ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.

10
docs/ko/docs/advanced/middleware.md

@ -1,8 +1,8 @@
# ๊ณ ๊ธ‰ Middleware { #advanced-middleware }
๋ฉ”์ธ ํŠœํ† ๋ฆฌ์–ผ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— [์ปค์Šคํ…€ Middleware](../tutorial/middleware.md){.internal-link target=_blank}๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค.
๋ฉ”์ธ ํŠœํ† ๋ฆฌ์–ผ์—์„œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— [์ปค์Šคํ…€ Middleware](../tutorial/middleware.md)๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  [`CORSMiddleware`๋กœ CORS ์ฒ˜๋ฆฌํ•˜๊ธฐ](../tutorial/cors.md){.internal-link target=_blank}๋„ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  [`CORSMiddleware`๋กœ CORS ์ฒ˜๋ฆฌํ•˜๊ธฐ](../tutorial/cors.md)๋„ ์ฝ์—ˆ์Šต๋‹ˆ๋‹ค.
์ด ์„น์…˜์—์„œ๋Š” ๋‹ค๋ฅธ middleware๋“ค์„ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
@ -91,7 +91,7 @@ HTTP Host Header ๊ณต๊ฒฉ์„ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด, ๋“ค์–ด์˜ค๋Š” ๋ชจ๋“  ์š”์ฒญ์—
์˜ˆ๋ฅผ ๋“ค์–ด:
* <a href="https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py" class="external-link" target="_blank">Uvicorn์˜ `ProxyHeadersMiddleware`</a>
* <a href="https://github.com/florimondmanca/msgpack-asgi" class="external-link" target="_blank">MessagePack</a>
* [Uvicorn์˜ `ProxyHeadersMiddleware`](https://github.com/encode/uvicorn/blob/master/uvicorn/middleware/proxy_headers.py)
* [MessagePack](https://github.com/florimondmanca/msgpack-asgi)
์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋‹ค๋ฅธ middleware๋ฅผ ๋ณด๋ ค๋ฉด <a href="https://www.starlette.dev/middleware/" class="external-link" target="_blank">Starlette์˜ Middleware ๋ฌธ์„œ</a>์™€ <a href="https://github.com/florimondmanca/awesome-asgi" class="external-link" target="_blank">ASGI Awesome List</a>๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋‹ค๋ฅธ middleware๋ฅผ ๋ณด๋ ค๋ฉด [Starlette์˜ Middleware ๋ฌธ์„œ](https://www.starlette.dev/middleware/)์™€ [ASGI Awesome List](https://github.com/florimondmanca/awesome-asgi)๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

10
docs/ko/docs/advanced/openapi-callbacks.md

@ -35,7 +35,7 @@
/// tip | ํŒ
`callback_url` ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” Pydantic์˜ <a href="https://docs.pydantic.dev/latest/api/networks/" class="external-link" target="_blank">Url</a> ํƒ€์ž…์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
`callback_url` ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” Pydantic์˜ [Url](https://docs.pydantic.dev/latest/api/networks/) ํƒ€์ž…์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
///
@ -66,7 +66,7 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
์‹ค์ œ ์ฝœ๋ฐฑ์€ ๋‹จ์ง€ HTTP ์š”์ฒญ์ž…๋‹ˆ๋‹ค.
์ฝœ๋ฐฑ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” <a href="https://www.python-httpx.org" class="external-link" target="_blank">HTTPX</a>๋‚˜ <a href="https://requests.readthedocs.io/" class="external-link" target="_blank">Requests</a> ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฝœ๋ฐฑ์„ ์ง์ ‘ ๊ตฌํ˜„ํ•  ๋•Œ๋Š” [HTTPX](https://www.python-httpx.org)๋‚˜ [Requests](https://requests.readthedocs.io/) ๊ฐ™์€ ๊ฒƒ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
///
@ -106,11 +106,11 @@ httpx.post(callback_url, json={"description": "Invoice paid", "paid": True})
์ผ๋ฐ˜์ ์ธ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์™€์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ 2๊ฐ€์ง€์ž…๋‹ˆ๋‹ค:
* ์‹ค์ œ ์ฝ”๋“œ๋ฅผ ๊ฐ€์งˆ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ๋ถ„์˜ ์•ฑ์€ ์ด ์ฝ”๋“œ๋ฅผ ์ ˆ๋Œ€ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์ด๋Š” *external API*๋ฅผ ๋ฌธ์„œํ™”ํ•˜๋Š” ๋ฐ๋งŒ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•จ์ˆ˜๋Š” ๊ทธ๋ƒฅ `pass`๋งŒ ์žˆ์–ด๋„ ๋ฉ๋‹ˆ๋‹ค.
* *path*์—๋Š” <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>(์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ์ฐธ๊ณ )์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด *์—ฌ๋Ÿฌ๋ถ„์˜ API*๋กœ ๋ณด๋‚ด์ง„ ์›๋ž˜ ์š”์ฒญ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ์ผ๋ถ€ ๊ฐ’์„ ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
* *path*์—๋Š” [OpenAPI 3 ํ‘œํ˜„์‹](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)(์ž์„ธํ•œ ๋‚ด์šฉ์€ ์•„๋ž˜ ์ฐธ๊ณ )์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด *์—ฌ๋Ÿฌ๋ถ„์˜ API*๋กœ ๋ณด๋‚ด์ง„ ์›๋ž˜ ์š”์ฒญ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ์ผ๋ถ€ ๊ฐ’์„ ๋ณ€์ˆ˜๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
### ์ฝœ๋ฐฑ ๊ฒฝ๋กœ ํ‘œํ˜„์‹ { #the-callback-path-expression }
์ฝœ๋ฐฑ *path*๋Š” *์—ฌ๋Ÿฌ๋ถ„์˜ API*๋กœ ๋ณด๋‚ด์ง„ ์›๋ž˜ ์š”์ฒญ์˜ ์ผ๋ถ€๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” <a href="https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression" class="external-link" target="_blank">OpenAPI 3 expression</a>์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฝœ๋ฐฑ *path*๋Š” *์—ฌ๋Ÿฌ๋ถ„์˜ API*๋กœ ๋ณด๋‚ด์ง„ ์›๋ž˜ ์š”์ฒญ์˜ ์ผ๋ถ€๋ฅผ ํฌํ•จํ•  ์ˆ˜ ์žˆ๋Š” [OpenAPI 3 ํ‘œํ˜„์‹](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.1.0.md#key-expression)์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ, ๋‹ค์Œ `str`์ž…๋‹ˆ๋‹ค:
@ -179,7 +179,7 @@ https://www.external.org/events/invoices/2expen51ve
### ๋ฌธ์„œ ํ™•์ธํ•˜๊ธฐ { #check-the-docs }
์ด์ œ ์•ฑ์„ ์‹คํ–‰ํ•˜๊ณ  <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>๋กœ ์ด๋™ํ•˜์„ธ์š”.
์ด์ œ ์•ฑ์„ ์‹คํ–‰ํ•˜๊ณ  [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)๋กœ ์ด๋™ํ•˜์„ธ์š”.
*๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์— ๋Œ€ํ•ด "Callbacks" ์„น์…˜์„ ํฌํ•จํ•œ ๋ฌธ์„œ๊ฐ€ ํ‘œ์‹œ๋˜๋ฉฐ, *external API*๊ฐ€ ์–ด๋–ค ํ˜•ํƒœ์—ฌ์•ผ ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

2
docs/ko/docs/advanced/openapi-webhooks.md

@ -48,7 +48,7 @@ webhook์—์„œ๋Š” ์‹ค์ œ๋กœ(`/items/` ๊ฐ™์€) *๊ฒฝ๋กœ(path)*๋ฅผ ์„ ์–ธํ•˜์ง€ ์•Š
### ๋ฌธ์„œ ํ™•์ธํ•˜๊ธฐ { #check-the-docs }
์ด์ œ ์•ฑ์„ ์‹คํ–‰ํ•˜๊ณ  <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>๋กœ ์ด๋™ํ•˜์„ธ์š”.
์ด์ œ ์•ฑ์„ ์‹คํ–‰ํ•˜๊ณ  [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)๋กœ ์ด๋™ํ•˜์„ธ์š”.
๋ฌธ์„œ์— ์ผ๋ฐ˜์ ์ธ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๊ฐ€ ๋ณด์ด๊ณ , ์ด์ œ๋Š” ์ผ๋ถ€ **webhooks**๋„ ํ•จ๊ป˜ ๋ณด์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค:

6
docs/ko/docs/advanced/path-operation-advanced-configuration.md

@ -60,7 +60,7 @@ OpenAPI์— ์‚ฌ์šฉํ•  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์˜ docstring ์ค„ ์ˆ˜๋ฅผ ์ œํ•œํ• 
๋ชจ๋ธ, ์ƒํƒœ ์ฝ”๋“œ ๋“ฑ๊ณผ ํ•จ๊ป˜ ์ถ”๊ฐ€ ์‘๋‹ต๋„ ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด์— ๋Œ€ํ•œ ๋ฌธ์„œ์˜ ์ „์ฒด ์žฅ์ด ์žˆ์œผ๋‹ˆ, [OpenAPI์˜ ์ถ”๊ฐ€ ์‘๋‹ต](additional-responses.md){.internal-link target=_blank}์—์„œ ์ฝ์–ด๋ณด์„ธ์š”.
์ด์— ๋Œ€ํ•œ ๋ฌธ์„œ์˜ ์ „์ฒด ์žฅ์ด ์žˆ์œผ๋‹ˆ, [OpenAPI์˜ ์ถ”๊ฐ€ ์‘๋‹ต](additional-responses.md)์—์„œ ์ฝ์–ด๋ณด์„ธ์š”.
## OpenAPI Extra { #openapi-extra }
@ -68,7 +68,7 @@ OpenAPI์— ์‚ฌ์šฉํ•  *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ ํ•จ์ˆ˜*์˜ docstring ์ค„ ์ˆ˜๋ฅผ ์ œํ•œํ• 
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ
OpenAPI ๋ช…์„ธ์—์„œ๋Š” ์ด๋ฅผ <a href="https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object" class="external-link" target="_blank">Operation Object</a>๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
OpenAPI ๋ช…์„ธ์—์„œ๋Š” ์ด๋ฅผ [Operation Object](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#operation-object)๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
///
@ -82,7 +82,7 @@ OpenAPI ๋ช…์„ธ์—์„œ๋Š” ์ด๋ฅผ <a href="https://github.com/OAI/OpenAPI-Specifica
์ด๋Š” ์ €์ˆ˜์ค€ ํ™•์žฅ ์ง€์ ์ž…๋‹ˆ๋‹ค.
์ถ”๊ฐ€ ์‘๋‹ต๋งŒ ์„ ์–ธํ•˜๋ฉด ๋œ๋‹ค๋ฉด, ๋” ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์€ [OpenAPI์˜ ์ถ”๊ฐ€ ์‘๋‹ต](additional-responses.md){.internal-link target=_blank}์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
์ถ”๊ฐ€ ์‘๋‹ต๋งŒ ์„ ์–ธํ•˜๋ฉด ๋œ๋‹ค๋ฉด, ๋” ํŽธ๋ฆฌํ•œ ๋ฐฉ๋ฒ•์€ [OpenAPI์˜ ์ถ”๊ฐ€ ์‘๋‹ต](additional-responses.md)์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
///

2
docs/ko/docs/advanced/response-change-status-code.md

@ -1,6 +1,6 @@
# ์‘๋‹ต - ์ƒํƒœ ์ฝ”๋“œ ๋ณ€๊ฒฝ { #response-change-status-code }
๊ธฐ๋ณธ [์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ ์„ค์ •](../tutorial/response-status-code.md){.internal-link target=_blank}์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฑธ ์ด๋ฏธ ์•Œ๊ณ  ๊ณ„์‹ค ๊ฒ๋‹ˆ๋‹ค.
๊ธฐ๋ณธ [์‘๋‹ต ์ƒํƒœ ์ฝ”๋“œ ์„ค์ •](../tutorial/response-status-code.md)์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๊ฑธ ์ด๋ฏธ ์•Œ๊ณ  ๊ณ„์‹ค ๊ฒ๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๊ธฐ๋ณธ ์„ค์ •๊ณผ ๋‹ค๋ฅธ ์ƒํƒœ ์ฝ”๋“œ๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•  ๋•Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

6
docs/ko/docs/advanced/response-cookies.md

@ -20,13 +20,13 @@
์ฝ”๋“œ์—์„œ `Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ๋•Œ๋„ ์ฟ ํ‚ค๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด [Response๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md){.internal-link target=_blank}์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์‘๋‹ต์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด [Response๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md)์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์‘๋‹ต์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ ๋‹ค์Œ ์ฟ ํ‚ค๋ฅผ ์„ค์ •ํ•˜๊ณ  ๋ฐ˜ํ™˜ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค:
{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
/// tip | ํŒ
/// tip
`Response` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ, FastAPI๋Š” ์ด๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•œ๋‹ค๋Š” ์ ์— ์œ ์˜ํ•˜์„ธ์š”.
@ -48,4 +48,4 @@
///
์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์˜ต์…˜์€ <a href="https://www.starlette.dev/responses/#set-cookie" class="external-link" target="_blank">Starlette์˜ ๋ฌธ์„œ</a>์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜์™€ ์˜ต์…˜์€ [Starlette์˜ ๋ฌธ์„œ](https://www.starlette.dev/responses/#set-cookie)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

34
docs/ko/docs/advanced/response-directly.md

@ -2,19 +2,23 @@
**FastAPI**์—์„œ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ(path operation)*๋ฅผ ์ƒ์„ฑํ•  ๋•Œ, ์ผ๋ฐ˜์ ์œผ๋กœ `dict`, `list`, Pydantic ๋ชจ๋ธ, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ชจ๋ธ ๋“ฑ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ธฐ๋ณธ์ ์œผ๋กœ **FastAPI**๋Š” [JSON ํ˜ธํ™˜ ๊ฐ€๋Šฅ ์ธ์ฝ”๋”](../tutorial/encoder.md){.internal-link target=_blank}์— ์„ค๋ช…๋œ `jsonable_encoder`๋ฅผ ์‚ฌ์šฉํ•ด ํ•ด๋‹น ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ž๋™์œผ๋กœ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
[์‘๋‹ต ๋ชจ๋ธ](../tutorial/response-model.md)์„ ์„ ์–ธํ•˜๋ฉด FastAPI๋Š” Pydantic์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ ๋‹ค์Œ, ๋‚ด๋ถ€์ ์œผ๋กœ๋Š” JSON ํ˜ธํ™˜ ๋ฐ์ดํ„ฐ(์˜ˆ: `dict`)๋ฅผ `JSONResponse`์— ๋„ฃ์–ด ํด๋ผ์ด์–ธํŠธ๋กœ ์‘๋‹ต์„ ์ „์†กํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
์‘๋‹ต ๋ชจ๋ธ์„ ์„ ์–ธํ•˜์ง€ ์•Š์œผ๋ฉด, FastAPI๋Š” [JSON ํ˜ธํ™˜ ๊ฐ€๋Šฅ ์ธ์ฝ”๋”](../tutorial/encoder.md)์— ์„ค๋ช…๋œ `jsonable_encoder`๋ฅผ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜ํ•˜๊ณ  ์ด๋ฅผ `JSONResponse`์— ๋„ฃ์Šต๋‹ˆ๋‹ค.
ํ•˜์ง€๋งŒ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*์—์„œ `JSONResponse`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ `JSONResponse`๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•ด ๋ฐ˜ํ™˜ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด, ์‚ฌ์šฉ์ž ์ •์˜ ํ—ค๋”๋‚˜ ์ฟ ํ‚ค๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
/// tip | ํŒ
์ผ๋ฐ˜์ ์œผ๋กœ `JSONResponse`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค [์‘๋‹ต ๋ชจ๋ธ](../tutorial/response-model.md)์„ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ์„ฑ๋Šฅ์ด ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด Pydantic์ด Rust์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค.
///
## `Response` ๋ฐ˜ํ™˜ํ•˜๊ธฐ { #return-a-response }
์‚ฌ์‹ค, `Response` ๋˜๋Š” ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`Response` ๋˜๋Š” ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
/// tip | ํŒ
/// info | ์ •๋ณด
`JSONResponse` ์ž์ฒด๋„ `Response`์˜ ํ•˜์œ„ ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
@ -26,6 +30,8 @@ Pydantic ๋ชจ๋ธ๋กœ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋‚ด์šฉ์„ ๋‹ค๋ฅธ
์ด๋กœ ์ธํ•ด ๋งŽ์€ ์œ ์—ฐ์„ฑ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์–ด๋–ค ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด๋“  ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๊ณ , ๋ฐ์ดํ„ฐ ์„ ์–ธ์ด๋‚˜ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋ฅผ ์žฌ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ๋งŽ์€ ์ฑ…์ž„๋„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์˜ฌ๋ฐ”๋ฅด๊ณ , ์˜ฌ๋ฐ”๋ฅธ ํ˜•์‹์ด๋ฉฐ, ์ง๋ ฌํ™”๊ฐ€ ๊ฐ€๋Šฅํ•˜๋„๋ก ์—ฌ๋Ÿฌ๋ถ„์ด ์ง์ ‘ ๋ณด์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
## `Response`์—์„œ `jsonable_encoder` ์‚ฌ์šฉํ•˜๊ธฐ { #using-the-jsonable-encoder-in-a-response }
**FastAPI**๋Š” ๋ฐ˜ํ™˜ํ•˜๋Š” `Response`์— ์•„๋ฌด๋Ÿฐ ๋ณ€๊ฒฝ๋„ ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ๊ทธ ๋‚ด์šฉ์ด ์ค€๋น„๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
@ -50,16 +56,28 @@ Pydantic ๋ชจ๋ธ๋กœ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋‚ด์šฉ์„ ๋‹ค๋ฅธ
์ด์ œ, ์ด๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž ์ •์˜ ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด <a href="https://en.wikipedia.org/wiki/XML" class="external-link" target="_blank">XML</a> ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด [XML](https://en.wikipedia.org/wiki/XML) ์‘๋‹ต์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์‹ถ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.
XML ๋‚ด์šฉ์„ ๋ฌธ์ž์—ด์— ๋„ฃ๊ณ , ์ด๋ฅผ `Response`์— ๋„ฃ์–ด ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
## ์‘๋‹ต ๋ชจ๋ธ ๋™์ž‘ ๋ฐฉ์‹ { #how-a-response-model-works }
๊ฒฝ๋กœ ์ฒ˜๋ฆฌ์—์„œ [์‘๋‹ต ๋ชจ๋ธ - ๋ฐ˜ํ™˜ ํƒ€์ž…](../tutorial/response-model.md)์„ ์„ ์–ธํ•˜๋ฉด **FastAPI**๋Š” Pydantic์„ ์‚ฌ์šฉํ•ด ๋ฐ์ดํ„ฐ๋ฅผ JSON์œผ๋กœ ์ง๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค.
{* ../../docs_src/response_model/tutorial001_01_py310.py hl[16,21] *}
์ด๋Š” Rust ์ธก์—์„œ ์ฒ˜๋ฆฌ๋˜๋ฏ€๋กœ, ์ผ๋ฐ˜์ ์ธ Python๊ณผ `JSONResponse` ํด๋ž˜์Šค๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ์„ฑ๋Šฅ์ด ํ›จ์”ฌ ์ข‹์Šต๋‹ˆ๋‹ค.
`response_model` ๋˜๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž…์„ ์‚ฌ์šฉํ•  ๋•Œ FastAPI๋Š” `jsonable_encoder`๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€ํ™˜(์ด๋Š” ๋” ๋А๋ฆฝ๋‹ˆ๋‹ค)ํ•˜์ง€๋„ ์•Š๊ณ , `JSONResponse` ํด๋ž˜์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋„ ์•Š์Šต๋‹ˆ๋‹ค.
๋Œ€์‹  ์‘๋‹ต ๋ชจ๋ธ(๋˜๋Š” ๋ฐ˜ํ™˜ ํƒ€์ž…)์„ ์‚ฌ์šฉํ•ด Pydantic์ด ์ƒ์„ฑํ•œ JSON ๋ฐ”์ดํŠธ๋ฅผ ๊ฐ€์ ธ์™€, JSON์— ๋งž๋Š” ๋ฏธ๋””์–ด ํƒ€์ž…(`application/json`)์„ ๊ฐ€์ง„ `Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.
## ์ฐธ๊ณ  ์‚ฌํ•ญ { #notes }
`Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ๋•Œ, ๊ทธ ๋ฐ์ดํ„ฐ๋Š” ์ž๋™์œผ๋กœ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๋˜๊ฑฐ๋‚˜, ๋ณ€ํ™˜(์ง๋ ฌํ™”)๋˜๊ฑฐ๋‚˜, ๋ฌธ์„œํ™”๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ [OpenAPI์—์„œ ์ถ”๊ฐ€ ์‘๋‹ต](additional-responses.md){.internal-link target=_blank}์—์„œ ์„ค๋ช…๋œ ๋Œ€๋กœ ๋ฌธ์„œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฌ๋‚˜ [OpenAPI์—์„œ ์ถ”๊ฐ€ ์‘๋‹ต](additional-responses.md)์—์„œ ์„ค๋ช…๋œ ๋Œ€๋กœ ๋ฌธ์„œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ดํ›„ ์„น์…˜์—์„œ ์ž๋™ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜, ๋ฌธ์„œํ™” ๋“ฑ์„ ๊ณ„์† ์‚ฌ์šฉํ•˜๋ฉด์„œ ์ด๋Ÿฌํ•œ ์‚ฌ์šฉ์ž ์ •์˜ `Response`๋ฅผ ์‚ฌ์šฉํ•˜๋Š”/์„ ์–ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

6
docs/ko/docs/advanced/response-headers.md

@ -20,7 +20,7 @@
`Response`๋ฅผ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•  ๋•Œ์—๋„ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md){.internal-link target=_blank}์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๊ณ , ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜์„ธ์š”:
[์‘๋‹ต์„ ์ง์ ‘ ๋ฐ˜ํ™˜ํ•˜๊ธฐ](response-directly.md)์— ์„ค๋ช…ํ•œ ๋Œ€๋กœ ์‘๋‹ต์„ ์ƒ์„ฑํ•˜๊ณ , ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ ๋งค๊ฐœ๋ณ€์ˆ˜๋กœ ์ „๋‹ฌํ•˜์„ธ์š”:
{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
@ -36,6 +36,6 @@
## ์ปค์Šคํ…€ ํ—ค๋” { #custom-headers }
<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers" class="external-link" target="_blank">`X-` ์ ‘๋‘์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ</a> ์ปค์Šคํ…€ ์‚ฌ์„ค ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.
์ปค์Šคํ…€ ์‚ฌ์„ค ํ—ค๋”๋Š” [`X-` ์ ‘๋‘์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers) ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.
ํ•˜์ง€๋งŒ, ์—ฌ๋Ÿฌ๋ถ„์ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณผ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜๋Š” ์ปค์Šคํ…€ ํ—ค๋”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, CORS ์„ค์ •์— ์ด๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค([CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md){.internal-link target=_blank}์—์„œ ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”). <a href="https://www.starlette.dev/middleware/#corsmiddleware" class="external-link" target="_blank">Starlette์˜ CORS ๋ฌธ์„œ</a>์— ๋ฌธ์„œํ™”๋œ `expose_headers` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.
ํ•˜์ง€๋งŒ, ์—ฌ๋Ÿฌ๋ถ„์ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ๋ณผ ์ˆ˜ ์žˆ๊ธฐ๋ฅผ ์›ํ•˜๋Š” ์ปค์Šคํ…€ ํ—ค๋”๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, CORS ์„ค์ •์— ์ด๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค([CORS (Cross-Origin Resource Sharing)](../tutorial/cors.md)์—์„œ ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”). [Starlette์˜ CORS ๋ฌธ์„œ](https://www.starlette.dev/middleware/#corsmiddleware)์— ๋ฌธ์„œํ™”๋œ `expose_headers` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์„ธ์š”.

4
docs/ko/docs/advanced/security/http-basic-auth.md

@ -32,7 +32,7 @@ HTTP Basic Auth์—์„œ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‚ฌ์šฉ์ž๋ช…๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€
dependency๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž๋ช…๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ์ง€ ํ™•์ธํ•˜์„ธ์š”.
์ด๋ฅผ ์œ„ํ•ด Python ํ‘œ์ค€ ๋ชจ๋“ˆ <a href="https://docs.python.org/3/library/secrets.html" class="external-link" target="_blank">`secrets`</a>๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž๋ช…๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด Python ํ‘œ์ค€ ๋ชจ๋“ˆ [`secrets`](https://docs.python.org/3/library/secrets.html)๋ฅผ ์‚ฌ์šฉํ•ด ์‚ฌ์šฉ์ž๋ช…๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
`secrets.compare_digest()`๋Š” `bytes` ๋˜๋Š” ASCII ๋ฌธ์ž(์˜์–ด์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ฌธ์ž)๋งŒ ํฌํ•จํ•œ `str`์„ ๋ฐ›์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, `Sebastiรกn`์˜ `รก` ๊ฐ™์€ ๋ฌธ์ž๊ฐ€ ์žˆ์œผ๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
@ -52,7 +52,7 @@ if not (credentials.username == "stanleyjobson") or not (credentials.password ==
ํ•˜์ง€๋งŒ `secrets.compare_digest()`๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด "timing attacks"๋ผ๊ณ  ๋ถˆ๋ฆฌ๋Š” ํ•œ ์œ ํ˜•์˜ ๊ณต๊ฒฉ์— ๋Œ€ํ•ด ์•ˆ์ „ํ•ด์ง‘๋‹ˆ๋‹ค.
### Timing Attacks { #timing-attacks }
### ํƒ€์ด๋ฐ ๊ณต๊ฒฉ { #timing-attacks }
๊ทธ๋ ‡๋‹ค๋ฉด "timing attack"์ด๋ž€ ๋ฌด์—‡์ผ๊นŒ์š”?

4
docs/ko/docs/advanced/security/index.md

@ -2,7 +2,7 @@
## ์ถ”๊ฐ€ ๊ธฐ๋Šฅ { #additional-features }
[ํŠœํ† ๋ฆฌ์–ผ - ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ: ๋ณด์•ˆ](../../tutorial/security/index.md){.internal-link target=_blank}์—์„œ ๋‹ค๋ฃฌ ๋‚ด์šฉ ์™ธ์—๋„, ๋ณด์•ˆ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
[ํŠœํ† ๋ฆฌ์–ผ - ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ: ๋ณด์•ˆ](../../tutorial/security/index.md)์—์„œ ๋‹ค๋ฃฌ ๋‚ด์šฉ ์™ธ์—๋„, ๋ณด์•ˆ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
/// tip | ํŒ
@ -14,6 +14,6 @@
## ๋จผ์ € ํŠœํ† ๋ฆฌ์–ผ ์ฝ๊ธฐ { #read-the-tutorial-first }
๋‹ค์Œ ์„น์…˜์€ ์ฃผ์š” [ํŠœํ† ๋ฆฌ์–ผ - ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ: ๋ณด์•ˆ](../../tutorial/security/index.md){.internal-link target=_blank}์„ ์ด๋ฏธ ์ฝ์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
๋‹ค์Œ ์„น์…˜์€ ์ฃผ์š” [ํŠœํ† ๋ฆฌ์–ผ - ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ: ๋ณด์•ˆ](../../tutorial/security/index.md)์„ ์ด๋ฏธ ์ฝ์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค.
๋ชจ๋‘ ๋™์ผํ•œ ๊ฐœ๋…์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.

16
docs/ko/docs/advanced/settings.md

@ -8,7 +8,7 @@
/// tip | ํŒ
ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด [ํ™˜๊ฒฝ ๋ณ€์ˆ˜](../environment-variables.md){.internal-link target=_blank}๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”.
ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด [ํ™˜๊ฒฝ ๋ณ€์ˆ˜](../environment-variables.md)๋ฅผ ์ฝ์–ด๋ณด์„ธ์š”.
///
@ -20,11 +20,11 @@
## Pydantic `Settings` { #pydantic-settings }
๋‹คํ–‰ํžˆ Pydantic์€ <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/" class="external-link" target="_blank">Pydantic: Settings management</a>๋ฅผ ํ†ตํ•ด ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ์˜ค๋Š” ์ด๋Ÿฌํ•œ ์„ค์ •์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ›Œ๋ฅญํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
๋‹คํ–‰ํžˆ Pydantic์€ ํ™˜๊ฒฝ ๋ณ€์ˆ˜์—์„œ ์˜ค๋Š” ์ด๋Ÿฌํ•œ ์„ค์ •์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ํ›Œ๋ฅญํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ [Pydantic: Settings ๊ด€๋ฆฌ](https://docs.pydantic.dev/latest/concepts/pydantic_settings/)๋กœ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
### `pydantic-settings` ์„ค์น˜ํ•˜๊ธฐ { #install-pydantic-settings }
๋จผ์ € [๊ฐ€์ƒ ํ™˜๊ฒฝ](../virtual-environments.md){.internal-link target=_blank}์„ ๋งŒ๋“ค๊ณ  ํ™œ์„ฑํ™”ํ•œ ๋‹ค์Œ, `pydantic-settings` ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”:
๋จผ์ € [๊ฐ€์ƒ ํ™˜๊ฒฝ](../virtual-environments.md)์„ ๋งŒ๋“ค๊ณ  ํ™œ์„ฑํ™”ํ•œ ๋‹ค์Œ, `pydantic-settings` ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”:
<div class="termy">
@ -100,7 +100,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
## ๋‹ค๋ฅธ ๋ชจ๋“ˆ์˜ ์„ค์ • { #settings-in-another-module }
[Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ, ์„ค์ •์„ ๋‹ค๋ฅธ ๋ชจ๋“ˆ ํŒŒ์ผ์— ๋„ฃ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
[๋” ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ์—ฌ๋Ÿฌ ํŒŒ์ผ](../tutorial/bigger-applications.md)์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ, ์„ค์ •์„ ๋‹ค๋ฅธ ๋ชจ๋“ˆ ํŒŒ์ผ์— ๋„ฃ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
์˜ˆ๋ฅผ ๋“ค์–ด `config.py` ํŒŒ์ผ์„ ๋‹ค์Œ์ฒ˜๋Ÿผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -112,7 +112,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
/// tip | ํŒ
[Bigger Applications - Multiple Files](../tutorial/bigger-applications.md){.internal-link target=_blank}์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ `__init__.py` ํŒŒ์ผ๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
[๋” ํฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ์—ฌ๋Ÿฌ ํŒŒ์ผ](../tutorial/bigger-applications.md)์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ `__init__.py` ํŒŒ์ผ๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
///
@ -172,7 +172,7 @@ $ ADMIN_EMAIL="[email protected]" APP_NAME="ChimichangApp" fastapi run main.p
///
Pydantic์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋Ÿฐ ์œ ํ˜•์˜ ํŒŒ์ผ์—์„œ ์ฝ๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ <a href="https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support" class="external-link" target="_blank">Pydantic Settings: Dotenv (.env) support</a>๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
Pydantic์€ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด ์ด๋Ÿฐ ์œ ํ˜•์˜ ํŒŒ์ผ์—์„œ ์ฝ๋Š” ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [Pydantic Settings: Dotenv (.env) ์ง€์›](https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.
/// tip | ํŒ
@ -197,7 +197,7 @@ APP_NAME="ChimichangApp"
/// tip | ํŒ
`model_config` ์†์„ฑ์€ Pydantic ์„ค์ •์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ <a href="https://docs.pydantic.dev/latest/concepts/config/" class="external-link" target="_blank">Pydantic: Concepts: Configuration</a>๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.
`model_config` ์†์„ฑ์€ Pydantic ์„ค์ •์„ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ [Pydantic: ๊ฐœ๋…: ๊ตฌ์„ฑ](https://docs.pydantic.dev/latest/concepts/config/)์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.
///
@ -291,7 +291,7 @@ participant execute as Execute function
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฑฐ์˜ ์ „์—ญ ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์˜์กด์„ฑ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์‰ฝ๊ฒŒ overrideํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`@lru_cache`๋Š” Python ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ `functools`์— ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ž์„ธํ•œ ๋‚ด์šฉ์€ <a href="https://docs.python.org/3/library/functools.html#functools.lru_cache" class="external-link" target="_blank">`@lru_cache`์— ๋Œ€ํ•œ Python ๋ฌธ์„œ</a>์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`@lru_cache`๋Š” Python ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ `functools`์— ํฌํ•จ๋˜์–ด ์žˆ์œผ๋ฉฐ, ์ž์„ธํ•œ ๋‚ด์šฉ์€ [`@lru_cache`์— ๋Œ€ํ•œ Python ๋ฌธ์„œ](https://docs.python.org/3/library/functools.html#functools.lru_cache)์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
## ์ •๋ฆฌ { #recap }

34
docs/ko/docs/advanced/sub-applications.md

@ -1,10 +1,10 @@
# ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ - ๋งˆ์šดํŠธ { #sub-applications-mounts }
# ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ๋งˆ์šดํŠธ { #sub-applications-mounts }
๊ฐ๊ฐ์˜ ๋…๋ฆฝ์ ์ธ OpenAPI์™€ ๋ฌธ์„œ UI๋ฅผ ๊ฐ–๋Š” ๋‘ ๊ฐœ์˜ ๋…๋ฆฝ์ ์ธ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ•„์š”ํ•˜๋‹ค๋ฉด, ๋ฉ”์ธ ์•ฑ์„ ๋‘๊ณ  ํ•˜๋‚˜(๋˜๋Š” ๊ทธ ์ด์ƒ)์˜ ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์„ "๋งˆ์šดํŠธ"ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ฐ๊ฐ์˜ ๋…๋ฆฝ์ ์ธ OpenAPI์™€ ๋ฌธ์„œ UI๋ฅผ ๊ฐ–๋Š” ๋‘ ๊ฐœ์˜ ๋…๋ฆฝ์ ์ธ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ•„์š”ํ•˜๋‹ค๋ฉด, ๋ฉ”์ธ ์•ฑ์„ ๋‘๊ณ  ํ•˜๋‚˜(๋˜๋Š” ๊ทธ ์ด์ƒ)์˜ ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ "๋งˆ์šดํŠธ"ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
## **FastAPI** ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งˆ์šดํŠธ { #mounting-a-fastapi-application }
"๋งˆ์šดํŠธ"๋ž€ ์™„์ „ํžˆ "๋…๋ฆฝ์ ์ธ" ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํŠน์ • ๊ฒฝ๋กœ์— ์ถ”๊ฐ€ํ•˜๊ณ , ๊ทธ ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์— ์„ ์–ธ๋œ _๊ฒฝ๋กœ ์ฒ˜๋ฆฌ_๋กœ ํ•ด๋‹น ๊ฒฝ๋กœ ์•„๋ž˜์˜ ๋ชจ๋“  ๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
"๋งˆ์šดํŠธ"๋ž€ ์™„์ „ํžˆ "๋…๋ฆฝ์ ์ธ" ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ํŠน์ • ๊ฒฝ๋กœ์— ์ถ”๊ฐ€ํ•˜๊ณ , ๊ทธ ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์„ ์–ธ๋œ _๊ฒฝ๋กœ ์ฒ˜๋ฆฌ_๋กœ ํ•ด๋‹น ๊ฒฝ๋กœ ์•„๋ž˜์˜ ๋ชจ๋“  ๊ฒƒ์„ ์ฒ˜๋ฆฌํ•˜๋„๋ก ํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
### ์ตœ์ƒ์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ { #top-level-application }
@ -12,17 +12,17 @@
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
### ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ { #sub-application }
### ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ { #sub-application }
๊ทธ ๋‹ค์Œ, ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ๊ณผ ๊ทธ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
๊ทธ ๋‹ค์Œ, ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๊ทธ *๊ฒฝ๋กœ ์ฒ˜๋ฆฌ*๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
์ด ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์€ ๋˜ ๋‹ค๋ฅธ ํ‘œ์ค€ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด์ง€๋งŒ, "๋งˆ์šดํŠธ"๋  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค:
์ด ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋˜ ๋‹ค๋ฅธ ํ‘œ์ค€ FastAPI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด์ง€๋งŒ, "๋งˆ์šดํŠธ"๋  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ž…๋‹ˆ๋‹ค:
{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
### ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ ๋งˆ์šดํŠธ { #mount-the-sub-application }
### ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งˆ์šดํŠธ { #mount-the-sub-application }
์ตœ์ƒ์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ `app`์—์„œ ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ `subapi`๋ฅผ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค.
์ตœ์ƒ์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ `app`์—์„œ ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ `subapi`๋ฅผ ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค.
์ด ๊ฒฝ์šฐ `/subapi` ๊ฒฝ๋กœ์— ๋งˆ์šดํŠธ๋ฉ๋‹ˆ๋‹ค:
@ -30,27 +30,27 @@
### ์ž๋™ API ๋ฌธ์„œ ํ™•์ธ { #check-the-automatic-api-docs }
์ด์ œ ํŒŒ์ผ๊ณผ ํ•จ๊ป˜ `fastapi` ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์„ธ์š”:
์ด์ œ `fastapi` ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜์„ธ์š”:
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
๊ทธ๋ฆฌ๊ณ  <a href="http://127.0.0.1:8000/docs" class="external-link" target="_blank">http://127.0.0.1:8000/docs</a>์—์„œ ๋ฌธ์„œ๋ฅผ ์—ฌ์„ธ์š”.
๊ทธ๋ฆฌ๊ณ  [http://127.0.0.1:8000/docs](http://127.0.0.1:8000/docs)์—์„œ ๋ฌธ์„œ๋ฅผ ์—ฌ์„ธ์š”.
๋ฉ”์ธ ์•ฑ์˜ ์ž๋™ API ๋ฌธ์„œ๋ฅผ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ด๋ฉฐ, ๋ฉ”์ธ ์•ฑ ์ž์ฒด์˜ _๊ฒฝ๋กœ ์ฒ˜๋ฆฌ_๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค:
<img src="/img/tutorial/sub-applications/image01.png">
๊ทธ ๋‹ค์Œ, <a href="http://127.0.0.1:8000/subapi/docs" class="external-link" target="_blank">http://127.0.0.1:8000/subapi/docs</a>์—์„œ ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์˜ ๋ฌธ์„œ๋ฅผ ์—ฌ์„ธ์š”.
๊ทธ ๋‹ค์Œ, [http://127.0.0.1:8000/subapi/docs](http://127.0.0.1:8000/subapi/docs)์—์„œ ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฌธ์„œ๋ฅผ ์—ฌ์„ธ์š”.
ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์˜ ์ž๋™ API ๋ฌธ์„œ๋ฅผ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ด๋ฉฐ, ํ•˜์œ„ ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ `/subapi` ์•„๋ž˜์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํฌํ•จ๋œ ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ ์ž์ฒด์˜ _๊ฒฝ๋กœ ์ฒ˜๋ฆฌ_๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค:
ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ž๋™ API ๋ฌธ์„œ๋ฅผ ๋ณด๊ฒŒ ๋  ๊ฒƒ์ด๋ฉฐ, ํ•˜์œ„ ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ `/subapi` ์•„๋ž˜์— ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ํฌํ•จ๋œ ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ž์ฒด์˜ _๊ฒฝ๋กœ ์ฒ˜๋ฆฌ_๋งŒ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค:
<img src="/img/tutorial/sub-applications/image02.png">
@ -58,10 +58,10 @@ $ fastapi dev main.py
### ๊ธฐ์ˆ ์  ์„ธ๋ถ€์‚ฌํ•ญ: `root_path` { #technical-details-root-path }
์œ„์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์„ ๋งˆ์šดํŠธํ•˜๋ฉด, FastAPI๋Š” ASGI ๋ช…์„ธ์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ธ `root_path`๋ฅผ ์‚ฌ์šฉํ•ด ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•œ ๋งˆ์šดํŠธ ๊ฒฝ๋กœ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
์œ„์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งˆ์šดํŠธํ•˜๋ฉด, FastAPI๋Š” ASGI ๋ช…์„ธ์˜ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ธ `root_path`๋ฅผ ์‚ฌ์šฉํ•ด ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋Œ€ํ•œ ๋งˆ์šดํŠธ ๊ฒฝ๋กœ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ์€ ๋ฌธ์„œ UI๋ฅผ ์œ„ํ•ด ํ•ด๋‹น ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ๋ฌธ์„œ UI๋ฅผ ์œ„ํ•ด ํ•ด๋‹น ๊ฒฝ๋กœ ์ ‘๋‘์‚ฌ๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ํ•˜์œ„ ์‘์šฉํ”„๋กœ๊ทธ๋žจ๋„ ์ž์ฒด์ ์œผ๋กœ ํ•˜์œ„ ์•ฑ์„ ๋งˆ์šดํŠธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, FastAPI๊ฐ€ ์ด ๋ชจ๋“  `root_path`๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ ํ•˜์œ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋„ ์ž์ฒด์ ์œผ๋กœ ํ•˜์œ„ ์•ฑ์„ ๋งˆ์šดํŠธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, FastAPI๊ฐ€ ์ด ๋ชจ๋“  `root_path`๋ฅผ ์ž๋™์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒƒ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
`root_path`์™€ ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” [ํ”„๋ก์‹œ ๋’ค](behind-a-proxy.md){.internal-link target=_blank} ์„น์…˜์—์„œ ๋” ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
`root_path`์™€ ์ด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด์„œ๋Š” [ํ”„๋ก์‹œ ๋’ค](behind-a-proxy.md) ์„น์…˜์—์„œ ๋” ์•Œ์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

4
docs/ko/docs/advanced/templates.md

@ -8,7 +8,7 @@
## ์˜์กด์„ฑ ์„ค์น˜ { #install-dependencies }
[๊ฐ€์ƒ ํ™˜๊ฒฝ](../virtual-environments.md){.internal-link target=_blank}์„ ์ƒ์„ฑํ•˜๊ณ , ํ™œ์„ฑํ™”ํ•œ ํ›„ `jinja2`๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
[๊ฐ€์ƒ ํ™˜๊ฒฝ](../virtual-environments.md)์„ ์ƒ์„ฑํ•˜๊ณ , ํ™œ์„ฑํ™”ํ•œ ํ›„ `jinja2`๋ฅผ ์„ค์น˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค:
<div class="termy">
@ -123,4 +123,4 @@ Item ID: 42
## ๋” ๋งŽ์€ ์„ธ๋ถ€ ์‚ฌํ•ญ { #more-details }
ํ…œํ”Œ๋ฆฟ ํ…Œ์ŠคํŠธ๋ฅผ ํฌํ•จํ•œ ๋” ๋งŽ์€ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ <a href="https://www.starlette.dev/templates/" class="external-link" target="_blank">Starlette์˜ ํ…œํ”Œ๋ฆฟ ๋ฌธ์„œ</a>๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
ํ…œํ”Œ๋ฆฟ ํ…Œ์ŠคํŠธ๋ฅผ ํฌํ•จํ•œ ๋” ๋งŽ์€ ์„ธ๋ถ€ ์‚ฌํ•ญ์€ [Starlette์˜ ํ…œํ”Œ๋ฆฟ ๋ฌธ์„œ](https://www.starlette.dev/templates/)๋ฅผ ํ™•์ธํ•˜์„ธ์š”.

4
docs/ko/docs/advanced/testing-websockets.md

@ -6,8 +6,8 @@
{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
/// note | ์ฐธ๊ณ 
/// note
์ž์„ธํ•œ ๋‚ด์šฉ์€ Starlette์˜ <a href="https://www.starlette.dev/testclient/#testing-websocket-sessions" class="external-link" target="_blank">WebSocket ํ…Œ์ŠคํŠธ</a> ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
์ž์„ธํ•œ ๋‚ด์šฉ์€ Starlette์˜ [WebSocket ํ…Œ์ŠคํŠธ](https://www.starlette.dev/testclient/#testing-websocket-sessions) ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
///

4
docs/ko/docs/advanced/using-request-directly.md

@ -15,7 +15,7 @@
## `Request` ๊ฐ์ฒด์— ๋Œ€ํ•œ ์„ธ๋ถ€ ์‚ฌํ•ญ { #details-about-the-request-object }
**FastAPI**๋Š” ์‹ค์ œ๋กœ ๋‚ด๋ถ€์— **Starlette**์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๊ทธ ์œ„์— ์—ฌ๋Ÿฌ ๋„๊ตฌ๋ฅผ ๋ง๋ถ™์ธ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฌ๋Ÿฌ๋ถ„์ด ํ•„์š”ํ•  ๋•Œ Starlette์˜ <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">`Request`</a> ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
**FastAPI**๋Š” ์‹ค์ œ๋กœ ๋‚ด๋ถ€์— **Starlette**์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๊ทธ ์œ„์— ์—ฌ๋Ÿฌ ๋„๊ตฌ๋ฅผ ๋ง๋ถ™์ธ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์—ฌ๋Ÿฌ๋ถ„์ด ํ•„์š”ํ•  ๋•Œ Starlette์˜ [`Request`](https://www.starlette.dev/requests/) ๊ฐ์ฒด๋ฅผ ์ง์ ‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ ์ด๋Š” `Request` ๊ฐ์ฒด์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒฝ์šฐ(์˜ˆ: ๋ณธ๋ฌธ์„ ์ฝ๊ธฐ) FastAPI๊ฐ€ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๋ฅผ ๊ฒ€์ฆํ•˜๊ฑฐ๋‚˜ ๋ณ€ํ™˜ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฌธ์„œํ™”(OpenAPI๋ฅผ ํ†ตํ•œ ์ž๋™ API ์‚ฌ์šฉ์ž ์ธํ„ฐํŽ˜์ด์Šค์šฉ)๋„ ๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜๋ฏธ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
@ -45,7 +45,7 @@
## `Request` ์„ค๋ช…์„œ { #request-documentation }
์—ฌ๋Ÿฌ๋ถ„์€ <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">๊ณต์‹ Starlette ์„ค๋ช…์„œ ์‚ฌ์ดํŠธ์˜ `Request` ๊ฐ์ฒด</a>์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์„ ์ฝ์–ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๋Ÿฌ๋ถ„์€ [`Request` ๊ฐ์ฒด์— ๋Œ€ํ•œ ๊ณต์‹ Starlette ์„ค๋ช…์„œ ์‚ฌ์ดํŠธ](https://www.starlette.dev/requests/)์— ๋Œ€ํ•œ ๋” ์ž์„ธํ•œ ๋‚ด์šฉ์„ ์ฝ์–ด๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
/// note | ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ

24
docs/ko/docs/advanced/websockets.md

@ -1,10 +1,10 @@
# WebSockets { #websockets }
์—ฌ๋Ÿฌ๋ถ„์€ **FastAPI**์—์„œ <a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API" class="external-link" target="_blank">WebSockets</a>๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์—ฌ๋Ÿฌ๋ถ„์€ **FastAPI**์—์„œ [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
## `websockets` ์„ค์น˜ { #install-websockets }
[๊ฐ€์ƒ ํ™˜๊ฒฝ](../virtual-environments.md){.internal-link target=_blank}์„ ์ƒ์„ฑํ•˜๊ณ  ํ™œ์„ฑํ™”ํ•œ ๋‹ค์Œ, `websockets`("WebSocket" ํ”„๋กœํ† ์ฝœ์„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”:
[๊ฐ€์ƒ ํ™˜๊ฒฝ](../virtual-environments.md)์„ ์ƒ์„ฑํ•˜๊ณ  ํ™œ์„ฑํ™”ํ•œ ๋‹ค์Œ, `websockets`("WebSocket" ํ”„๋กœํ† ์ฝœ์„ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)๋ฅผ ์„ค์น˜ํ•˜์„ธ์š”:
<div class="termy">
@ -64,19 +64,19 @@ WebSocket ๊ฒฝ๋กœ์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋Œ€๊ธฐ(`await`)ํ•˜๊ณ  ์ „์†กํ•  ์ˆ˜ ์žˆ์Šต
## ์‹œ๋„ํ•ด๋ณด๊ธฐ { #try-it }
ํŒŒ์ผ ์ด๋ฆ„์ด `main.py`๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
์ฝ”๋“œ๋ฅผ `main.py` ํŒŒ์ผ์— ๋„ฃ๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
๋ธŒ๋ผ์šฐ์ €์—์„œ <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>์„ ์—ฌ์„ธ์š”.
๋ธŒ๋ผ์šฐ์ €์—์„œ [http://127.0.0.1:8000](http://127.0.0.1:8000)์„ ์—ฌ์„ธ์š”.
๊ฐ„๋‹จํ•œ ํŽ˜์ด์ง€๊ฐ€ ๋‚˜ํƒ€๋‚  ๊ฒƒ์ž…๋‹ˆ๋‹ค:
@ -115,25 +115,25 @@ WebSocket ์—”๋“œํฌ์ธํŠธ์—์„œ `fastapi`์—์„œ ๋‹ค์Œ์„ ๊ฐ€์ ธ์™€ ์‚ฌ์šฉํ• 
WebSocket์ด๊ธฐ ๋•Œ๋ฌธ์— `HTTPException`์„ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์€ ์ ์ ˆํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋Œ€์‹  `WebSocketException`์„ ๋ฐœ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค.
๋ช…์„ธ์„œ์— ์ •์˜๋œ <a href="https://tools.ietf.org/html/rfc6455#section-7.4.1" class="external-link" target="_blank">์œ ํšจํ•œ ์ฝ”๋“œ</a>๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ข…๋ฃŒ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ช…์„ธ์„œ์— ์ •์˜๋œ [์œ ํšจํ•œ ์ฝ”๋“œ](https://tools.ietf.org/html/rfc6455#section-7.4.1)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ข…๋ฃŒ ์ฝ”๋“œ๋ฅผ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
///
### ์ข…์†์„ฑ์„ ๊ฐ€์ง„ WebSockets ์‹œ๋„ํ•ด๋ณด๊ธฐ { #try-the-websockets-with-dependencies }
ํŒŒ์ผ ์ด๋ฆ„์ด `main.py`๋ผ๊ณ  ๊ฐ€์ •ํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค:
<div class="termy">
```console
$ fastapi dev main.py
$ fastapi dev
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
```
</div>
๋ธŒ๋ผ์šฐ์ €์—์„œ <a href="http://127.0.0.1:8000" class="external-link" target="_blank">http://127.0.0.1:8000</a>์„ ์—ฌ์„ธ์š”.
๋ธŒ๋ผ์šฐ์ €์—์„œ [http://127.0.0.1:8000](http://127.0.0.1:8000)์„ ์—ฌ์„ธ์š”.
์—ฌ๊ธฐ์—์„œ ๋‹ค์Œ์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -174,7 +174,7 @@ Client #1596980209979 left the chat
ํ•˜์ง€๋งŒ ๋ชจ๋“  ๊ฒƒ์„ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋‹จ์ผ ๋ฆฌ์ŠคํŠธ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฏ€๋กœ, ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ๋™์•ˆ๋งŒ ๋™์ž‘ํ•˜๋ฉฐ ๋‹จ์ผ ํ”„๋กœ์„ธ์Šค์—์„œ๋งŒ ์ž‘๋™ํ•œ๋‹ค๋Š” ์ ์„ ๊ธฐ์–ตํ•˜์„ธ์š”.
FastAPI์™€ ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉด์„œ ๋” ๊ฒฌ๊ณ ํ•˜๊ณ  Redis, PostgreSQL ๋“ฑ์„ ์ง€์›ํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด, <a href="https://github.com/encode/broadcaster" class="external-link" target="_blank">encode/broadcaster</a>๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
FastAPI์™€ ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉด์„œ ๋” ๊ฒฌ๊ณ ํ•˜๊ณ  Redis, PostgreSQL ๋“ฑ์„ ์ง€์›ํ•˜๋Š” ๋„๊ตฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด, [encode/broadcaster](https://github.com/encode/broadcaster)๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
///
@ -182,5 +182,5 @@ FastAPI์™€ ์‰ฝ๊ฒŒ ํ†ตํ•ฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉด์„œ ๋” ๊ฒฌ๊ณ ํ•˜๊ณ  Redis, PostgreSQL
๋‹ค์Œ ์˜ต์…˜์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด๋ ค๋ฉด Starlette์˜ ๋ฌธ์„œ๋ฅผ ํ™•์ธํ•˜์„ธ์š”:
* <a href="https://www.starlette.dev/websockets/" class="external-link" target="_blank">`WebSocket` ํด๋ž˜์Šค</a>.
* <a href="https://www.starlette.dev/endpoints/#websocketendpoint" class="external-link" target="_blank">ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ WebSocket ์ฒ˜๋ฆฌ</a>.
* [`WebSocket` ํด๋ž˜์Šค](https://www.starlette.dev/websockets/).
* [ํด๋ž˜์Šค ๊ธฐ๋ฐ˜ WebSocket ์ฒ˜๋ฆฌ](https://www.starlette.dev/endpoints/#websocketendpoint).

6
docs/ko/docs/advanced/wsgi.md

@ -1,6 +1,6 @@
# WSGI ํฌํ•จํ•˜๊ธฐ - Flask, Django ๋“ฑ { #including-wsgi-flask-django-others }
[์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ๋งˆ์šดํŠธ](sub-applications.md){.internal-link target=_blank}, [ํ”„๋ก์‹œ ๋’ค์—์„œ](behind-a-proxy.md){.internal-link target=_blank}์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ WSGI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งˆ์šดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
[์„œ๋ธŒ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ - ๋งˆ์šดํŠธ](sub-applications.md), [ํ”„๋ก์‹œ ๋’ค์—์„œ](behind-a-proxy.md)์—์„œ ๋ณธ ๊ฒƒ์ฒ˜๋Ÿผ WSGI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งˆ์šดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ์œ„ํ•ด `WSGIMiddleware`๋ฅผ ์‚ฌ์šฉํ•ด WSGI ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜(์˜ˆ: Flask, Django ๋“ฑ)์„ ๊ฐ์Œ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
@ -36,13 +36,13 @@
๊ทธ๋ฆฌ๊ณ  ๋‚˜๋จธ์ง€๋Š” **FastAPI**์— ์˜ํ•ด ์ฒ˜๋ฆฌ๋ฉ๋‹ˆ๋‹ค.
์‹คํ–‰ํ•˜๊ณ  <a href="http://localhost:8000/v1/" class="external-link" target="_blank">http://localhost:8000/v1/</a>๋กœ ์ด๋™ํ•˜๋ฉด Flask์˜ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
์‹คํ–‰ํ•˜๊ณ  [http://localhost:8000/v1/](http://localhost:8000/v1/)๋กœ ์ด๋™ํ•˜๋ฉด Flask์˜ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```txt
Hello, World from Flask!
```
๊ทธ๋ฆฌ๊ณ  <a href="http://localhost:8000/v2" class="external-link" target="_blank">http://localhost:8000/v2</a>๋กœ ์ด๋™ํ•˜๋ฉด **FastAPI**์˜ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
๊ทธ๋ฆฌ๊ณ  [http://localhost:8000/v2](http://localhost:8000/v2)๋กœ ์ด๋™ํ•˜๋ฉด **FastAPI**์˜ ์‘๋‹ต์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
```JSON
{

8
docs/ko/docs/how-to/custom-request-and-route.md

@ -18,7 +18,7 @@
์‚ฌ์šฉ ์‚ฌ๋ก€์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค:
* JSON์ด ์•„๋‹Œ ์š”์ฒญ ๋ฐ”๋””๋ฅผ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ(์˜ˆ: <a href="https://msgpack.org/index.html" class="external-link" target="_blank">`msgpack`</a>).
* JSON์ด ์•„๋‹Œ ์š”์ฒญ ๋ฐ”๋””๋ฅผ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•˜๊ธฐ(์˜ˆ: [`msgpack`](https://msgpack.org/index.html)).
* gzip์œผ๋กœ ์••์ถ•๋œ ์š”์ฒญ ๋ฐ”๋”” ์••์ถ• ํ•ด์ œํ•˜๊ธฐ.
* ๋ชจ๋“  ์š”์ฒญ ๋ฐ”๋””๋ฅผ ์ž๋™์œผ๋กœ ๋กœ๊น…ํ•˜๊ธฐ.
@ -32,7 +32,7 @@
/// tip | ํŒ
์ด ์˜ˆ์‹œ๋Š” ๋™์ž‘ ๋ฐฉ์‹ ์‹œ์—ฐ์„ ์œ„ํ•œ ์žฅ๋‚œ๊ฐ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. Gzip ์ง€์›์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์ œ๊ณต๋˜๋Š” [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware){.internal-link target=_blank}๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด ์˜ˆ์‹œ๋Š” ๋™์ž‘ ๋ฐฉ์‹ ์‹œ์—ฐ์„ ์œ„ํ•œ ์žฅ๋‚œ๊ฐ ์˜ˆ์ œ์ž…๋‹ˆ๋‹ค. Gzip ์ง€์›์ด ํ•„์š”ํ•˜๋‹ค๋ฉด ์ œ๊ณต๋˜๋Š” [`GzipMiddleware`](../advanced/middleware.md#gzipmiddleware)๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
///
@ -66,7 +66,7 @@
๊ทธ๋ฆฌ๊ณ  ์ด ๋‘ ๊ฐ€์ง€, `scope`์™€ `receive`๊ฐ€ ์ƒˆ๋กœ์šด `Request` ์ธ์Šคํ„ด์Šค๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฒƒ๋“ค์ž…๋‹ˆ๋‹ค.
`Request`์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด๋ ค๋ฉด <a href="https://www.starlette.dev/requests/" class="external-link" target="_blank">Starlette์˜ Requests ๋ฌธ์„œ</a>๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
`Request`์— ๋Œ€ํ•ด ๋” ์•Œ์•„๋ณด๋ ค๋ฉด [Starlette์˜ Requests ๋ฌธ์„œ](https://www.starlette.dev/requests/)๋ฅผ ํ™•์ธํ•˜์„ธ์š”.
///
@ -82,7 +82,7 @@
/// tip | ํŒ
๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด `RequestValidationError`์— ๋Œ€ํ•œ ์ปค์Šคํ…€ ํ•ธ๋“ค๋Ÿฌ์—์„œ `body`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ์•„๋งˆ ํ›จ์”ฌ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค([์˜ค๋ฅ˜ ์ฒ˜๋ฆฌํ•˜๊ธฐ](../tutorial/handling-errors.md#use-the-requestvalidationerror-body){.internal-link target=_blank}).
๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๋ฉด `RequestValidationError`์— ๋Œ€ํ•œ ์ปค์Šคํ…€ ํ•ธ๋“ค๋Ÿฌ์—์„œ `body`๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํŽธ์ด ์•„๋งˆ ํ›จ์”ฌ ๋” ์‰ฝ์Šต๋‹ˆ๋‹ค([์˜ค๋ฅ˜ ์ฒ˜๋ฆฌํ•˜๊ธฐ](../tutorial/handling-errors.md#use-the-requestvalidationerror-body)).
ํ•˜์ง€๋งŒ ์ด ์˜ˆ์‹œ๋„ ์—ฌ์ „ํžˆ ์œ ํšจํ•˜๋ฉฐ, ๋‚ด๋ถ€ ์ปดํฌ๋„ŒํŠธ์™€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

4
docs/ko/docs/tutorial/metadata.md

@ -14,7 +14,7 @@ OpenAPI ๋ช…์„ธ ๋ฐ ์ž๋™ํ™”๋œ API ๋ฌธ์„œ UI์— ์‚ฌ์šฉ๋˜๋Š” ๋‹ค์Œ ํ•„๋“œ๋ฅผ
| `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> |
| `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์— ๋Œ€ํ•œ [SPDX](https://spdx.org/licenses/) ๋ผ์ด์„ ์Šค ํ‘œํ˜„์ž…๋‹ˆ๋‹ค. <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> |
๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:
@ -40,7 +40,7 @@ OpenAPI 3.1.0 ๋ฐ FastAPI 0.99.0๋ถ€ํ„ฐ `license_info`์— `url` ๋Œ€์‹  `identifie
## ํƒœ๊ทธ์— ๋Œ€ํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ { #metadata-for-tags }
`openapi_tags` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ์„ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์—ฌ๋Ÿฌ ํƒœ๊ทธ์— ์ถ”๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
`openapi_tags` ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ๋ฅผ ๊ทธ๋ฃนํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์—ฌ๋Ÿฌ ํƒœ๊ทธ์— ์ถ”๊ฐ€ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
๋ฆฌ์ŠคํŠธ๋Š” ๊ฐ ํƒœ๊ทธ์— ๋Œ€ํ•ด ํ•˜๋‚˜์˜ ๋”•์…”๋„ˆ๋ฆฌ๋ฅผ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค.

Loadingโ€ฆ
Cancel
Save