В FastAPI можно организовать маршруты для разных субдоменов с помощью `APIRouter` и мидлваров для обработки запросов на уровне приложения. Давайте подробнее разберем, как это можно сделать.
### Шаг 1: Определение субдомена
Сначала необходимо определять, на какой субдомен поступил запрос. Это можно сделать с использованием класса `Request`, который предоставляет FastAPI. Для этого мы можем создать специальную мидлвару:
```python
from fastapi import FastAPI, Request
from starlette.middleware.base import BaseHTTPMiddleware
class SubdomainMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
subdomain = request.url.hostname.split('.')[0] # Получаем субдомен из хоста
request.state.subdomain = subdomain # Сохраняем субдомен в состоянии запроса
response = await call_next(request)
return response
app = FastAPI()
# Добавляем нашу мидлвару
app.add_middleware(SubdomainMiddleware)
```
### Шаг 2: Создание маршрутов с использованием APIRouter
Теперь мы можем создать разные маршрутизаторы для разных субдоменов и использовать их в зависимости от значения `request.state.subdomain`.
```python
from fastapi import APIRouter, Depends
private_router = APIRouter()
public_router = APIRouter()
@private_router.get("/users/{user_id}")
async def get_private_user(user_id: int, request: Request):
# Логика для приватного API
return {"subdomain": request.state.subdomain, "user_id": user_id}
@public_router.get("/users/{user_id}")
async def get_public_user(user_id: int, request: Request):
# Логика для публичного API
return {"subdomain": request.state.subdomain, "user_id": user_id}
@app.middleware("http")
async def subdomain_router(request: Request, call_next):
if request.state.subdomain == "private":
response = await private_router.routes[0].endpoint(request, user_id=int(request.path_params['user_id']))
elif request.state.subdomain == "public":
response = await public_router.routes[0].endpoint(request, user_id=int(request.path_params['user_id']))
else:
response = JSONResponse(content={"error": "Subdomain not found"}, status_code=404)
return response
app.include_router(private_router, prefix="/private")
app.include_router(public_router, prefix="/public")
```
### Шаг 3: Пример использования
Таким образом, запросы к `private.example.com/users/1` и `public.example.com/users/1` будут правильно обрабатываться благодаря делегированию маршрутов в зависимости от субдомена.
### Важно
1. **Настройка DNS**: Убедитесь, что ваши субдомены правильно настроены в DNS.
2. **Серверное конфигурирование**: Проверьте настройки вашего сервера (например, Nginx или Apache) так, чтобы запросы к субдомена корректно перенаправлялись на приложение FastAPI.
### Заключение
Использование мидлваров позволяет вам легко определять субдомен и делать маршрутизацию в зависимости от него. Такой подход позволяет избежать конфликтов в эндпоинтах и поддерживать чистую архитектуру приложения.