Centralized API Client Standards
This skill defines the architectural standards for all API interactions within Arlis. Adhering to these rules prevents "fragmented fetching" and ensures consistency across the codebase.
Core Principles
- •Single Source of Truth: All API calls (internal and external) MUST be registered in
lib/api/client.ts. - •No Direct Fetch: Components should NEVER use the native
fetch()API or directsupabaseclient calls for data fetching. - •Type Safety: Every API method must have clearly defined Request and Response interfaces.
- •TanStack Hooks: UI components should interact with the API through centralized TanStack Query hooks in
lib/hooks/queries.ts.
Structure of the API Client (lib/api/client.ts)
The client is organized into namespaces/modules. Each module represents a logical domain.
typescript
// Good Pattern
export const api = {
vault: {
process: (id: string) => fetcher<ProcessingResult>("/api/vault/process", { ... }),
},
applications: {
list: () => supabase.from("applications").select("*"),
get: (id: string) => supabase.from("applications").select("*").eq("id", id).single(),
}
}
Data Fetching Workflow
1. Define the API Method
Add the endpoint or database query to lib/api/client.ts.
2. Create the Query Hook
Wrap the API method in a TanStack Query hook in lib/hooks/queries.ts.
typescript
export function useApplication(id: string) {
return useQuery({
queryKey: ['application', id],
queryFn: () => api.applications.get(id),
});
}
3. Use in Component
Call the hook in your component.
typescript
const { data, isLoading } = useApplication(id);
Forbidden Patterns
- •❌
const res = await fetch('/api/data')inside a component. - •❌
const { data } = await supabase.from('...')inside auseEffect. - •❌ Ad-hoc
useQuerydefinitions inside components (unless highly specific and non-reusable).
Handling Authentication
- •Client-side: Use the unified browser client. Session cookies are handled automatically by the browser.
- •Server/API side: Always verify the user using
lib/auth/server.tsbefore processing requests.
Real-time Integration
When using Supabase Realtime, subscribe within the centralized hooks or a dedicated state manager, ensuring the TanStack Query cache is invalidated or updated when a change occurs.