Een Finch-applicatie uitvoeren

Een Finch-applicatie heeft twee bestanden nodig: app.dart (applicatie-opzet) en een beginpunt — doorgaans bin/main.dart voor productie of lib/serve.dart voor ontwikkeling met bestandsbewaking.

app.dart — Applicatie-opzet

app.dart maakt de FinchApp-instantie aan, registreert routes en definieert main(). Dit is de canonieke structuur op basis van het Finch-voorbeeldproject:

// lib/app.dart
import 'package:finch/finch_app.dart';
import 'package:finch/finch_tools.dart';
import 'package:finch/finch_route.dart';
import 'package:finch/finch_console.dart';
import 'route/web_route.dart';

FinchConfigs configs = FinchConfigs(
  port: env.getInt('DOMAIN_PORT', 8080),
  domain: env.get('DOMAIN', 'localhost'),
  publicDir: pathTo(env.get('PUBLIC_DIR', './public')),
  widgetsPath: pathTo(env.get('WIDGETS_PATH', './lib/widgets')),
  widgetsType: env.get('WIDGETS_TYPE', 'j2.html'),
  languagePath: pathTo(env.get('LANGUAGE_PATH', './lib/languages')),
  enableLocalDebugger: env.getBool('ENABLE_LOCAL_DEBUGGER', false),
);

final app = FinchApp(configs: configs);

void main([List<String>? args]) async {
  app.addRouting(getWebRoute);

  app.start(args).then((value) {
    Console.p('Server started: http://localhost:${value.port}');
  });
}

Routefunctie

Routes worden gedefinieerd in een functie die een Request ontvangt en Future<List<FinchRoute>> teruggeeft:

// lib/route/web_route.dart
import 'package:finch/finch_route.dart';
import '../controllers/home_controller.dart';

final homeController = HomeController();

Future<List<FinchRoute>> getWebRoute() async {
  return [
    FinchRoute(
      key: 'root',
      path: '/',
      methods: Methods.ONLY_GET,
      index: homeController.index,
    ),
    FinchRoute(
      key: 'root.api',
      path: 'api/hello',
      methods: Methods.ONLY_GET,
      index: homeController.hello,
    ),
  ];
}

Inline routes (verkorte notatie)

Voor eenvoudige of snelle routes heeft FinchApp verkorte methoden. De index-callback ontvangt de Request als parameter:

app
  ..get(
    path: '/ping',
    index: (rq) async => rq.renderString(text: 'pong'),
  )
  ..post(
    path: '/echo',
    index: (rq) async {
      var body = rq.get<String>('message', def: '');
      return rq.renderString(text: body);
    },
  )
  ..postGet(
    path: '/form',
    index: (rq) async => rq.renderString(text: 'GET or POST'),
  );

Ontwikkeling: serve.dart met bestandswatcher

Gebruik tijdens de ontwikkeling lib/serve.dart (gegenereerd door finch create). Dit bestand voert main() uit vanuit app.dart en bewaakt widget- en taalbestanden op wijzigingen, waarbij de Dart-sourcemaps automatisch worden gegenereerd zonder de server volledig opnieuw te starten:

finch serve -p lib/serve.dart
# of
dart run lib/serve.dart

De watcher roept bij bestandswijzigingen de LanguageToDart- en WidgetToDart-converters aan, en stelt vervolgens de verbonden debugbalk op de hoogte om de pagina opnieuw te laden.

Productie: binary compilatie

Compileer naar een zelfstandige native binary:

finch build -a lib/app.dart -o ./build/app
./build/app

Of gebruik de meegeleverde Dockerfile / docker-compose. Zie Docker.

Cron-taken

Registreer geplande taken met app.registerCron():

app.registerCron(
  FinchCron(
    schedule: FinchCron.evryDay(2),   // Elke 2 dagen
    onCron: (index, cron) async {
      // opruimtaak uitvoeren
    },
    delayFirstMoment: true,
  ).start(),
);

// Standaard cron-expressie
app.registerCron(
  FinchCron(
    schedule: '0 * * * *',  // Elk uur
    onCron: (index, cron) async {
      // uurlijkse taak uitvoeren
    },
  ).start(),
);

Gelogde fouten afhandelen

Registreer een callback met app.onError() om op de hoogte te worden gesteld wanneer er een fout wordt gelogd via Console (bijv. Console.e(...)), bijvoorbeeld om deze door te sturen naar een externe monitoringservice:

app.onError((error, type) {
  // 'type' is het loglevel, bijv. 'error'
  MyMonitoringService.report(error, type);
});

Argumenten doorgeven

Geef args altijd door van main naar app.start(). Dit zorgt ervoor dat CLI-opdrachten zoals migrate en aangepaste opdrachten werken:

void main([List<String>? args]) async {
  app.addRouting(getWebRoute);
  app.start(args);
}
dart run lib/app.dart migrate --init