Requêtes dépendantes
Une requête dépendante ne se déclenche qu'après qu'une autre requête ait chargé ses données avec succès. C'est le pattern pour la récupération de données séquentielle : charger d'abord la session, puis le profil utilisateur ; charger un projet, puis ses membres.
dependsOn
Définir QoraOptions.dependsOn à la clé de la requête prérequise. Qora s'abonne en interne et déclenche le fetch dépendant quand les données deviennent disponibles.
// Étape 1 : récupérer la session
client.watchQuery<Session>(
key: ['session'],
fetcher: () => api.getSession(),
);
// Étape 2 : se déclenche automatiquement une fois que ['session'] a des données
client.watchQuery<User>(
key: ['user'],
fetcher: () => api.getUser(session!.userId),
options: QoraOptions(dependsOn: ['session']),
);
Comportement par API
| API | Comportement quand la dépendance n'est pas résolue |
|---|---|
watchQuery | S'abonne de façon réactive ; se déclenche quand la dépendance atteint Success |
fetchQuery | Lève StateError immédiatement. Appeler après la résolution de la dépendance. |
prefetch | Ignore silencieusement. Sûr à appeler de façon spéculative. |
Dans Flutter : QoraBuilder
Le pattern Flutter le plus propre est d'imbriquer un QoraBuilder pour la requête dépendante dans le cas success du parent :
QoraBuilder<Session>(
queryKey: ['session'],
fetcher: () => api.getSession(),
builder: (context, sessionState, refetch) => switch (sessionState) {
Loading() || Initial() => const CircularProgressIndicator(),
Failure(:final error) => ErrorWidget('$error'),
Success(:final data) => QoraBuilder<User>(
queryKey: ['user', data.userId],
fetcher: () => api.getUser(data.userId),
builder: (context, userState, _) => switch (userState) {
Success(:final data) => ProfileCard(data),
Loading() => const CircularProgressIndicator(),
Failure(:final error) => ErrorWidget('$error'),
Initial() => const SizedBox.shrink(),
},
),
},
)
Le QoraBuilder interne ne se monte que quand la session est prête, donc le fetch dépendant ne se déclenche jamais prématurément.
Utiliser dependsOn avec watchQuery
Quand les deux requêtes doivent être actives simultanément (ex. dans une couche repository sans Flutter), utiliser dependsOn :
class UserRepository {
final QoraClient _client;
Stream<QoraState<User>> watchCurrentUser() {
// S'assurer que la requête de session est en cours
_client.watchQuery<Session>(
key: ['session'],
fetcher: () => api.getSession(),
);
// Cette requête attend que ['session'] ait des données avant de fetcher
return _client.watchQuery<User>(
key: ['user'],
fetcher: () async {
final session = _client.getQueryData<Session>(['session'])!;
return api.getUser(session.userId);
},
options: const QoraOptions(dependsOn: ['session']),
);
}
}
Chaîner plusieurs dépendances
Une requête ne peut déclarer qu'un seul dependsOn. Pour une chaîne de trois requêtes, imbriquer le dependsOn à chaque étape :
// 1 : session
client.watchQuery<Session>(key: ['session'], fetcher: () => api.getSession());
// 2 : user (dépend de session)
client.watchQuery<User>(
key: ['user'],
fetcher: () => api.getUser(session!.userId),
options: const QoraOptions(dependsOn: ['session']),
);
// 3 : projects (dépend de user)
client.watchQuery<List<Project>>(
key: ['projects'],
fetcher: () => api.getProjects(user!.orgId),
options: const QoraOptions(dependsOn: ['user']),
);
fetchQuery et dépendances
fetchQuery lève une exception immédiatement si la dépendance n'est pas résolue. L'utiliser uniquement après avoir vérifié que la dépendance a des données :
// Sûr uniquement une fois que ['session'] est à l'état Success
final user = await client.fetchQuery<User>(
key: ['user'],
fetcher: () => api.getUser(session!.userId),
options: QoraOptions(dependsOn: ['session']),
);
Pour le code réactif, préférer watchQuery : il gère automatiquement le timing.
Voir aussi
- API QoraOptions :
dependsOn,enabled - QoraBuilder : Binding de requête au niveau widget
- Démarrage rapide
Requêtes infinies
Implémenter la pagination avant et bidirectionnelle avec InfiniteQueryObserver : chargement au scroll, pull-to-refresh, pagination fenêtrée et APIs basées sur curseur.
Annulation
Utiliser CancelToken pour interrompre coopérativement les fetchs en cours : lors de la navigation, d'un timeout ou d'une action utilisateur.