Browse Source
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>pull/15903/head
committed by
GitHub
1 changed files with 133 additions and 0 deletions
@ -0,0 +1,133 @@ |
|||
# ํ๋ก ํธ์๋ { #frontend } |
|||
|
|||
`app.frontend()`(๋๋ `router.frontend()`)๋ก ์ ์ ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์ ๊ณตํ ์ ์์ต๋๋ค. |
|||
|
|||
์ด๋ Vite๋ฅผ ์ฌ์ฉํ๋ React, TanStack Router, Astro, Vue, Svelte, Angular, Solid ๋ฑ๊ณผ ๊ฐ์ด ์ ์ ํ์ผ์ ์์ฑํ๋ ํ๋ก ํธ์๋ ๋๊ตฌ์ ์ ์ฉํฉ๋๋ค. |
|||
|
|||
์ด๋ฌํ ๋๊ตฌ์์๋ ๋ณดํต ๋ค์๊ณผ ๊ฐ์ ๋ช
๋ น์ด๋ก ํ๋ก ํธ์๋๋ฅผ ๋น๋ํ๋ ๋จ๊ณ๊ฐ ์์ต๋๋ค: |
|||
|
|||
```bash |
|||
npm run build |
|||
``` |
|||
|
|||
๊ทธ๋ฌ๋ฉด ํ๋ก ํธ์๋ ํ์ผ์ด ๋ค์ด ์๋ `./dist/` ๊ฐ์ ๋๋ ํฐ๋ฆฌ๊ฐ ์์ฑ๋ฉ๋๋ค. |
|||
|
|||
`app.frontend()`๋ฅผ ์ฌ์ฉํ๋ฉด ์ด๋ฌํ ํ๋ก ํธ์๋ ํ๋ ์์ํฌ์ ํ์ํ ๊ท์น์ ๋ฐ๋ผ ํด๋น ๋๋ ํฐ๋ฆฌ๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. |
|||
|
|||
**FastAPI**๋ ๋จผ์ *๊ฒฝ๋ก ์ฒ๋ฆฌ*๋ฅผ ํ์ธํฉ๋๋ค. ํ๋ก ํธ์๋ ํ์ผ์ ์ผ๋ฐ ๋ผ์ฐํธ์ ๋งค์นญ๋์ง ์๋ ๊ฒฝ์ฐ์๋ง ํ์ธ๋๋ฏ๋ก, API์๋ ์ํฅ์ ์ฃผ์ง ์์ต๋๋ค. |
|||
|
|||
## ํ๋ก ํธ์๋ ์ ๊ณตํ๊ธฐ { #serve-a-frontend } |
|||
|
|||
์๋ฅผ ๋ค์ด `npm run build`๋ก ํ๋ก ํธ์๋๋ฅผ ๋น๋ํ ํ, ์์ฑ๋ ํ์ผ์ `dist` ๊ฐ์ ๋๋ ํฐ๋ฆฌ์ ๋ฃ์ต๋๋ค. |
|||
|
|||
ํ๋ก์ ํธ ๊ตฌ์กฐ๋ ๋ค์๊ณผ ๊ฐ์ ์ ์์ต๋๋ค: |
|||
|
|||
```text |
|||
. |
|||
โโโ pyproject.toml |
|||
โโโ app |
|||
โ โโโ __init__.py |
|||
โ โโโ main.py |
|||
โโโ dist |
|||
โโโ index.html |
|||
โโโ assets |
|||
โโโ app.js |
|||
``` |
|||
|
|||
๊ทธ๋ฐ ๋ค์ `app.frontend()`๋ก ์ ๊ณตํฉ๋๋ค: |
|||
|
|||
{* ../../docs_src/frontend/tutorial001_py310.py hl[5] *} |
|||
|
|||
์ด๋ ๊ฒ ํ๋ฉด `/assets/app.js`์ ๋ํ ์์ฒญ์ด `dist/assets/app.js`๋ฅผ ์ ๊ณตํ ์ ์์ต๋๋ค. |
|||
|
|||
**FastAPI** *๊ฒฝ๋ก ์ฒ๋ฆฌ*๋ ์๋ค๋ฉด, *๊ฒฝ๋ก ์ฒ๋ฆฌ*๊ฐ ์ฐ์ ํฉ๋๋ค. |
|||
|
|||
## ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ
{ #client-side-routing } |
|||
|
|||
**single-page apps**(SPAs)๋ฅผ ํฌํจํ ๋ง์ ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์
์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ
์ ์ฌ์ฉํฉ๋๋ค. `/dashboard/settings` ๊ฐ์ ๊ฒฝ๋ก๋ ์ค์ ํ์ผ์ด ์๋ ์ ์์ง๋ง, ํ๋ ์์ํฌ๊ฐ ์ด๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. |
|||
|
|||
๋ฐ๋ผ์ ํด๋น URL์ ์ง์ ์ ๊ทผํ๋ ๊ฒฝ์ฐ(์ ํ๋ฆฌ์ผ์ด์
์์์ ํ์ํ๋ ๋์ ), ๋ฐฑ์๋๋ `index.html`์์ ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์
์ ์ ๊ณตํด์ผ ํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด ํ๋ก ํธ์๋ ํ๋ ์์ํฌ๊ฐ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ
์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค. |
|||
|
|||
์ด๋ฅผ ์ํด `fallback="index.html"`์ ์ฌ์ฉํฉ๋๋ค: |
|||
|
|||
{* ../../docs_src/frontend/tutorial002_py310.py hl[5] *} |
|||
|
|||
**FastAPI**๋ ๋ธ๋ผ์ฐ์ ํ์์ฒ๋ผ ๋ณด์ด๋ `GET` ๋ฐ `HEAD` ์์ฒญ์๋ง ์ด fallback์ ์ฌ์ฉํฉ๋๋ค. JavaScript, CSS, ์ด๋ฏธ์ง์ฒ๋ผ ๋๋ฝ๋ ํ์ผ์ ์ฌ์ ํ `404`๋ฅผ ๋ฐํํฉ๋๋ค. |
|||
|
|||
`POST`๋ `PUT` ๊ฐ์ ๋ค๋ฅธ ๋ฉ์๋์ ์์ฒญ์ด ํ๋ก ํธ์๋ fallback์๋ง ๋งค์นญ๋๋ ๊ฒฝ๋ก๋ก ๋ค์ด์๋ `404`๋ฅผ ๋ฐํํฉ๋๋ค. ์ผ๋ฐ **FastAPI** *๊ฒฝ๋ก ์ฒ๋ฆฌ*๋ ์ฌ์ ํ ํ๋ก ํธ์๋ ๋ผ์ฐํธ๋ณด๋ค ๋์ ์ฐ์ ์์๋ฅผ ๊ฐ์ง๋๋ค. |
|||
|
|||
/// tip | ํ |
|||
|
|||
๊ธฐ๋ณธ์ ์ผ๋ก `fallback`์ `fallback="auto"` ๊ฐ์ ๊ฐ์ง๋๋ค. ๋๋ถ๋ถ์ ๊ฒฝ์ฐ `fallback`์ ์ง์ ํ ํ์๊ฐ ์์ต๋๋ค. ์์ธํ ๋ด์ฉ์ ์๋๋ฅผ ์ฝ์ด๋ณด์ธ์. |
|||
|
|||
/// |
|||
|
|||
์ด๋ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ
์ ์ฌ์ฉํ๋ ๋ง์ ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์
์์ ์ํ๋ ๋์์
๋๋ค. ์๋ฅผ ๋ค์ด TanStack Router๋ฅผ ์ฌ์ฉํ๋ React, Vue, Angular, SvelteKit, Solid ๋ฑ์ด ์์ต๋๋ค. |
|||
|
|||
## ์ฌ์ฉ์ ์ ์ 404 ํ์ด์ง { #custom-404-page } |
|||
|
|||
๋๋ฝ๋ ํ๋ก ํธ์๋ ๊ฒฝ๋ก์ ๋ํด ์ ์ `404.html` ํ์ด์ง๋ฅผ ์ ๊ณตํ ์๋ ์์ต๋๋ค: |
|||
|
|||
{* ../../docs_src/frontend/tutorial003_py310.py hl[5] *} |
|||
|
|||
์ด ์๋ต์ `404` ์ํ ์ฝ๋๋ฅผ ์ ์งํฉ๋๋ค. |
|||
|
|||
์ด ๊ฒฝ์ฐ **FastAPI**๋ ๋๋ฝ๋ ํ๋ก ํธ์๋ ๊ฒฝ๋ก์ ๋ํด `index.html`์ ์ ๊ณตํ์ง ์์ต๋๋ค. ๋์ `404.html` ํ์ผ์ ๋ฐํํฉ๋๋ค. |
|||
|
|||
/// tip | ํ |
|||
|
|||
๊ธฐ๋ณธ์ ์ผ๋ก `fallback`์ `fallback="auto"` ๊ฐ์ ๊ฐ์ง๋๋ค. ์ด๋ฅผ ์ฌ์ฉํ๋ฉด `404.html` ํ์ผ์ด ๋ฐ๊ฒฌ๋ ๊ฒฝ์ฐ ์๋์ผ๋ก fallback์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค. |
|||
|
|||
๋ฐ๋ผ์ ์ผ๋ฐ์ ์ผ๋ก `fallback` ์ธ์๋ฅผ ์๋ตํ ์ ์์ต๋๋ค. |
|||
|
|||
/// |
|||
|
|||
์ด๋ Astro์ฒ๋ผ ๊ฐ ํ์ด์ง์ ๋ํ ์ ์ HTML ํ์ผ์ ์์ฑํ๋ ํ๋ก ํธ์๋ ๋๊ตฌ์ ์ ์ฉํฉ๋๋ค. |
|||
|
|||
## Fallback ์๋ ์ค์ { #fallback-auto } |
|||
|
|||
๊ธฐ๋ณธ์ ์ผ๋ก `app.frontend()`๋ `fallback="auto"`๋ฅผ ์ฌ์ฉํฉ๋๋ค. |
|||
|
|||
ํ๋ก ํธ์๋ ๋๋ ํฐ๋ฆฌ์ `404.html` ํ์ผ์ด ์์ผ๋ฉด, ๋๋ฝ๋ ํ๋ก ํธ์๋ ๊ฒฝ๋ก๋ ์ํ ์ฝ๋ `404`์ ํจ๊ป ํด๋น ํ์ผ์ ์ ๊ณตํฉ๋๋ค. |
|||
|
|||
๊ทธ๋ ์ง ์๊ณ `index.html` ํ์ผ์ด ์์ผ๋ฉด, ๋๋ฝ๋ ๋ธ๋ผ์ฐ์ ํ์ ๊ฒฝ๋ก๋ `index.html`์ ์ ๊ณตํฉ๋๋ค. ์ด๋ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋ผ์ฐํ
์ ์ฌ์ฉํ๋ ๋ง์ ํ๋ก ํธ์๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ๊ธฐ๋ํ๋ ๋์์
๋๋ค. |
|||
|
|||
๋ฐ๋ผ์ ๋๋ถ๋ถ์ ๊ฒฝ์ฐ `fallback` ์ธ์๋ฅผ ์ง์ ํ์ง ์๊ณ `app.frontend("/", directory="dist")`๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค. |
|||
|
|||
{* ../../docs_src/frontend/tutorial001_py310.py hl[5] *} |
|||
|
|||
## Fallback ๋นํ์ฑํ { #disable-fallback } |
|||
|
|||
๋๋ฝ๋ ํ๋ก ํธ์๋ ๊ฒฝ๋ก์ ๋ํด fallback ํ์ผ์ ์ ๊ณตํ๊ณ ์ถ์ง ์๋ค๋ฉด `fallback=None`์ ์ฌ์ฉํฉ๋๋ค: |
|||
|
|||
{* ../../docs_src/frontend/tutorial005_py310.py hl[5] *} |
|||
|
|||
๊ทธ๋ฌ๋ฉด ๋๋ฝ๋ ํ๋ก ํธ์๋ ๊ฒฝ๋ก๋ ์ผ๋ฐ `404`๋ฅผ ๋ฐํํฉ๋๋ค. |
|||
|
|||
## ๋๋ ํฐ๋ฆฌ ํ์ธํ๊ธฐ { #check-directory } |
|||
|
|||
๊ธฐ๋ณธ์ ์ผ๋ก `app.frontend()`๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ์์ฑ๋ ๋ ๋๋ ํฐ๋ฆฌ๊ฐ ์กด์ฌํ๋์ง ํ์ธํฉ๋๋ค. |
|||
|
|||
์ด๋ ์ค์ ์ค๋ฅ๋ฅผ ์ผ์ฐ ๋ฐ๊ฒฌํ๋ ๋ฐ ๋์์ด ๋ฉ๋๋ค. ์๋ฅผ ๋ค์ด ํ๋ก ํธ์๋ ๋น๋ ์ถ๋ ฅ ๋๋ ํฐ๋ฆฌ๊ฐ ์๋ค๋ฉด **FastAPI**๋ ์์ ์ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. |
|||
|
|||
ํ๋ก ํธ์๋ ํ์ผ์ด ๋์ค์ ์์ฑ๋๋ค๋ฉด, ์๋ฅผ ๋ค์ด ์ ํ๋ฆฌ์ผ์ด์
๊ฐ์ฒด๊ฐ ์์ฑ๋ ํ ๋ณ๋์ ๋น๋ ๋จ๊ณ์์ ์์ฑ๋๋ค๋ฉด, `check_dir=False`๋ฅผ ์ค์ ํฉ๋๋ค: |
|||
|
|||
{* ../../docs_src/frontend/tutorial006_py310.py hl[5] *} |
|||
|
|||
`check_dir=False`๋ฅผ ์ฌ์ฉํ๋ฉด **FastAPI**๋ ์ ํ๋ฆฌ์ผ์ด์
์ด ์์ฑ๋ ๋ ๋๋ ํฐ๋ฆฌ๋ฅผ ํ์ธํ์ง ์์ต๋๋ค. ์์ฒญ์ด ์ฒ๋ฆฌ๋ ๋ ์ค์ ๋ ๋๋ ํฐ๋ฆฌ๊ฐ ์ฌ์ ํ ์๋ค๋ฉด, ๊ทธ๋ **FastAPI**๊ฐ ์ค๋ฅ๋ฅผ ๋ฐ์์ํต๋๋ค. |
|||
|
|||
## `APIRouter`์ ํจ๊ป ์ฌ์ฉํ๊ธฐ { #use-it-with-apirouter } |
|||
|
|||
ํ๋ก ํธ์๋ ํ์ผ์ `APIRouter`์ ์ถ๊ฐํ๊ณ prefix์ ํจ๊ป ํฌํจํ ์๋ ์์ต๋๋ค: |
|||
|
|||
{* ../../docs_src/frontend/tutorial004_py310.py hl[6,7] *} |
|||
|
|||
์ด ์์ ์์๋ ํ๋ก ํธ์๋ ๊ฒฝ๋ก๊ฐ `/app` ์๋์์ ์ ๊ณต๋ฉ๋๋ค. |
|||
|
|||
๋ค๋ฅธ ๋ผ์ฐํฐ์ ์๋ ๊ฒ์ ํฌํจํ์ฌ, ์ ํ๋ฆฌ์ผ์ด์
์ ๋ชจ๋ ์ผ๋ฐ *๊ฒฝ๋ก ์ฒ๋ฆฌ*๊ฐ ์ฌ์ ํ ์ฐ์ ํฉ๋๋ค. |
|||
|
|||
## ์ ์ ๋น๋ ์ถ๋ ฅ๋ง ์ฌ์ฉํ๊ธฐ { #static-build-output-only } |
|||
|
|||
`app.frontend()`๋ ํ๋ก ํธ์๋ ๋น๋์์ ์ด๋ฏธ ์์ฑ๋ ํ์ผ์ ์ ๊ณตํฉ๋๋ค. |
|||
|
|||
์๋ฒ ์ฌ์ด๋ ๋ ๋๋ง์ ์คํํ์ง ์์ต๋๋ค. ๊ฐ ์์ฒญ๋ง๋ค ์๋ฒ์์ ๋์ ๋ ๋๋ง์ด ํ์ํ ํ๋ ์์ํฌ๊ฐ ์๋๋ผ, ์ ์ ํ์ผ์ ์์ฑํ๋ ํ๋ก ํธ์๋ ํ๋ ์์ํฌ๋ฅผ ์ํ ๊ฒ์
๋๋ค. |
|||
Loadingโฆ
Reference in new issue