Prise en main

Qu'est-ce que Qora ?

Qora récupère, met en cache et synchronise les données serveur dans Flutter et Dart, et garde votre application utilisable quand le réseau ne l'est pas.

Qora est une bibliothèque de state serveur pour Flutter et Dart. Elle récupère, met en cache et synchronise les données que votre application charge depuis une API, et garde l'application utilisable quand le réseau ne l'est pas.

Si vous connaissez TanStack Query, vous connaissez déjà le modèle : les données serveur sont un cache avec un cycle de vie, pas un state global d'UI. Qora apporte ce modèle à Dart 3 avec les sealed classes et le pattern matching, sans génération de code.

Le problème résolu

Une donnée qui vient d'un serveur n'est pas un compteur ni un champ de formulaire. Elle peut être périmée, elle est partagée entre plusieurs écrans, elle change quand quelqu'un écrit dessus, et elle disparaît avec le réseau. Gérée à la main, chaque écran finit avec le même code :

without_qora.dart
class _UserScreenState extends State<UserScreen> {
  User? _user;
  Object? _error;
  bool _loading = false;

  @override
  void initState() {
    super.initState();
    _load();
  }

  Future<void> _load() async {
    setState(() => _loading = true);
    try {
      _user = await api.getUser(widget.userId); // re-téléchargé à chaque visite
      _error = null;
    } catch (e) {
      _error = e; // et l'utilisateur précédent est perdu en cas d'erreur
    } finally {
      setState(() => _loading = false);
    }
  }
  // ...et rien ne rafraîchit cet écran quand un autre modifie l'utilisateur.
}

Avec Qora, l'écran déclare de quelles données il a besoin et comment afficher chaque état :

user_screen.dart
QoraBuilder<User>(
  queryKey: ['users', userId],
  fetcher: () => api.getUser(userId),
  builder: (context, state, fetchStatus) => switch (state) {
    Success(:final data) => UserCard(data),
    Failure(:final error, :final previousData) =>
      previousData != null ? UserCard(previousData) : ErrorView(error),
    Loading(:final previousData) =>
      previousData != null ? UserCard(previousData) : const LoadingView(),
    Initial() => const SizedBox.shrink(),
  },
)

À la deuxième visite, l'utilisateur en cache s'affiche dès la première frame et se rafraîchit en arrière-plan. Deux widgets qui demandent ['users', userId] partagent une seule requête. Après client.invalidate(['users', userId]), chaque écran qui affiche cet utilisateur se met à jour. Le compilateur vérifie que chaque état est traité.

Ce que vous obtenez

Récupération et cache

  • Stale-while-revalidate : les données du cache d'abord, les données fraîches en arrière-plan
  • Déduplication des requêtes et retries automatiques avec backoff exponentiel
  • Invalidation par clé exacte, préfixe de clé, prédicat ou tag
  • Requêtes infinies, requêtes dépendantes, polling, prefetch

Hors-ligne

  • PersistQoraClient : données du cache sauvegardées et restaurées avant la première frame
  • Des requêtes qui se mettent en pause hors-ligne, le signalent via FetchStatus.paused et reprennent à la reconnexion
  • Une file de mutations hors-ligne qui rejoue les écritures dans l'ordre au retour du réseau (en mémoire ; persistée entre deux redémarrages en 1.4)

Écritures

  • Mutations avec onMutate / onError / onSuccess pour les mises à jour optimistes et le rollback
  • Invalidation automatique après une mutation réussie

Outillage

  • Un overlay DevTools dans l'application qui affiche chaque requête et chaque mutation en mode debug

Packages

PackageÀ utiliser pour
qora_flutterLes apps Flutter. Widgets (QoraScope, QoraBuilder, QoraMutationBuilder, InfiniteQueryBuilder), managers de cycle de vie et de connectivité. Inclut qora.
qora_hooksLes apps qui utilisent flutter_hooks : useQuery, useMutation, useInfiniteQuery, useFetchStatus.
qoraDart pur : CLI, serveurs, packages partagés, tests. Aucune dépendance Flutter.
qora_devtools_overlayLe panneau de debug dans l'application, en dépendance de développement.

State serveur et state client

Qora gère le state serveur : les données qui vivent sur un serveur et qui sont récupérées, mises en cache et resynchronisées. Il ne remplace pas votre state management pour le state client : l'onglet sélectionné, la saisie d'un formulaire, le thème. Gardez Riverpod, BLoC ou Provider pour cela ; les guides d'intégration montrent comment les combiner.

Quand ne pas utiliser Qora

  • Une application en lecture seule, toujours en ligne, qui n'affiche jamais deux fois les mêmes données. Un FutureBuilder suffit.
  • Des données temps réel poussées par une socket. Vous pouvez écrire les événements de la socket dans le cache avec setQueryData, mais le flux lui-même n'est pas le rôle de Qora.

Pour une comparaison avec cached_query et flutter_query, voir la page de comparaison.

Prérequis

  • Dart 3.5 ou plus récent
  • Flutter 3.24 ou plus récent (pour qora_flutter et qora_hooks)

Étapes suivantes

Copyright © 2026