Das Problem ist also folgendes:
Mein Code zum Erstellen von Benutzern sieht so aus:
@Transactional
public void createUser(UserDto userDto) {
UserEntity newUser = userFactory.createUser(userDto);
String userId = userDto.getUserId();
externalApiService
.validateUser(userId)
.subscribe(a-> userRepository.save(newUser));
}
und Validierung des Benutzers ist wie folgt:
public Mono<Void> validateUser(String userId) {
return webClient
.get(...)
.retrieve()
.toEntity(Void.class);
//Exact request is bit more complicated, but those details shouldn't be crucial in this example
}
Mein Endpunkt, der dies verwendet, sieht so aus:
@PostMapping
public ResponseEntity<Void> createUser(@Valid @RequestBody UserDto dto) {
userService.createUser(dto);
return new ResponseEntity<>(HttpStatus.CREATED);
}
Das ist ganz einfach, wenn ich das Blockieren RestTemplateverwende oder das benutze block(), Monowas ich gerade von bekommen habe WebClient. Wenn es eine Ausnahme vom REST-Aufruf an den externen Dienst gibt, erledigt mein globaler Ausnahmehandler die Aufgabe und antwortet dem Benutzer mit dem richtigen Antwortcode.
Aber was ist, wenn ich die volle Kraft der reaktiven Programmierung nutzen möchte und nicht will block(). Ich kann nicht herausfinden, wie man das richtig macht. Kann mir jemand einen Rat geben?
Und bitte entschuldigen Sie, wenn meine Frage trivial ist, ich bin ziemlich neu in der WebClientreaktiven Programmierung.
Lösung des Problems
WebClientist ein reaktiver Client und die einzige Möglichkeit, ihn mit nicht reaktivem Spring MVC zu verwenden, ist block.
Um den Fluss vollständig blockierungsfrei zu machen, sollten alle Komponenten/Funktionen reaktiv sein. Sie müssten zu Spring WebFlux wechseln und auch createUserreaktiv machen.
@PostMapping
public Mono<ResponseEntity<Void>> createUser(@RequestBody UserDto dto) {
return userService.createUser(dto)
.map(user -> ResponseEntity.status(HttpStatus.CREATED).build());
}
Dieser Code geht davon aus, dass createUserer reaktiv ist
public static Mono<UserEntity> createUser(UserDto dto) {
...
}
Falls userRepositoryes nicht reaktiv ist, können Sie nicht reaktiven Code umschließen und auf einem separaten Planer ausführen. Wie umschließe ich einen synchronen, blockierenden Anruf?.
Keine Kommentare:
Kommentar veröffentlichen