프론트엔드

프론트엔드 (Frontend)

app.frontend()(또는 router.frontend())를 사용하면 정적(static) 프론트엔드 앱을 서빙할 수 있습니다.

이 기능은 React with Vite, TanStack Router, Astro, Vue, Svelte, Angular, Solid 같은 정적 파일을 만들어 내는 프론트엔드 도구에 유용해요.

이런 도구를 쓰면 보통 아래 같은 명령으로 프론트엔드를 빌드하는 단계가 있습니다:

npm run build

그러면 ./dist/ 같은 디렉터리에 프론트엔드 파일들이 생성됩니다.

app.frontend()로 그 디렉터리를, 이 프론트엔드 프레임워크들이 요구하는 규칙에 맞춰 서빙할 수 있습니다.

FastAPI경로 동작(path operations) 을 먼저 확인합니다. 프론트엔드 파일은 정상적인 라우트가 하나도 매칭되지 않았을 때만 확인하므로, 여러분의 API에는 영향이 없습니다.

출처: 공식문서

프론트엔드 서빙하기 (Serve a Frontend)

예를 들어 npm run build로 프론트엔드를 빌드한 뒤, 생성된 파일들을 dist라는 디렉터리에 넣었다고 합시다.

프로젝트 구조는 이렇게 생겼을 거예요:

.
├── pyproject.toml
├── app
│   ├── __init__.py
│   └── main.py
└── dist
    ├── index.html
    └── assets
        └── app.js

그다음 app.frontend()로 서빙합니다:

from fastapi import FastAPI

app = FastAPI()

app.frontend("/", directory="dist")

이렇게 하면 /assets/app.js 요청이 dist/assets/app.js를 서빙해 줍니다.

FastAPI 경로 동작 도 있다면, 경로 동작 이 우선합니다.

클라이언트 사이드 라우팅 (Client-Side Routing)

단일 페이지 앱(SPA) 을 포함한 많은 프론트엔드 앱이 클라이언트 사이드 라우팅을 사용합니다. /dashboard/settings 같은 경로는 실제 파일이 아닐 수 있는데, 프레임워크가 대신 처리해 줍니다.

그래서 (앱을 통해 이동하는 게 아니라) 그 URL에 직접 접근하면, 백엔드가 프론트엔드 앱을 index.html에서 서빙해서, 프론트엔드 프레임워크가 클라이언트 사이드 라우팅을 처리할 수 있게 해야 합니다.

이때 fallback="index.html"을 사용합니다:

from fastapi import FastAPI

app = FastAPI()

app.frontend("/", directory="dist", fallback="index.html")

FastAPI는 이 fallback을 오직 Accept: text/html 또는 Accept: application/xhtml+xml로 HTML을 명시적으로 허용하는 GETHEAD 요청(브라우저 내비게이션 요청이 대개 그렇죠)에만 사용합니다. JavaScript, CSS, 이미지 같은 누락된 파일은 여전히 404를 반환합니다.

그 외 메서드(예: POST, PUT)의 요청이 프론트엔드 fallback에만 매칭되는 경로로 오는 경우에도 404를 반환합니다. 일반적인 FastAPI 경로 동작 은 여전히 프론트엔드 라우트보다 우선순위가 높아요.

!!! tip "팁" 기본적으로 fallback의 값은 fallback="auto"입니다. 대부분의 경우 fallback을 직접 지정할 필요가 없습니다. 자세한 내용은 아래를 읽어보세요.

이것이 클라이언트 사이드 라우팅을 쓰는 많은 프론트엔드 앱(예: React with TanStack Router, Vue, Angular, SvelteKit, Solid)에서 원하는 동작입니다.

커스텀 404 페이지 (Custom 404 Page)

누락된 프론트엔드 경로에 대해 정적 404.html 페이지를 서빙할 수도 있습니다:

from fastapi import FastAPI

app = FastAPI()

app.frontend("/", directory="dist", fallback="404.html")

그 응답은 상태 코드 404를 유지합니다.

이 경우 FastAPI는 누락된 프론트엔드 경로에 index.html을 서빙하지 않고, 대신 404.html 파일을 반환합니다.

!!! tip "팁" 기본적으로 fallback의 값은 fallback="auto"입니다. 이 값과 함께라면 404.html 파일이 있으면 자동으로 fallback으로 사용됩니다.

그래서 평소에는 `fallback` 인자를 생략해도 됩니다.

이 기능은 Astro처럼 페이지마다 정적 HTML 파일을 생성하는 프론트엔드 도구에 유용합니다.

Fallback Auto

기본적으로 app.frontend()fallback="auto"를 사용합니다.

프론트엔드 디렉터리에 404.html 파일이 있으면, 누락된 프론트엔드 경로는 그 파일을 상태 코드 404와 함께 서빙합니다.

그게 아니라 index.html 파일이 있으면, 누락된 브라우저 내비게이션 경로가 index.html을 서빙하는데, 이는 클라이언트 사이드 라우팅을 쓰는 많은 프론트엔드 앱이 기대하는 동작입니다.

그래서 대부분의 경우 fallback 인자 없이 app.frontend("/", directory="dist")만 사용해도 됩니다.

from fastapi import FastAPI

app = FastAPI()

app.frontend("/", directory="dist")

Fallback 비활성화하기 (Disable Fallback)

누락된 프론트엔드 경로에 fallback 파일을 서빙하고 싶지 않다면 fallback=None을 사용하세요:

from fastapi import FastAPI

app = FastAPI()

app.frontend("/", directory="dist", fallback=None)

그러면 누락된 프론트엔드 경로가 일반적인 404를 반환합니다.

디렉터리 확인하기 (Check Directory)

기본적으로 app.frontend()check_dir="auto"를 사용합니다.

FASTAPI_ENV 환경 변수가 development로 설정되어 있으면, FastAPI는 프론트엔드 빌드 출력 디렉터리가 없을 때 경고만 표시합니다. fastapi dev 명령은 이 환경 변수가 아직 설정되지 않았다면 자동으로 설정해 줍니다. 덕분에 개발 중에는 프론트엔드를 빌드하거나 시작하기 전에 백엔드를 먼저 시작할 수 있어요.

그 외의 어떤 환경에서는 FastAPI가 앱을 만들 때 오류를 발생시킵니다. 이는 프론트엔드 파일 없이 앱을 배포하기 전에 설정 오류를 일찍 잡아 주는 역할을 합니다.

check_dir=True로 설정하면 앱을 만들 때 항상 디렉터리를 확인하게 할 수도 있습니다.

프론트엔드 파일이 나중에 생성되는 경우(예: 앱 객체가 만들어진 뒤 별도의 빌드 단계에서 생성되는 경우)는 check_dir=False로 설정하세요:

from fastapi import FastAPI

app = FastAPI()

app.frontend("/", directory="dist", check_dir=False)

check_dir=False를 쓰면 FastAPI가 앱을 만들 때 디렉터리를 확인하지 않습니다. 설정된 디렉터리가 요청 처리 시점에도 여전히 없다면, 그때 오류를 발생시킵니다.

APIRouter와 함께 사용하기 (Use it with APIRouter)

APIRouter에 프론트엔드 파일을 추가하고 접두어(prefix)와 함께 include할 수도 있습니다:

from fastapi import APIRouter, FastAPI

app = FastAPI()
router = APIRouter()

router.frontend("/", directory="dist", fallback="index.html")
app.include_router(router, prefix="/app")

이 예제에서는 프론트엔드 경로가 /app 아래에서 서빙됩니다.

앱의 일반적인 경로 동작 은 여전히 우선하며, 다른 router의 것들도 마찬가지입니다.

의존성과 미들웨어 (Dependencies and Middleware)

프론트엔드 응답은 일반적인 FastAPI 애플리케이션 안에서 실행되므로, HTTP 미들웨어가 적용됩니다.

앱, APIRouter, 그리고 include_router()의 의존성도 프론트엔드 응답에 적용됩니다. 이는 쿠키 인증 같은 것으로 프론트엔드를 보호하는 데 유용할 수 있어요.

일반적인 경로 동작 과 마찬가지로, 의존성이 응답 헤더를 수정하거나 백그라운드 작업을 추가할 수도 있습니다.

정적 빌드 출력만 (Static Build Output Only)

app.frontend()는 프론트엔드 빌드로 이미 생성된 파일들을 서빙합니다.

서버 사이드 렌더링을 실행하지 않아요. 이 기능은 정적 파일을 생성하는 프론트엔드 프레임워크를 위한 것이지, 요청마다 서버에서 동적으로 렌더링해야 하는 프레임워크를 위한 것이 아닙니다.

더 알아보기 (Learn more)

  • app.frontend()는 정적 프론트엔드 산출물을 서빙하며, 같은 경로에 대한 API 경로 동작 이 항상 우선합니다.
  • SPA의 클라이언트 사이드 라우팅은 fallback="index.html"(또는 기본값 fallback="auto")로 처리합니다.
  • 프론트엔드 응답에도 미들웨어와 의존성이 적용되므로, 인증 등에 활용할 수 있습니다.
  • check_dir로 앱 생성 시점에 프론트엔드 디렉터리 존재 여부를 확인하도록 조절할 수 있습니다.