Saltar a contenido

Flutter y Dart Frog

KanjiIQ usa Flutter para el frontend y Dart Frog para el backend — un ecosistema Dart unificado que simplifica el desarrollo, las pruebas y el despliegue.

Flutter Web

¿Por qué Flutter?

  • Un solo código base: Web, iOS, Android y escritorio desde una sola fuente
  • Material Design 3: UI con apariencia nativa y mínimo estilizado personalizado
  • Sólido soporte i18n: Localización integrada basada en ARB para 51 idiomas
  • Soporte offline: SQLite mediante el paquete sqflite para caché de datos local

Proceso de compilación

Flutter Web produce assets estáticos (HTML, JS, CSS, imágenes) que son servidos por 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

Argumentos de compilación:

  • API_URL — Endpoint de la API del backend (por defecto /api/ relativo)
  • CACHEBUST — Fuerza compilaciones frescas en CI/CD (basado en marca de tiempo)

Gestión de estado

KanjiIQ usa Provider para la gestión de estado:

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

Provider fue elegido sobre las alternativas (Riverpod, BLoC) por su simplicidad — las necesidades de estado de KanjiIQ son directas (estado de sesión de tarjetas, preferencias de locale, estado de conectividad).

Enrutamiento

GoRouter gestiona el enrutamiento declarativo con soporte para:

  • Deep linking (navegación basada en URL)
  • Guardas de redirección (verificaciones de autenticación)
  • Rutas anidadas para jerarquía de pantallas

Backend Dart Frog

¿Por qué Dart Frog?

  • Mismo lenguaje que el frontend: Los modelos Dart se pueden compartir
  • Ligero: Overhead mínimo del framework, similar a Express.js
  • Basado en middleware: Pipeline de solicitudes limpio con middleware componible
  • Hot reload: Iteración rápida en desarrollo con dart_frog dev

Ciclo de vida de una solicitud

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

Cada ruta es un archivo Dart en el directorio routes/. Dart Frog usa enrutamiento basado en archivos:

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
│       └── ...

Proceso de compilación

# 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"]

El paso de compilación compila Dart a un binario de servidor independiente con todas las rutas pre-registradas.

Ecosistema Dart compartido

Tanto el frontend como el backend se benefician de las mismas herramientas de Dart:

Herramienta Propósito
dart analyze Análisis estático en ambos códigos base
dart format Estilo de código consistente
dart test Pruebas unitarias y de integración
pub.dev Repositorio de paquetes compartido

Preparación para móvil

El frontend Flutter está diseñado para despliegue multiplataforma:

  • Web: Actualmente desplegado (objetivo principal)
  • iOS/Android: Listo para compilar con flutter build apk / flutter build ipa
  • Escritorio: Soportado mediante flutter build macos / linux / windows

La arquitectura offline-first (caché SQLite, detección de conectividad, sincronización en segundo plano) fue diseñada pensando en móvil desde el inicio.