es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cuál es la forma correcta de consolidar los resultados de Flux de diferentes microservicios?

Tengo un servicio de frontera que consolida los resultados de 3 microservicios diferentes.

  1. Devuelve un Flux de clientes
  2. Devuelve un Mono de perfil para el cliente
  3. Devuelve un Flux de roles para el cliente

¿Cuál es la forma correcta de construir un Flux de objetos CustomerProfile que incluirá información sobre el cliente, el perfil y los roles?

“`java
@RequiredArgsConstructor
@RestController
class CrmRestController {
private final CrmClient crmClient;

<pre><code>@GetMapping("/perfiles-cliente")
public Flux<CustomerProfile> getCustomerProfiles() {
return crmClient.getCustomerProfiles();
}
</code></pre>

}

@RequiredArgsConstructor
@Component
class CrmClient {
private final WebClient http;
private final RSocketRequester rsocket;

<pre><code>Flux<Customer> getCustomers() {
return this.http.get().uri("http://localhost:8080/clientes").retrieve().bodyToFlux(Customer.class);
}

Flux<Role> getRolesFor(Integer customerId) {
return this.http.get().uri("http://localhost:8183/roles").retrieve().bodyToFlux(Role.class);
}

Mono<Profile> getProfileFor(Integer customerId) {
return this.rsocket.route("perfiles.{customerId}", customerId).retrieveMono(Profile.class);
}

Flux<CustomerProfile> getCustomerProfiles() {
//TODO: ¿Cuál es la forma correcta de crear los objetos CustomerProfile y completar los valores?
//mi mejor suposición no se compila
return getCustomers()
.flatMap(customer -> getProfileFor(customer.getId())
.map(profile -> getRolesFor(customer.getId())
.collectList().map(roles -> new CustomerProfile(customer, profile, roles))));
}
</code></pre>

}

@Data
@AllArgsConstructor
class Customer {
private Integer id;
private String name;
}

@Data
@AllArgsConstructor
class Profile {
Integer id;
Date registered;
}

@Data
@AllArgsConstructor
class Role {
private Integer id;
private String title;
}

@Data
@AllArgsConstructor
class CustomerProfile {
private Customer customer;
private Profile profile;
private List<Role> roles;
}
“`

Tags:  ,

Answer

  1. Avatar for davy.ai

    La forma correcta de construir un Flux de objetos CustomerProfile que incluirá información sobre el cliente, el perfil y los roles es utilizando algunos operadores reactivos, principalmente flatMap, zip y collectList:

    Flux<customerprofile> getCustomerProfiles() {
        return getCustomers()
                .flatMap(customer -> {
                    Mono<profile> profileMono = getProfileFor(customer.getId());
                    Flux<role> roleFlux = getRolesFor(customer.getId());
                    return Mono.zip(profileMono, roleFlux.collectList())
                            .map(tuple -> new CustomerProfile(customer, tuple.getT1(), tuple.getT2()));
                });
    }
    

    En este código, usamos flatMap para extraer cada ID de cliente y luego llamar a getProfileFor y getRolesFor para ese ID, produciendo un Mono y un Flux respectivamente. Usamos Mono.zip para combinar el Mono y el Flux en un solo Mono<><profile,></profile,><role>>>, donde el Tuple2 contiene el perfil y una lista de roles. Finalmente, usamos map para combinar el Customer, Profile y List<role> en un objeto CustomerProfile.

Comments are closed.