🌐 API & Frontend Communication
This section explains how the SvelteKit frontend communicates with the FastAPI backend, ensuring type safety and consistency across the stack.
🏗️ Architecture
LibreFolio uses a strict OpenAPI-first approach (generated from code) to synchronize the backend and frontend.
graph LR
Backend[FastAPI Backend] -- "Generates" --> OpenAPI[openapi.json]
OpenAPI -- "openapi-zod-client" --> TSClient[generated.ts]
TSClient -- "Imports" --> Frontend[SvelteKit Frontend]
Frontend -- "Calls" --> TSClient
TSClient -- "Validates (Zod)" --> TSClient
TSClient -- "HTTP Request" --> Backend
🔄 The Synchronization Workflow
The synchronization process is automated via dev.py:
- Backend Definition: API endpoints and Pydantic models are defined in Python (
backend/app/api/). - Schema Export:
./dev.py api schemastarts a temporary backend process to export theopenapi.jsonfile. - Client Generation:
./dev.py api clientusesopenapi-zod-clientto read the JSON schema and generate a TypeScript client (frontend/src/lib/api/generated.ts).
One-step sync
Use ./dev.py api sync to run both steps (schema export + client generation) in a single command. This is the recommended workflow after any backend API change.
💻 CLI Commands
# Export OpenAPI schema only
./dev.py api schema
# Generate TypeScript client from existing schema
./dev.py api client
# Both in one step (recommended)
./dev.py api sync
⚡ Generated Client Features
The generated client provides:
- TypeScript Interfaces: Matching the Pydantic models (e.g.,
AssetRead,TransactionCreate). - Zod Schemas: Runtime validation schemas for API responses.
- API Functions: Typed functions for each endpoint (e.g.,
api.getAssets()).
🖥️ Usage in Frontend
In the SvelteKit frontend, developers import the generated client to make API calls.
import { api } from '$lib/api';
async function loadPortfolio() {
// 'data' is fully typed as PortfolioResponse
const data = await api.getPortfolio();
return data;
}
This ensures that if the backend API changes (e.g., a field is renamed), the frontend build will fail with a type error, preventing runtime crashes.