5

假设我需要在提供一些结果之前检查一些 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。能够在任何路由匹配之前检查它会很有趣,这样当它到达路由块时,我们就知道它没问题。这样它也可以在不同的路线上重复使用。

我已经检查了beforeandbefore-match,显然你可以做到,但你需要分析请求对象才能做到这一点,没有简单的方法可以做到这一点。

或者,是否有任何方式定义“后备路由”,以便如果找不到 URI,则返回未找到?

4

1 回答 1

11

在给出中间件答案之前,我在这种情况下的第一选择通常是一种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,因为当没有路由与路径段匹配时,路由器会自动生成该路由。

但是,如果想要采用中间件方式,那么最简单的方法是获取path-segmentsof therequest并检查适当的部分:

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>;
        }
    }
}
于 2020-05-12T19:22:22.830 回答