# API Module - REST Endpoints ## Purpose REST API endpoints using FastAPI. Handles authentication, health checks, and supplementary game operations not suited for WebSocket (e.g., initial page loads, file uploads). ## Structure ``` app/api/ ├── __init__.py # Package marker ├── dependencies.py # FastAPI dependencies (auth, db session) └── routes/ ├── health.py # Health check endpoints ├── auth.py # Discord OAuth flow └── games.py # Game CRUD operations ``` ## Routes ### Health (`/health`) ```python GET /health # Basic health check GET /health/ready # Ready check with DB connectivity ``` ### Auth (`/auth`) ```python GET /auth/discord/login # Initiate OAuth flow (redirects to Discord) GET /auth/discord/callback/server # OAuth callback, sets HttpOnly cookies, redirects to frontend GET /auth/me # Get current user from cookie (SSR-compatible) POST /auth/refresh # Refresh access token using refresh cookie POST /auth/logout # Clear auth cookies ``` **Cookie-Based Auth**: Uses HttpOnly cookies with `path="/"` for SSR compatibility. See `COOKIE_AUTH_IMPLEMENTATION.md` for complete flow documentation. ### Games (`/games`) ```python POST /games # Create new game GET /games # List user's games GET /games/{id} # Get game details GET /games/{id}/lineup # Get game lineup ``` ## Dependencies ### Authentication ```python from app.api.dependencies import get_current_user @router.get("/games") async def list_games(user: User = Depends(get_current_user)): # user is authenticated ``` ### Database Session ```python from app.api.dependencies import get_db @router.post("/games") async def create_game(db: AsyncSession = Depends(get_db)): # Use db for operations ``` ## FastAPI Patterns ### Request Validation ```python from pydantic import BaseModel class CreateGameRequest(BaseModel): league_id: str home_team_id: int away_team_id: int @router.post("/games") async def create_game(request: CreateGameRequest): # request is validated ``` ### Response Model ```python class GameResponse(BaseModel): id: UUID status: str home_score: int away_score: int @router.get("/games/{id}", response_model=GameResponse) async def get_game(id: UUID): ... ``` ### Error Handling ```python from fastapi import HTTPException if not game: raise HTTPException(status_code=404, detail="Game not found") ``` ## Common Tasks ### Add New Endpoint 1. Create route in `app/api/routes/` 2. Define Pydantic request/response models 3. Add dependencies (auth, db) 4. Register router in `app/main.py` ### Protected Route ```python @router.get("/protected") async def protected_route( user: User = Depends(get_current_user) ): return {"user_id": user.id} ``` ## Registration Routes are registered in `app/main.py`: ```python from app.api.routes import health, auth, games app.include_router(health.router, prefix="/health") app.include_router(auth.router, prefix="/auth") app.include_router(games.router, prefix="/games") ``` ## API Docs FastAPI auto-generates documentation: - Swagger UI: `http://localhost:8000/docs` - ReDoc: `http://localhost:8000/redoc` ## References - **WebSocket**: Main game communication via `../websocket/CLAUDE.md` - **Auth Utilities**: See `../utils/auth.py` --- **Updated**: 2025-01-19