Typed API Endpoints & RPC
Relevant source files
The following files were used as context for generating this wiki page:
Farm.js provides a comprehensive system for building type-safe API routes using a file-based directory structure. The framework utilizes createEndpoint (or endpoint) to define handlers with built-in validation for request bodies, query parameters, and URL segments. This architecture ensures that both server-side logic and client-side calls remain synchronized via generated TypeScript declarations.
The system supports Remote Procedure Call (RPC) patterns through createApiClients, which enables developers to call API routes as standard functions. When called on the server, these dispatches resolve locally to avoid HTTP overhead; when called from the browser, the runtime automatically executes the corresponding HTTP request.
API Route Architecture
API routes reside within the src/app/api/**/route.ts directory structure. The framework matches incoming request paths to these files, providing a specialized EndpointContext that contains parsed and validated data.
Request Flow and Discovery
In development mode, the APIRouteManager discovers routes by scanning the application directory for route.ts files. It identifies supported HTTP methods and maps them to the corresponding handlers.
The diagram shows the sequence from request arrival at the development server to handler execution.
Sources: packages/farm/src/vite.ts:789-805, ARCHITECTURE.md:126-133
Endpoint Configuration
Handlers are defined using a configuration object that includes schemas for input validation.
| Field | Description | Type |
|---|---|---|
method | The HTTP method (GET, POST, etc.) | HttpMethod |
body | Zod schema for request body validation | z.ZodType |
query | Zod schema for URL query parameters | z.ZodType |
params | Zod schema for dynamic URL segments | z.ZodType |
handler | The logic executed when the route is matched | EndpointHandler |
Sources: packages/farm/types/api.d.ts:70-80, examples/ssr-ssg-demo/src/app/api-demo/page.tsx:128-144
The Endpoint Context
Every handler receives an EndpointContext object. This object provides structured access to the request data, ensuring that handlers do not need to manually parse strings or handle raw streams unless necessary.
Data Structures
export interface EndpointContext<TBody = unknown, TQuery = unknown, TParams = unknown> {
body: TBody;
query: TQuery;
params: TParams;
headers: Headers;
request: Request;
}
Sources: packages/farm/types/api.d.ts:50-58
Validation Logic
The framework performs validation before the handler executes. If a request fails the Zod schema validation for query or body parameters, the framework rejects the request with an error before reaching the business logic.
Sources: SKILL.md:158-160, packages/farm/src/vite.ts:838-855
RPC and Client Callers
Farm.js encourages the use of a shared caller instance to facilitate RPC-like interactions between the client and server.
Local vs. HTTP Dispatch
The createApiClients factory generates two primary objects: api and apiClient.
- Local API (
api): Used during server-side rendering. It dispatches calls directly to the route definitions, bypassing the network stack and skipping HTTP-specific middleware. - Remote Client (
apiClient): Used in the browser. It translates function calls into HTTP requests (e.g.,POST /api/users) and handles the network lifecycle, including retries and optimistic updates.
The sequence diagram illustrates the remote call flow from a browser component.
Sources: SKILL.md:162-177, packages/farm/types/api.d.ts:9-10
Specialized Streaming
For data-intensive operations, the API system supports typed JSON streams. The jsonStream utility allows handlers to return an AsyncIterable, which the runtime streams to the client.
Stream Handling
- Server-side: Use
jsonStream(iterable)to start a chunked transfer. - Client-side: Use
readJSONStream(response)to consume the typed chunks as they arrive.
Sources: packages/farm/types/api.d.ts:28-48
Integration with Vite Dev Server
During development, API routes are handled by a dedicated Vite middleware. This middleware intercepts requests to paths matching the API base path (defaulting to /api).
Development Features
- Route Refreshing: The
APIRouteManagerinvalidates and re-scans routes whenroute.tsfiles are added or modified. - Error Reporting: Unhandled errors in API handlers are captured and logged to the terminal with Farm.js branding, while returning a 500 status to the client.
- Body Size Limits: The middleware enforces body size limits configured in
farm.config.ts.
Sources: packages/farm/src/vite.ts:795-810, packages/farm/src/vite.ts:860-865
Conclusion
The Typed API and RPC system in Farm.js bridges the gap between client and server by providing a unified, schema-validated communication layer. By leveraging file-based routing and generated TypeScript clients, it eliminates the need for manual fetch orchestration while maintaining high performance through local server-side dispatching.