如何在 Cro 中插入一些路由检查中间件?
How can I insert some route-checking middleware in Cro?
假设我需要在提供某些结果之前检查一些 URI。我可以这样做:
sub type-routes {
route {
get -> Str $type where $type ∈ @food-types {
my %ingredients-table = $rrr.calories-table;
my @result = %ingredients-table.keys.grep: {
%ingredients-table{$_}{$type} };
content 'application/json', @result;
}
get -> Str $type where $type ∉ @food-types {
not-found;
}
}
}
基本上,在这种情况下,现有产品和不存在产品的签名不同。但是,同一 URI 将在所有路由中使用。能够在 在 任何路由匹配之前检查它会很有趣,这样当它到达路由块时,我们就知道它没问题。这样它也可以在不同的路线上重复使用。
我检查过before
and before-match
,显然你可以做到,但你需要分析请求对象才能做到这一点,没有简单的方法可以做到这一点。
或者,是否有任何方法可以定义 "fallback-route",以便在未找到 URI 时返回 not-found?
在给出中间件答案之前,我在这种情况下的第一个选择通常是 subset
类型:
sub type-routes {
route {
my constant @food-types = <burgers pizzas beer>;
my subset Food of Str where { $^type ∈ @food-types }
get -> Food $type {
my %ingredients-table = $rrr.calories-table;
my @result = %ingredients-table.keys.grep: {
%ingredients-table{$_}{$type} };
content 'application/json', @result;
}
}
}
这样,Food
可以在任意多条路线上使用。不需要回退路由(无论是在这个解决方案中还是在原始问题中)来生成 not-found
,因为当没有路由与路径段匹配时路由器会自动生成。
但是,如果想采用中间件方式,那么最简单的方法是获取 request
的 path-segments
并检查相应的部分:
sub type-routes {
route {
my constant @food-types = <burgers pizzas beer>;
before {
not-found unless request.path-segments[0] ∈ @food-types;
}
get -> Str $type {
content 'application/json', <123 456>;
}
}
}
假设我需要在提供某些结果之前检查一些 URI。我可以这样做:
sub type-routes {
route {
get -> Str $type where $type ∈ @food-types {
my %ingredients-table = $rrr.calories-table;
my @result = %ingredients-table.keys.grep: {
%ingredients-table{$_}{$type} };
content 'application/json', @result;
}
get -> Str $type where $type ∉ @food-types {
not-found;
}
}
}
基本上,在这种情况下,现有产品和不存在产品的签名不同。但是,同一 URI 将在所有路由中使用。能够在 在 任何路由匹配之前检查它会很有趣,这样当它到达路由块时,我们就知道它没问题。这样它也可以在不同的路线上重复使用。
我检查过before
and before-match
,显然你可以做到,但你需要分析请求对象才能做到这一点,没有简单的方法可以做到这一点。
或者,是否有任何方法可以定义 "fallback-route",以便在未找到 URI 时返回 not-found?
在给出中间件答案之前,我在这种情况下的第一个选择通常是 subset
类型:
sub type-routes {
route {
my constant @food-types = <burgers pizzas beer>;
my subset Food of Str where { $^type ∈ @food-types }
get -> Food $type {
my %ingredients-table = $rrr.calories-table;
my @result = %ingredients-table.keys.grep: {
%ingredients-table{$_}{$type} };
content 'application/json', @result;
}
}
}
这样,Food
可以在任意多条路线上使用。不需要回退路由(无论是在这个解决方案中还是在原始问题中)来生成 not-found
,因为当没有路由与路径段匹配时路由器会自动生成。
但是,如果想采用中间件方式,那么最简单的方法是获取 request
的 path-segments
并检查相应的部分:
sub type-routes {
route {
my constant @food-types = <burgers pizzas beer>;
before {
not-found unless request.path-segments[0] ∈ @food-types;
}
get -> Str $type {
content 'application/json', <123 456>;
}
}
}