I'm trying to build a simple app that calls an API with quarkus-rest-client
.
I have to inject an API Key as a header which is the same for all resources of the API.
So I would like to put the value of this API Key (that depends on the environment dev/qa/prod
) in the application.properties
file located in src/main/resources
.
I tried different ways to achieve this:
com.acme.Configuration.getKey
into @ClientHeaderParam
value propertyFinally, I found the way described below to make it work.
My question is: Is there a better way to do it?
Here's my code:
@Path("/stores")
@RegisterRestClient
@ClientHeaderParam(name = "ApiKey", value = "{com.acme.Configuration.getStoresApiKey}")
public interface StoresService {
@GET
@Produces("application/json")
Stores getStores();
}
@ApplicationScoped
public class Configuration {
@ConfigProperty(name = "apiKey.stores")
private String storesApiKey;
public String getKey() {
return storesApiKey;
}
public static String getStoresApiKey() {
return CDI.current().select(Configuration.class).get().getKey();
}
}
@Path("/stores")
public class StoresController {
@Inject
@RestClient
StoresService storesService;
@GET
@Produces(MediaType.APPLICATION_JSON)
public Stores getStores() {
return storesService.getStores();
}
}
Quarkus allows developers to automatically generate Kubernetes resources including building and deploying container images without having to manually create YAML files.
Quarkus provides faster hot reloads than Spring Boot since it can automatically detect changes made to Java and other resource/configuration files, and transparently re-compile and deploy the changes. This feature can also be used with Quarkus applications running in a remote environment.
But over the course of 2021, Quarkus, the Kubernetes-native pure Java stack, began to gain momentum as an alternative path to the cloud for Java applications. Now, in 2022, that growth is spurring Quarkus to become one of the most popular topics for Java developers. It's also allowing companies to adopt a new stack.
Four reasons to try Quarkus Java™ is still the programming language of choice for many developers, but the evolution of cloud-native technologies like Kubernetes and serverless presents a challenge. See why Quarkus is the Java framework developers need to work with Knative and serverless.
Late to the party, but putting this here for my own reference. There seems to be a difference in using @ClientHeaderParam and @HeaderParam, so I investigated a little further: According to the Microprofile docs, you can put a compute method for the value in curly braces. This method can extract the property value.
See link for more examples.
EDIT: What I came up with resembles the original, but uses a default method on the interface, so you can at least discard the Configuration class. Also, using the org.eclipse.microprofile.config.Config and ConfigProvider classes to get the config value:
@RegisterRestClient
@ClientHeaderParam(name = "Authorization", value = "{getAuthorizationHeader}")
public interface StoresService {
default String getAuthorizationHeader(){
final Config config = ConfigProvider.getConfig();
return config.getValue("apiKey.stores", String.class);
}
@GET
@Produces("application/json")
Stores getStores();
I will get rid of the Configuration
class and use an @HeaderParam
to pass your configuration property from your rest endpoint to your rest client. The annotation will then send this property as an HTTP header to the remote service.
Somthing like this should works:
@Path("/stores")
@RegisterRestClient
public interface StoresService {
@GET
@Produces("application/json")
Stores getStores(@HeaderParam("ApiKey") storesApiKey);
}
@Path("/stores")
public class StoresController {
@ConfigProperty(name = "apiKey.stores")
private String storesApiKey;
@Inject
@RestClient
StoresService storesService;
@GET
@Produces(MediaType.APPLICATION_JSON)
public Stores getStores() {
return storesService.getStores(storesApiKey);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With