Queries & commands
A page calls a Frond with a query for reads or a command for writes. A call is identified by the entity class and operation name. The class carries the metadata and its name is used as the registration key.
import Post from '@frond/blog/entities/Post';
const { items, total, hasMore, loading, error } = await useQuery<PostCard>(Post, 'list');
const publish = useCommand<Post>(Post, 'publish');
await publish.execute({ params: { id } });
// → every mounted query on Post revalidates, automatically
useQuery
useQuery<T>(Entity, op, input?, opts?)
// input: CallInput | () => CallInput CallInput = { params?, query?, body? }
// opts: { immediate?: boolean } immediate: false → don't fire on mount
Returns (all reactive):
| Key | Type | Notes |
|---|---|---|
data | Ref<T | null> | the raw result (single object ops: findById, bySlug…) |
items | ComputedRef<T[]> | list normalization: a bare array or a ListResult both read as items |
total, hasMore | from ListResult | present when the op returns one |
loading | Ref<boolean> | |
error | Ref<FougereError | null> | the revived typed error (Errors) |
refresh | () => Promise<void> | manual revalidation — rarely needed, see the link |
A getter input makes the query reactive to its arguments:
const { items } = await useQuery<Hit>(Post, 'searchByTitle',
() => ({ body: { title: submitted.value } }),
{ immediate: false });
useCommand
useCommand<T>(Entity, op)
// → { execute(input?): Promise<T>, loading: Ref<boolean>, error: Ref<FougereError | null> }
execute rejects with the same FougereError it stores in error — await it in a
try/catch or read the ref, either style works.
The link
A successful command on an entity revalidates active queries for that entity. After a post is published, post lists are therefore refreshed. Clearing this cache does not change operation results, but causes new reads.
The wire — and SSR
The browser POSTs the same JSON-RPC frame process-to-process transport uses
(POST /_fougere/call, method: "post.list", params = the invocation).
The documentation calls the
POST /_fougere/callendpoint used byuseQuery,useCommand, andinvokethe envelope. The REST and GraphQL surfaces translate their protocols to the same operations.
Two properties:
- During SSR, the same call collapses to in-process execution — no network, no port.
- The browser does not provide
state: the server builds it from the request context, including the session.
The client transport does not automatically retry commands and preserves typed errors (Errors).
Next: Forms — state, validation, and submission.