🌐 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.
📡 Notable Endpoints
POST /api/v1/assets/prices/current — Bulk Current Price
Returns the live current price for a list of asset IDs. The response is designed for the LiveTicker frontend component.
Request body: List[int] — asset IDs.
Response (FACurrentPriceResponse):
{
"results": [
{
"asset_id": 1,
"value": "123.45",
"currency": "EUR",
"source": "justetf",
"timestamp": "2026-04-10T12:00:00Z",
"error": null
}
]
}
Resolution strategy (per asset):
- Ask the assigned provider's
get_current_value()(live quote from JustETF WebSocket, Yahoo Financeticker.info, etc.) - Fallback: if the provider fails or has no live feed, return the latest close price from the database.
This endpoint is used by the LiveTicker component in the Dashboard and Asset Detail pages, and by the Asset List page for inline live prices in cards.