Component and Service Calls
Typically, a Kalix service comprises many components. Such components might dependent on one another, on other Kalix services or even external services. This section describes how to call other components and services from within a Kalix service.
Kalix components
Since Kalix is an auto-scaling solution, components can be distributed across many nodes within the same service. Kalix doesn’t hide this fact and makes it explicit. That’s why calling Kalix components is done via HTTP/gRPC DeferredCall
calls. A DeferredCall
is just an instruction on how to call a given component, which can be optimized by the Kalix engine (see forwarding). Sometimes it’s necessary to transform the DeferredCall
into the CompletionStage
to combine many different component calls and build a single asynchronous reply.
Component Client
The Kalix ComponentClient
is a utility for creating deferred calls in a type-safe way. You don’t have to remember what the endpoint path is or which HTTP method should be selected for the call. To use the ComponentClient
you need to inject it into your component (an Action in this example):
private ComponentClient componentClient; (1)
public LimitedFibonacciAction(ComponentClient componentClient) { (2)
this.componentClient = componentClient; (3)
}
1 | Declare a field for the ComponentClient . |
2 | Have a constructor that accepts the ComponentClient as an argument. |
3 | Assign the ComponentClient to the field. |
With the componentClient
available on your component, you can use it to create a DeferredCall
. Constructing the call is a matter of:
-
selecting the component type,
-
choosing the endpoint, with a Java method reference,
-
passing in parameters, if expected.
DeferredCall<Any, Number> deferredCall = componentClient.forAction() (1)
.call(FibonacciAction::getNumber) (2)
.params(number); (3)
return effects().forward(deferredCall);
1 | Select Action component. |
2 | Select endpoint method reference. |
3 | Pass in endpoint method arguments. |
Calling endpoints that return a stream response like Flux is not supported currently by the ComponentClient .
|
Kalix services
Calling other Kalix services in the same project from an Action is done by invoking them using a Spring WebFlux WebClient
. The service is identified by the name it has been deployed. Kalix takes care of routing requests to the service and keeping the data safe by encrypting the connection for you.
In this sample we will make an action that does a call to the Value Entity Counter service, deployed with the service name counter
.
The Kalix Java SDK provides a utility class WebClientProvider
that can provide previously configured `WebClient`s to reach other Kalix services deployed on the same Kalix project.
In our delegating service implementation:
public class DelegatingServiceAction extends Action {
final private WebClient webClient;
public DelegatingServiceAction(WebClientProvider webClientProvider) { (1)
this.webClient = webClientProvider.webClientFor("counter"); (2)
}
@PostMapping("/delegate/counter/{counter_id}/increase")
public Effect<Number> addAndReturn(@PathVariable String counterId, @RequestBody Number increaseBy) {
var result =
webClient
.post().uri("/counter/" + counterId + "/increase") (3)
.bodyValue(increaseBy)
.retrieve()
.bodyToMono(Number.class).toFuture();
return effects().asyncReply(result); (4)
}
}
1 | Let the WebClientProvider be injected into the Action with constructor injection. |
2 | Use the WebClientProvider to build a WebClient for the counter service. |
3 | Use the WebClient to make a REST call to the counter service. |
4 | Use the remote call result to create a reply. |
External services
Calling Kalix services deployed on different projects or any other external service, is done by configuring specific WebClients
.
See the Spring WebFlux WebClient
documentation for details on configuring the WebClients
.