Setup
createCaller uses the same source definitions as proxy mode. One line to set up.
ts
// Direct mode — import source and create caller inline
import { createCaller } from "@noverax/courier"
import { api } from "@/api"
const caller = createCaller(api)Direct mode calls the backend from the server itself. There is no /api/request proxy hop: requests go straight to the base URL the source declares.
Fetch Users (RSC)
Data is fetched during server rendering. The response is streamed as HTML — zero client-side fetch.
ts
// Server Component — runs on the server, zero client JS
const users = await caller.users.getAll()caller.users.getAll()RENDERED ON THE SERVER
{
"data": [
{
"id": 1,
"name": "Alice Johnson",
"email": "alice@example.com",
"role": "admin",
"createdAt": "2025-01-15T10:00:00Z"
},
{
"id": 2,
"name": "Bob Smith",
"email": "bob@example.com",
"role": "user",
"createdAt": "2025-02-20T14:30:00Z"
},
{
"id": 3,
"name": "Carol Williams",
"email": "carol@example.com",
"role": "moderator",
"createdAt": "2025-03-10T09:15:00Z"
}
],
"total": 3,
"page": 1,
"limit": 10
}Single User
Path parameters like :id are replaced automatically from the variables object.
ts
// Path params are passed as the variables object
const user = await caller.users.getById({ id: 1 })caller.users.getById({ id: 1 })RENDERED ON THE SERVER
{
"id": 1,
"name": "Alice Johnson",
"email": "alice@example.com",
"role": "admin",
"createdAt": "2025-01-15T10:00:00Z"
}Fetch Posts
Access any request group the same way. The API surface is identical to proxy mode.
ts
// Access any request group via dot-notation
const posts = await caller.posts.getAll()caller.posts.getAll()RENDERED ON THE SERVER
{
"data": [
{
"id": 1,
"userId": 1,
"title": "Getting Started with Courier",
"body": "Courier is a type-safe HTTP client...",
"tags": [
"courier",
"tutorial"
],
"createdAt": "2025-03-01T12:00:00Z"
},
{
"id": 2,
"userId": 1,
"title": "Proxy Mode vs Direct Mode",
"body": "Understanding the two modes of operation...",
"tags": [
"courier",
"architecture"
],
"createdAt": "2025-03-05T08:00:00Z"
},
{
"id": 3,
"userId": 2,
"title": "Request Groups Explained",
"body": "How to organize your API calls with groups...",
"tags": [
"courier",
"patterns"
],
"createdAt": "2025-03-08T16:00:00Z"
},
{
"id": 4,
"userId": 3,
"title": "Error Handling Best Practices",
"body": "Using HTTPError and isHTTPError for robust error handling...",
"tags": [
"courier",
"errors"
],
"createdAt": "2025-03-10T11:00:00Z"
}
],
"total": 4
}