Flutter & Dart Frog¶
KanjiIQ verwendet Flutter für das Frontend und Dart Frog für das Backend — ein einheitliches Dart-Ökosystem, das Entwicklung, Testen und Deployment vereinfacht.
Flutter Web¶
Warum Flutter?¶
- Eine einzige Codebasis: Web, iOS, Android und Desktop aus einer Quelle
- Material Design 3: Nativ wirkende Benutzeroberfläche mit minimalem individuellem Styling
- Starke i18n-Unterstützung: Eingebaute ARB-basierte Lokalisierung für 51 Sprachen
- Offline-Unterstützung: SQLite über das
sqflite-Paket für lokales Daten-Caching
Build-Prozess¶
Flutter Web erzeugt statische Assets (HTML, JS, CSS, Bilder), die von Nginx bereitgestellt werden:
# 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
Build-Argumente:
API_URL— Backend API-Endpunkt (Standard: relativer/api/)CACHEBUST— Erzwingt frische Builds in CI/CD (zeitstempelbasiert)
Zustandsverwaltung¶
KanjiIQ verwendet Provider für die Zustandsverwaltung:
MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => StudyProvider()),
// Locale, connectivity, sync providers
],
child: MyApp(),
)
Provider wurde gegenüber Alternativen (Riverpod, BLoC) wegen seiner Einfachheit gewählt — die Zustandsanforderungen von KanjiIQ sind unkompliziert (Karteikarten-Sitzungszustand, Locale-Einstellungen, Verbindungsstatus).
Routing¶
GoRouter übernimmt deklaratives Routing mit Unterstützung für:
- Deep Linking (URL-basierte Navigation)
- Redirect-Guards (Authentifizierungsprüfungen)
- Verschachtelte Routen für Bildschirmhierarchie
Dart Frog Backend¶
Warum Dart Frog?¶
- Gleiche Sprache wie das Frontend: Dart-Modelle können geteilt werden
- Leichtgewichtig: Minimaler Framework-Overhead, ähnlich wie Express.js
- Middleware-basiert: Saubere Anfrage-Pipeline mit komponierbarer Middleware
- Hot Reload: Schnelle Entwicklungsiteration mit
dart_frog dev
Anfrage-Lebenszyklus¶
graph LR
R[HTTP Request] --> MW[Middleware Stack]
MW --> RH[Route Handler]
RH --> DB[(PostgreSQL)]
DB --> RH
RH --> RS[JSON Response]
Jede Route ist eine Dart-Datei im routes/-Verzeichnis. Dart Frog verwendet dateibasiertes Routing:
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
│ └── ...
Build-Prozess¶
# 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"]
Der Build-Schritt kompiliert Dart zu einer eigenständigen Server-Binary mit allen vorregistrierten Routen.
Gemeinsames Dart-Ökosystem¶
Sowohl Frontend als auch Backend profitieren vom selben Dart-Tooling:
| Werkzeug | Zweck |
|---|---|
dart analyze |
Statische Analyse über beide Codebasen |
dart format |
Einheitlicher Code-Stil |
dart test |
Unit- und Integrationstests |
pub.dev |
Gemeinsames Paket-Repository |
Mobile Bereitschaft¶
Das Flutter-Frontend ist für Multi-Plattform-Deployment konzipiert:
- Web: Derzeit bereitgestellt (primäres Ziel)
- iOS/Android: Build-bereit mit
flutter build apk/flutter build ipa - Desktop: Unterstützt über
flutter build macos/linux/windows
Die Offline-First-Architektur (SQLite-Cache, Konnektivitätserkennung, Hintergrundsynchronisation) wurde von Anfang an mit Mobilgeräten im Blick entwickelt.