fbpx

Jak z głową zbudować własną libkę

Jak z głową zbudować własną libkę

Tworzenie własnej libki na potrzeby architektury mikroserwisowej to nie jest najlepszy pomysł. Z wielu powodów. Tym razem spójrz jak to zrobić, w sytuacji, kiedy jednak taką libke bardzo chcesz stworzyć.

Weźmy na warsztat taką sytuację:

“Komunikacja REST wymaga dodania nagłówków X, Y i Z.”

Masz wiele mikroserwisów i wszędzie te nagłówki muszą być wysyłane.

No to teraz, na przykładzie WebClienta, przejdźmy od najgorszego do najlepszego rozwiązania 😄

💥 Skonfigurowany WebClient

Twoja libka dostarcza gotowego WebClienta. Wystarczy, że go użyjesz u siebie, aby wykonać zapytanie REST, wszystkie nagłówki są magicznie dołączone.

@Configuration
public class WebClientConfig {

    @Bean
    WebClient webClient() {
        return WebClient.builder()
                .defaultHeader("x-header-x", "some-value-x")
                .defaultHeader("x-header-y", "some-value-y")
                .defaultHeader("x-header-z", "some-value-z")
                .build();
    }
}

Po podniesieniu takie klasy konfiguracyjnej będziesz mieć gotowego do użycia WebClienta. Niby super. Ale…

🧨 Nie masz możliwości dodania kolejnych nagłówków.

🧨 Nie masz możliwości dodania filtrów.

🧨 Nie masz możliwości wpłynięcia na konfigurację serializacji (Jackson).

🧨 Twoja aplikacja musi być w pełni zgodna z założeniami libki, co do tego jak “pobrać” wartości dla nagłówków.

Generalnie nic nie możesz, jak chcesz coś zmienić, musisz zrobić wszystko ręcznie od nowa.

🧨 Skonfigurowany WebClient.Builder

Trochę bardziej elastycznym rozwiązaniem, będzie dostarczenie prekonfigurowanego WebClient.Buildera.

@Configuration
public class WebClientConfig {

    @Bean
    WebClient.Builder webClientBuilder() {
        return WebClient.builder()
                .defaultHeader("x-header-x", "some-value-x")
                .defaultHeader("x-header-y", "some-value-y")
                .defaultHeader("x-header-z", "some-value-z");
    }
}

Wykorzystując go, możesz stworzyć WebClienta, jednocześnie dodając swoje customizacje.

✅ Możesz dodać kolejne nagłówki

✅ Możesz dodać filtry

✅ Możesz dowolnie konfigurować serializacje

🧨 Nadal Twoja aplikacja musi być w pełni zgodna z założeniami libki.

🪄 Automagiczny filtr

Jeżeli masz ochotę na jeszcze większą elastyczność, to warto pójść w stronę własnego filtra. Dzięki temu masz dodatkowo kontrolę na tym, kiedy te nagłówki zostaną nadane.

public class MyCustomHeadersFilter implements ExchangeFilterFunction {

		@Override
    public Mono<ClientResponse> filter(
			ClientRequest request, ExchangeFunction next) {
        var headers = request.headers();
        
        headers.add("x-header-x", "some-value-x");
        headers.add("x-header-y", "some-value-y");
        headers.add("x-header-z", "some-value-z");
        
        return next.exchange(request);
    }
}

Taki filtr ręcznie dodajesz, w wybrane przez siebie miejsce podczas tworzenia WebClienta w swojej apce. Nikt nic Ci automatycznie nie konfiguruje.

✅ Masz pełną kontrolę nad Twoim WebClientem

✅ Ty decydujesz w którym momencie zostaną dodane nagłówki

🧨 Nadal Twoja aplikacja musi być zgodna z założeniami libki. Filtr musi skądś wartości nagłówków pobrać.

🍸 Filtr z Supplierem

Aby uwolnić się od ostatniego problemu, musisz po prostu zparametryzować filtr!

@RequiredArgsConstructor
public class MyCustomHeadersFilter
        implements ExchangeFilterFunction {

    private final Supplier<HeaderValues> valuesSupplier;

    @Override
    public Mono<ClientResponse> filter(
            ClientRequest request, ExchangeFunction next) {
        var headers = request.headers();

        var values = valuesSupplier.get();

        headers.add("x-header-x", values.getX());
        headers.add("x-header-y", values.getY());
        headers.add("x-header-z", values.getZ());

        return next.exchange(request);
    }
}

Teraz, dodając filtr do swojego WebClienta, musisz przekazać mu tez funkcję, za pomocą której zostaną dostarczone odpowiednie wartości z Twojej aplikacji. Masz pełną kontrolę nad tym, co tam przekażesz, a wartość będzie za każdym razem pobierana od nowa, dla każdego requestu.

Możesz tam pobierać informacje z requestu, który przyszedł do Twojej aplikacji, z kontekstu Security, z konfiguracji czy nawet generować je losowo.

✅ Masz pełną kontrolę. Biblioteka nic Ci nie narzuca!

Awatar Łukasz Monkiewicz

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *