dispatch method

void dispatch(
  1. HttpRequest request
)

Dispatches an HttpRequest to the matching route.

Matching Priority:

  1. Exact static routes
  2. Dynamic routes (regex + type coercion)
  3. 404 Not Found

Parameters are injected into Zone and accessible via RouteParams.

Implementation

void dispatch(HttpRequest request) async {
  // final spoofMethod = request.uri.queryParameters['_method'];
  // HttpMethod method = _parseMethod(request.method);
  // if (spoofMethod != null) {
  //   method = _parseMethod(spoofMethod);
  // }

  HttpMethod method = _parseMethod(request.method);

  // Only check for method spoofing on POST requests with _method query parameter
  if (request.method == 'POST') {
    final spoofMethod = request.uri.queryParameters['_method'];
    if (spoofMethod != null) {
      method = _parseMethod(spoofMethod);
    }
  }

  final path = _normalize(request.uri.path);

  // 1. Static route lookup (fastest)
  final handler = _routes[method]?[path];
  // Get middleware for this specific method+path combination
  final middleware = _middlewareMap[method]?[path] ?? const [];

  if (handler != null) {
    _runMiddleware(
      request,
      middleware,
      0,
      () async => await handler(request),
    );
    return;
  }

  // 2. Dynamic route matching
  final compiled = _dynamicRoutes[method] ?? const [];
  for (final cr in compiled) {
    final match = cr.regex.firstMatch(path);
    if (match == null) continue;

    // Extract and coerce parameters
    final params = <String, dynamic>{};
    var valid = true;

    for (var i = 0; i < cr.paramNames.length; i++) {
      final raw = match.group(i + 1)!;
      final typeName = cr.paramTypes[i];
      final coerced = _coerce(raw, typeName);

      if (coerced is _Coerce && coerced.value == null) {
        valid = false;
        break;
      }
      params[cr.paramNames[i]] = coerced is _Coerce
          ? coerced.value!
          : coerced;
    }

    if (!valid) continue;

    // Execute with params in Zone
    runZoned(
      () => _runMiddleware(
        request,
        cr.middleware,
        0,
        () => cr.handler(request),
      ),
      zoneValues: RouteParams._zoneValues(params),
    );

    return;
  }

  // 3. Not found
  request.notFound();
}