Фронтенд¶
🌐 Перевод выполнен с помощью ИИ и людей
Этот перевод был сделан ИИ под руководством людей. 🤝
В нем могут быть ошибки из-за неправильного понимания оригинального смысла или неестественности и т. д. 🤖
Вы можете улучшить этот перевод, помогая нам лучше направлять ИИ LLM.
Вы можете «отдавать» статические фронтенд-приложения с помощью app.frontend() (или router.frontend()).
Это полезно для фронтенд-инструментов, которые генерируют статические файлы, таких как React с Vite, TanStack Router, Astro, Vue, Svelte, Angular, Solid и других.
С такими инструментами обычно есть этап сборки фронтенда с помощью команды вроде:
npm run build
Она сгенерирует директорию вроде ./dist/ с файлами вашего фронтенда.
Вы можете использовать app.frontend(), чтобы «отдавать» эту директорию, следуя соглашениям, которые требуются этим фронтенд-фреймворкам.
FastAPI сначала проверяет операции пути. Файлы фронтенда проверяются только если не совпал ни один обычный маршрут, поэтому ваш API не будет затронут.
Отдача фронтенда¶
После сборки фронтенда, например с помощью 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, приоритет будет у операции пути.
Маршрутизация на стороне клиента¶
Многие фронтенд-приложения, включая single-page apps (SPA), используют маршрутизацию на стороне клиента. Путь вроде /dashboard/settings может не быть реальным файлом, но фреймворк возьмёт на себя его обработку.
Поэтому, если обратиться к этому URL напрямую (а не перейти к нему через приложение), backend должен отдать фронтенд-приложение из index.html, чтобы затем фронтенд-фреймворк мог обработать маршрутизацию на стороне клиента.
Для этого используйте fallback="index.html":
from fastapi import FastAPI
app = FastAPI()
app.frontend("/", directory="dist", fallback="index.html")
FastAPI использует этот fallback только для запросов GET и HEAD, которые похожи на навигацию в браузере. Отсутствующие файлы, такие как JavaScript, CSS и изображения, по-прежнему возвращают 404.
Запросы с другими методами, например POST или PUT, к путям, которые совпадают только с fallback фронтенда, также возвращают 404. Обычные операции пути FastAPI по-прежнему имеют более высокий приоритет, чем маршруты фронтенда.
Совет
По умолчанию fallback имеет значение fallback="auto". В большинстве случаев вам не нужно будет указывать fallback. Подробности ниже.
Именно такое поведение нужно для многих фронтенд-приложений, которые используют маршрутизацию на стороне клиента, например React с TanStack Router, Vue, Angular, SvelteKit или Solid.
Кастомная страница 404¶
Вы также можете отдавать статическую страницу 404.html для отсутствующих путей фронтенда:
from fastapi import FastAPI
app = FastAPI()
app.frontend("/", directory="dist", fallback="404.html")
Этот HTTP-ответ сохраняет статус-код 404.
В этом случае FastAPI не будет отдавать index.html для отсутствующих путей фронтенда. Вместо этого он вернёт файл 404.html.
Совет
По умолчанию fallback имеет значение fallback="auto". При этом, если найден файл 404.html, он будет автоматически использован как fallback.
Поэтому обычно можно не указывать аргумент fallback.
Это полезно с фронтенд-инструментами, которые генерируют статические HTML-файлы для каждой страницы, например Astro.
Автоматический fallback¶
По умолчанию app.frontend() использует fallback="auto".
Если в директории фронтенда есть файл 404.html, отсутствующие пути фронтенда отдают этот файл со статус-кодом 404.
В противном случае, если есть файл index.html, отсутствующие пути навигации в браузере отдают index.html, что и ожидают многие фронтенд-приложения с маршрутизацией на стороне клиента.
Поэтому в большинстве случаев можно использовать app.frontend("/", directory="dist") без указания аргумента fallback.
from fastapi import FastAPI
app = FastAPI()
app.frontend("/", directory="dist")
Отключение fallback¶
Если вы не хотите отдавать fallback-файл для отсутствующих путей фронтенда, используйте fallback=None:
from fastapi import FastAPI
app = FastAPI()
app.frontend("/", directory="dist", fallback=None)
Тогда отсутствующие пути фронтенда будут возвращать обычный 404.
Проверка директории¶
По умолчанию app.frontend() проверяет, что директория существует, при создании приложения.
Это помогает рано обнаруживать ошибки конфигурации. Например, если отсутствует директория с результатом сборки фронтенда, FastAPI вызовет ошибку при запуске.
Если ваши фронтенд-файлы создаются позже, например отдельным этапом сборки после создания объекта приложения, установите check_dir=False:
from fastapi import FastAPI
app = FastAPI()
app.frontend("/", directory="dist", check_dir=False)
С check_dir=False FastAPI не будет проверять директорию при создании приложения. Если настроенная директория всё ещё отсутствует во время обработки HTTP-запроса, FastAPI вызовет ошибку тогда.
Использование с APIRouter¶
Вы также можете добавить фронтенд-файлы в APIRouter и включить его с префиксом:
from fastapi import APIRouter, FastAPI
app = FastAPI()
router = APIRouter()
router.frontend("/", directory="dist", fallback="index.html")
app.include_router(router, prefix="/app")
В этом примере пути фронтенда отдаются под /app.
Любые обычные операции пути в приложении всё равно будут иметь приоритет, включая операции в других роутерах.
Только статический результат сборки¶
app.frontend() отдаёт файлы, уже сгенерированные сборкой вашего фронтенда.
Он не запускает server-side rendering. Он предназначен для фронтенд-фреймворков, которые генерируют статические файлы, а не для фреймворков, которым требуется динамический рендеринг на сервере для каждого HTTP-запроса.