where method
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;
}