Aller au contenu

Flutter et Dart Frog

KanjiIQ utilise Flutter pour le frontend et Dart Frog pour le backend — un écosystème Dart unifié qui simplifie le développement, les tests et le déploiement.

Flutter Web

Pourquoi Flutter ?

  • Code unique : Web, iOS, Android et desktop à partir d'une seule source
  • Material Design 3 : Interface native avec un minimum de personnalisation
  • Support i18n solide : Localisation intégrée basée sur ARB pour 51 langues
  • Support hors ligne : SQLite via le package sqflite pour le cache local des données

Processus de build

Flutter Web produit des assets statiques (HTML, JS, CSS, images) qui sont servis par Nginx :

# From Dockerfile.frontend (simplified)
FROM ubuntu:22.04 AS builder
# Install Flutter SDK
RUN flutter gen-l10n          # Generate 51 localization files
RUN flutter build web --release

FROM nginx:alpine
COPY --from=builder /app/frontend/build/web /usr/share/nginx/html

Arguments de build :

  • API_URL — Endpoint de l'API backend (par défaut : /api/ relatif)
  • CACHEBUST — Force des builds frais en CI/CD (basé sur l'horodatage)

Gestion d'état

KanjiIQ utilise Provider pour la gestion d'état :

MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => StudyProvider()),
    // Locale, connectivity, sync providers
  ],
  child: MyApp(),
)

Provider a été choisi par rapport aux alternatives (Riverpod, BLoC) pour sa simplicité — les besoins en gestion d'état de KanjiIQ sont simples (état de la session de flashcards, préférences de locale, état de la connectivité).

Routage

GoRouter gère le routage déclaratif avec le support de :

  • Liens profonds (navigation basée sur l'URL)
  • Gardes de redirection (vérifications d'authentification)
  • Routes imbriquées pour la hiérarchie des écrans

Backend Dart Frog

Pourquoi Dart Frog ?

  • Même langage que le frontend : Les modèles Dart peuvent être partagés
  • Léger : Surcharge minimale du framework, similaire à Express.js
  • Basé sur les middlewares : Pipeline de requêtes propre avec des middlewares composables
  • Hot reload : Itération de développement rapide avec dart_frog dev

Cycle de vie des requêtes

graph LR
    R[HTTP Request] --> MW[Middleware Stack]
    MW --> RH[Route Handler]
    RH --> DB[(PostgreSQL)]
    DB --> RH
    RH --> RS[JSON Response]

Chaque route est un fichier Dart dans le répertoire routes/. Dart Frog utilise le routage basé sur les fichiers :

backend/routes/
├── _middleware.dart           # Global middleware
├── api/v1/
│   ├── kanji/
│   │   ├── index.dart         # GET /api/v1/kanji
│   │   ├── [id].dart          # GET /api/v1/kanji/:id
│   │   └── random/
│   │       └── index.dart     # GET /api/v1/kanji/random
│   └── admin/
│       ├── _middleware.dart    # Admin auth middleware
│       └── ...

Processus de build

# From Dockerfile.backend (simplified)
FROM dart:stable AS builder
RUN dart pub global activate dart_frog_cli
RUN dart_frog build

FROM dart:stable
COPY --from=builder /app/build /app
CMD ["./server"]

L'étape de build compile Dart en un binaire serveur autonome avec toutes les routes pré-enregistrées.

Écosystème Dart partagé

Le frontend et le backend bénéficient tous deux des mêmes outils Dart :

Outil Fonction
dart analyze Analyse statique sur les deux bases de code
dart format Style de code cohérent
dart test Tests unitaires et d'intégration
pub.dev Dépôt de packages partagé

Prêt pour le mobile

Le frontend Flutter est conçu pour le déploiement multi-plateforme :

  • Web : Actuellement déployé (cible principale)
  • iOS/Android : Prêt à compiler avec flutter build apk / flutter build ipa
  • Desktop : Pris en charge via flutter build macos / linux / windows

L'architecture hors ligne d'abord (cache SQLite, détection de connectivité, synchronisation en arrière-plan) a été conçue avec le mobile à l'esprit dès le départ.