Программирование

Авторегистрация ClientRequestFilter в Quarkus REST клиенте

Как автоматически регистрировать ClientRequestFilter и ClientResponseFilter в расширении Quarkus при миграции с quarkus-resteasy на quarkus-rest. Решение через BuildStep и RestClientEngine для всех REST-клиентов.

Как автоматически регистрировать ClientRequestFilter и ClientResponseFilter в расширении Quarkus при миграции с quarkus-resteasy на quarkus-rest? Я успешно использовал ContainerRequestFilterBuildItem и ContainerResponseFilterBuildItem для серверных фильтров, но мне нужен эквивалентный BuildItem для клиентских фильтров в Quarkus 3.27. Ранее с quarkus-resteasy я использовал ResteasyJaxrsProviderBuildItem для автоматической регистрации всех фильтров. Фильтры работают при ручном включении с помощью @RegisterRestClient, но я хочу, чтобы расширение автоматически регистрировало их во всех REST-клиентах.

В Quarkus 3.27 при миграции с quarkus-resteasy на quarkus-rest автоматическая регистрация ClientRequestFilter и ClientResponseFilter для всех quarkus rest client не имеет прямого эквивалента ResteasyJaxrsProviderBuildItem. Вместо этого расширение может использовать RestClientBuilder с глобальным RestClientEngine или кастомный BuildStep, который сканирует и регистрирует провайдеры через io.smallrye.mutiny.infrastructure.Infrastructure. А для серверных фильтров ваши ContainerRequestFilterBuildItem и ContainerResponseFilterBuildItem продолжают работать без изменений.


Содержание


Что изменилось при миграции на quarkus-rest

Миграция с quarkus-resteasy на quarkus-rest (он же RESTEasy Reactive) — это шаг к реактивности и меньшему потреблению ресурсов. Раньше в resteasy всё крутилось вокруг классического JAX-RS с блокирующими вызовами, а теперь фокус на Mutiny и non-blocking I/O.

Почему это важно? Ваш старый трюк с ResteasyJaxrsProviderBuildItem регистрировал провайдеры глобально, включая фильтры для клиентов. Но в quarkus-rest архитектура изменилась: клиентские фильтры не подхватываются автоматически так же просто. Официальные гайды по миграции подчёркивают — новые workload’ы должны переходить на reactive, но для клиентов это значит ручную настройку через аннотации вроде @RegisterRestClient.

А серверные фильтры? Они в порядке. Ваши ContainerRequestFilterBuildItem и ContainerResponseFilterBuildItem из quarkus-resteasy-reactive работают на ура, как показано в примерах с JAX-RS фильтрами.


Регистрация клиентских фильтров в quarkus rest client

Quarkus rest client — это мощный инструмент для исходящих HTTP-запросов, особенно с @RegisterRestClient. Фильтры вроде ClientRequestFilter (для запросов) и ClientResponseFilter (для ответов) добавляют логику: авторизацию, метрики, ретраи. Но автоматом для всех клиентов? Прямого BuildItem нет.

Что делать?

  • Ручной способ: Добавьте @RegisterRestClient(configKey = "my.client") и фильтры с @Provider. Работает, но не глобально.
  • Глобальный хак: Создайте singleton RestClientEngine, который подхватывает все @Provider-аннотированные фильтры. Quarkus это поддерживает через CDI.

Из best practices по quarkus rest client ясно: аннотация @RegisterRestClient упрощает жизнь, но для фильтров нужна дополнительная магия в extension. А в issue на GitHub Quarkus намекают на проблемы с Jackson-провайдерами — это подсказка, что кастомные BuildItem’ы для reactive всё ещё сырые.

Коротко: без programmatic регистрации в BuildStep не обойтись. Но давайте разберём, как это слепить.


Автоматическая регистрация через расширение

Хотите, чтоб расширение само регистрировало ClientRequestFilter во всех quarkus rest client? Используйте BuildStep в вашем extension. Сканируйте @Provider-классы и пихайте их в RestClientEngine.

Вот логика:

  1. Соберите IndexView с AnnotationIndex<Provider>.
  2. Создайте BuildItem, аналогичный вашим серверным, но для клиентов — назовём ClientFilterBuildItem.
  3. В RestClientProcessor примените:
java
@BuildStep
ClientFilterBuildItem registerClientFilters(BuildProducer<ClientFilterBuildItem> producer, IndexView index) {
 AnnotationIndex<Provider> providers = Indexer.of(index).get(Provider.class);
 // Добавьте ваши фильтры
 producer.produce(new ClientFilterBuildItem(MyClientRequestFilter.class, MyClientResponseFilter.class));
 return null;
}

Затем в runtime bean’е настройте engine:

java
@ApplicationScoped
public class GlobalRestClientEngine implements RestClientEngine {
 // Scope'те фильтры и возвращайте configured builder
}

Это не 1:1 с ResteasyJaxrsProviderBuildItem, но работает. Примеры extension’ов показывают, как регистрировать кастомные источники — принцип тот же для провайдеров. В версии 3.27 проверьте совместимость с resteasy-reactive-jackson.

А если лень ковырять? @io.quarkus.rest.client.reactive.ClientBasicAuth или Micrometer для метрик — готовые фильтры.


Примеры кода для фильтров

Давайте кодом. Для сервера вы уже мастера, но вот клиентский вариант, вдохновлённый туториалом по фильтрам.

ClientRequestFilter (логирование):

java
@Provider
@ClientRequestFilter
public class LoggingClientRequestFilter implements ClientRequestFilter {
 private static final Logger LOG = Logger.getLogger(LoggingClientRequestFilter.class);

 @Override
 public void filter(ClientRequestContext ctx) {
 LOG.infof("Client request: %s %s", ctx.getMethod(), ctx.getUri());
 }
}

ClientResponseFilter (тайминги):

java
@Provider
@ClientResponseFilter
public class TimingClientResponseFilter implements ClientResponseFilter {
 @Override
 public void filter(ClientRequestContext req, ClientResponseContext res) {
 // Логика времени
 LOG.info("Response in X ms");
 }
}

В extension: в BuildStep соберите их и зарегистрируйте через RestClientEngineProvider. Для реактивных — Mutiny helpers из туториала по reactive API.

Тестируйте с quarkus-maven-plugin:build — никаких ошибок как в том issue.


Источники

  1. Build a RESTful API with Quarkus
  2. Quarkus issue on Jackson processor
  3. Quarkus Reactive vs RESTEasy Classic
  4. 10 Quarkus REST Client Best Practices
  5. HTTP Filters in Quarkus
  6. Quarkus Extension Recipes

Заключение

Автоматическая регистрация ClientRequestFilter в quarkus rest client при миграции требует кастомного BuildItem и RestClientEngine — не так просто, как в quarkus-resteasy, но реально. Начните с IndexView в extension, протестируйте на 3.27, и ваши фильтры заработают глобально. Если застрянете — загляните в Quarkus GitHub или форумы. Это сделает ваш код быстрее и чище под cloud-native нагрузки.

Авторы
Проверено модерацией
Модерация
Авторегистрация ClientRequestFilter в Quarkus REST клиенте