where method

Route where(
  1. String param,
  2. String regex
)

only match the route added last when its param matches regex. Else the route does not match, and the next route is tried (or the client gets 404). The regex must match the whole param text. Use (?:...) for groups, not (...). The value is checked again after % decoding, so the decoded text must match too (a %20 is a space then).

Route.get('users/{id}', controller).where('id', '[0-9]+');
Route.get('docs/{page}', controller).where('page', '.*');

Implementation

Route where(String param, String regex) {
  RouteData? last = _last;
  if (last == null) {
    throw StateError('Route.where("$param"): there is no route.');
  }
  int groups;
  try {
    groups = RegExp('(?:$regex)|').firstMatch('')!.groupCount;
  } on FormatException catch (error) {
    throw ArgumentError.value(regex, 'regex', error.message);
  }
  if (groups > 0) {
    throw ArgumentError.value(
      regex,
      'regex',
      'Use (?:...) for a group, not (...)',
    );
  }
  for (RouteData data in _lastGroup ?? <RouteData>[last]) {
    if (!data.paramNames.contains(param)) {
      throw ArgumentError.value(
        param,
        'param',
        'Route ${data.method} ${data.path} has no param "$param"',
      );
    }
    data.where(param, regex);
  }
  return this;
}