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 RestTemplate
verwende oder das benutze block()
, Mono
was 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 WebClient
reaktiven Programmierung.
Lösung des Problems
WebClient
ist 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 createUser
reaktiv 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 createUser
er reaktiv ist
public static Mono<UserEntity> createUser(UserDto dto) {
...
}
Falls userRepository
es 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