Queries & commands
Une page appelle une Frond avec une query pour lire ou une command pour écrire. L'appel est identifié par la classe de l'entité et le nom de l'opération. La classe porte les métadonnées et son nom sert de clé d'enregistrement.
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 } });
// → toutes les queries montées sur Post se revalident, automatiquement
useQuery
useQuery<T>(Entity, op, input?, opts?)
// input: CallInput | () => CallInput CallInput = { params?, query?, body? }
// opts: { immediate?: boolean } immediate: false → ne pas tirer au montage
Retour (tout est réactif) :
| Clé | Type | Notes |
|---|---|---|
data | Ref<T | null> | le résultat brut (ops à objet unique : findById, bySlug…) |
items | ComputedRef<T[]> | normalisation de liste : un tableau nu ou un ListResult se lisent pareil |
total, hasMore | du ListResult | présents quand l'op en rend un |
loading | Ref<boolean> | |
error | Ref<FougereError | null> | l'erreur typée ravivée (Erreurs) |
refresh | () => Promise<void> | revalidation manuelle — rarement utile, voir le lien |
Un input getter rend la query réactive à ses 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 rejette avec la même FougereError qu'il range dans error — attrapez-la en
try/catch ou lisez la ref, les deux styles marchent.
Le lien
Une command réussie sur une entité revalide les queries actives de cette entité. Après la publication d'un post, les listes de posts sont donc actualisées. Supprimer ce cache ne change pas le résultat des opérations, mais déclenche de nouvelles lectures.
Le fil — et le SSR
Le navigateur POSTe la même trame JSON-RPC que le transport process-à-process
(POST /_fougere/call, method: "post.list", params = l'invocation).
La documentation appelle enveloppe le point d'entrée
POST /_fougere/callutilisé paruseQuery,useCommandetinvoke. Les surfaces REST et GraphQL traduisent leurs protocoles vers les mêmes opérations.
Deux propriétés :
- En SSR, le même appel se replie en exécution in-process — pas de réseau, pas de port.
- Le navigateur ne fournit pas le
state: le serveur le construit depuis le contexte de requête, notamment pour y placer la session.
Le transport client ne relance pas automatiquement une command et conserve les erreurs typées (Erreurs).
Suite : Formulaires — état, validation et soumission.