Ordering of filters and weight of http features
Opened this issue · 4 comments
Hi, in using @filter
is there a way to specify the order? The helidon docs says that they get applied based the order they're added to Helidon. Is that then based on how we add the beans / HttpFeature? There's no way at the moment to sort it in some specific order.
More generally speaking, filters and controllers create Http Features, which have weights that impact ordering. Is there any way to set this?
Also is each controller a HttpFeature? Can we group things?
Thanks!
Each controller is indeed a http feature, with each route within the controller registered in order of appearance. Filters are technically categorized as a route as well so you can group everything into a single controller.
Weight of regular controller routes rarely matter, as filters always go before routes even if registered after
Yes, we will need a way to order @Filter
s and that might be missing. For avaje-inject there is a @Priority
and ability to get a list of components ordered by the priority value so that might be all that we are after at this stage.
For avaje-nima when adding HttpFeatures we'd change that from using beanScope.list(HttpFeature.class)
to beanScope.listByPriority(HttpFeature.class)
.
Perhaps we are over thinking it in that the simplest approach is to have a dedicated controller for filters [and perhaps exceptions] and the order of the filter methods there is the order in which they are registered.
For example:
@Controller
final class ErrorController {
@ExceptionHandler(statusCode = 407)
Map<String, Object> runEx(RuntimeException ex, ServerRequest req, ServerResponse res) {
return Map.of("err", String.valueOf(ex));
}
@Filter
void filter1(FilterChain chain, RoutingResponse res) {
chain.proceed();
}
@Filter
void filter2(FilterChain chain, RoutingResponse res) {
chain.proceed();
}
@Filter
void filter(FilterChain chain, RoutingResponse res) {
chain.proceed();
}
}
generates ...
@Override
public void setup(HttpRouting.Builder routing) {
routing.error(RuntimeException.class, this::_runEx);
routing.addFilter(this::_filter1);
routing.addFilter(this::_filter2);
routing.addFilter(this::_filter);
}
... so the order of the filters registered just matches the order in which they are defined in source.