Rozumiem, że skoro Confluent sobie wymyślił Schema Registry dla Avro to stara się rozpropagować używanie Avro jako jedyną właściwą drogę tylko nie dostrzegam w tym jakiś specjalnych korzyści. Jaką przewagę będzie miało avro ze Schema Registry nad takim rozwiązaniem:
producer:
Niech klasa Message
posiada Body
i Headers
. Niech każdy możliwy Message
jakie serwis może wysłać do brokera niech serwis udostępnia jako osobny, publiczny moduł. Niech każdy Headers
posiada header eventId
i version
obowiązkowo. Niech body będzie serializowane z String json.
konsumer
deserializuje body do String json. Nie mapuje ich na obiekt. Handlery sobie sprawdzają kombinację eventId
i version
i jeśli akceptują to obsługują sobie Message. Dopiero te handlery mapują String jsona na odpowiedni obiekt.
@KafkaListener
void listen(@Payload String body, @Headers Map<String, String> headers) {
handlers.stream()
.filter(handler -> handler.test(headers))
.forEach(handler -> handler.accept(body, headers));
}
Przewagi takiego rozwiązania nad avro Schema Registry jest taka, że definicję możliwych body trzymasz zapisane w javie a nie w tym dziwnym schemacie avro. Nie potrzebujesz dodatkowych serwisów Schema Registry. Nie walidujesz ich, bo nie musisz, sprawdzasz sobie jedynie headery. Nie musisz trzymać Backward Compatibility ani Forward. Masz wzorzec Chain of Responsibility za darmo dzięki czemu możesz mieć wiele handlerów do tego samego Message'a.
Co do wydajności to minisem jest to, że wiele handlerów może konsumować obiekt i każdy z nich będzie osobno mapował jsona na obiekt, do tego iterowanie po handlerach no i deserializowanie body odbywa się zawsze. (no ale zazwyczaj schemat Messagy jest przecież poprawny). Z drugiej strony Confluentowe sprawdzanie poprawności body ze schematem kosztuje (mimo że to byte[]) i robi to chyba przy każdej wiadomości, a jak już wspomniane zazwyczaj schemat Messagy jest przecież poprawny. Handlerów raczej jest mało. Body może być wielkie.