Getting and using REST client instances
restfn templating functions
The restfn templating functions allow you to obtain and use REST clients. This works only for clients that have been configured and declared with the RESTEasy client.
[#assign jokesService = restfn.getService("icndbClient", "info.magnolia.documentation.modules.restclientexamples.client.IcndbService")] (1)
[#assign response = jokesService.joke("random", "Tiger", "Lilly") /] (2)
<i>${response.get("value").get("joke").getTextValue()!"Nix found"}</i>
Line 1 accesses an instance of the client interface. In this example, it is of the IcndbService type.
|
Line 2 calls the method #joke, which returns a JsonNode object.
|
This is a simplified example. See Jackson Javadoc for how to process
|
During installation of the magnolia-resteasy-client module, RestEasyClientModuleVersionHandler adds restfn to renderer configurations. Make sure that the renderType of your template definition points to a renderer that is configured to use restfn. See Configure the functions in a renderer for how to add templating functions to a renderer.
|
Using the REST client factory
The recommended way to obtain a REST client instance in Java code is to use the RestClientFactory.
This replaces the older (now deprecated) approach of calling RestClientRegistry#getRestClient(clientName).
To construct a typed client, inject both of the following:
-
RestClientRegistry– to obtain theDefinitionProviderfor a configured REST client. -
RestClientFactory– to instantiate a typed client from that definition.
Example
import info.magnolia.rest.client.factory.RestClientFactory;
import info.magnolia.rest.client.registry.RestClientRegistry;
import info.magnolia.rest.client.RestClient;
import info.magnolia.rest.client.RestClientDefinition;
import info.magnolia.config.registry.DefinitionProvider;
import javax.inject.Inject;
public class MyModel {
private final RestClientRegistry clientRegistry;
private final RestClientFactory clientFactory;
@Inject
public MyModel(RestClientRegistry clientRegistry, RestClientFactory clientFactory) {
this.clientRegistry = clientRegistry;
this.clientFactory = clientFactory;
}
public String getJoke() {
final DefinitionProvider<RestClientDefinition> provider = (1)
clientRegistry.getProvider("icndbClient");
final RestClientDefinition definition = provider.get(); (2)
final RestClient client = clientFactory.createClient(definition); (3)
final IcndbService service = client.proxy(IcndbService.class); (4)
final JsonNode response = service.joke("random", "Tiger", "Lilly");
return response.get("value").get("joke").asText();
}
}
| 1 | Retrieve the definition provider for the configured client. |
| 2 | Extract the definition. |
| 3 | Create a client. |
| 4 | Get typed proxy interface. |
Using REST Client in UI components
When working inside UI components (for example, presenters or forms), use the RestClient with a JAX-RS proxy interface for type-safe invocation of external REST APIs.
This approach provides compile-time checking, IDE auto-completion, and clean method-based calls.
RestClient is created via RestClientFactory from the magnolia-rest-client module.
Use it in modules that depend on the REST client library.
|
Example
import info.magnolia.rest.client.RestClient;
import info.magnolia.rest.client.RestClientDefinition;
import info.magnolia.rest.client.factory.RestClientFactory;
import info.magnolia.rest.client.registry.RestClientRegistry;
import com.vaadin.ui.Notification;
import com.fasterxml.jackson.databind.JsonNode;
import javax.inject.Inject;
public class MyPresenter {
private final RestClientFactory restClientFactory;
private final RestClientRegistry restClientRegistry;
private final MyView view;
@Inject
public MyPresenter(RestClientFactory restClientFactory,
RestClientRegistry restClientRegistry,
MyView view) {
this.restClientFactory = restClientFactory;
this.restClientRegistry = restClientRegistry;
this.view = view;
}
private void fetchAndDisplayJoke() {
RestClientDefinition definition = restClientRegistry
.getProvider("icndbClient") (1)
.get();
try (RestClient client = restClientFactory.createClient(definition)) { (2)
IcndbService service = client.proxy(IcndbService.class); (3)
JsonNode response = service.joke("random", "Tiger", "Lilly"); (4)
String joke = response.get("value").get("joke").asText();
view.setJoke(joke);
} catch (Exception e) {
Notification.show("Error: " + e.getMessage(), Notification.Type.ERROR_MESSAGE);
}
}
}
| 1 | Use getProvider() to retrieve the REST client definition by name. |
| 2 | Create a RestClient instance.
Use try-with-resources for proper cleanup. |
| 3 | Get a type-safe proxy from the JAX-RS interface. |
| 4 | Call methods directly on the proxy with compile-time parameter checking. |
Component example
You have the option to configure components (filters) to be executed on every request. One use case could be authentication.
Client request filter
Here is an example filter that would handle authorization for each request.
package org.example.filters;
import info.magnolia.context.Context;
import info.magnolia.context.MgnlContext;
import java.io.IOException;
import jakarta.ws.rs.client.ClientRequestContext;
import jakarta.ws.rs.client.ClientRequestFilter;
import jakarta.ws.rs.ext.Provider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Interceptor for RESTEasy to handle authentication with an access token.
*/
@Provider
public class AuthenticationInterceptor implements ClientRequestFilter {
private static final Logger log = LoggerFactory.getLogger(AuthenticationInterceptor.class);
@Override
public void filter(ClientRequestContext requestContext) throws IOException {
if (MgnlContext.hasInstance() && MgnlContext.hasAttribute("ACCESS_TOKEN", Context.APPLICATION_SCOPE)) {
requestContext.getHeaders().putSingle("Authorization",
"OAuth " + MgnlContext.getAttribute("ACCESS_TOKEN", Context.APPLICATION_SCOPE));
log.trace("Authorization : {}",
(String) MgnlContext.getAttribute("ACCESS_TOKEN", Context.APPLICATION_SCOPE));
}
}
}