4

I am developing application, which uses microprofile rest client. And that rest client should send REST request with various http header. Some headers names changes dynamically. My microprofile rest client should be generic, but I did not find how to implement such behaviour. According to the documentation you need to specify all header names in the implementation via annotations and that is not generic. Is there any way how to "hack" it and add HTTP headers programatically?

Thanks in advance

 GenericRestClient genericRestClient = null;
 Map<String, Object> appConfig = context.appConfigs();
 String baseUrl = (String) appConfig.get("restClient.baseUrl");
 path = (String) appConfig.get("restClient.path");
 try {
     genericRestClient = RestClientBuilder.newBuilder()
                .baseUri(new URI(baseUrl)).build(GenericRestClient.class);
 }catch(URISyntaxException e){
      logger.error("",e);
      throw e;
 }

Response response = genericRestClient.sendMessage(path, value);
logger.info("Status: "+response.getStatus());
logger.info("Response body: "+response.getEntity().toString());

Generic rest client code:

@RegisterRestClient
public interface GenericRestClient {
    @POST
    @Path("{path}")
    @Produces("application/json")
    @Consumes("application/json")
    public Response sendMessage(<here should go any map of custom headers>, @PathParam("path") String pathParam, String jsonBody);
}
Per Henrik Lausten
  • 21,331
  • 3
  • 29
  • 76
madafaka
  • 133
  • 2
  • 7
  • Post code what you have written so that others can help you. – Sambit Jun 08 '19 at 18:01
  • Of course it is possible but SO is not a writing service so it would be best if you tried it yourself, evaluated it, and then came here with specific problems that others can help with. – pastaleg Jun 08 '19 at 18:03
  • I would rather suggest to use Apache HttpClient for Rest client operations. – Sambit Jun 09 '19 at 08:21

2 Answers2

2

According to the spec, you can use a ClientHeadersFactory. Something like this:

public class CustomClientHeadersFactory implements ClientHeadersFactory {
    @Override public MultivaluedMap<String, String> update(
        MultivaluedMap<String, String> incomingHeaders,
        MultivaluedMap<String, String> clientOutgoingHeaders
    ) {
        MultivaluedMap<String, String> returnVal = new MultivaluedHashMap<>();
        returnVal.putAll(clientOutgoingHeaders);
        returnVal.putSingle("MyHeader", "generated");
        return returnVal;
    }
}

@RegisterRestClient
@RegisterClientHeaders(CustomClientHeadersFactory.class)
public interface GenericRestClient {
    ...
}

You can't pass values directly to the ClientHeadersFactory; but you can directly access the headers of an incoming request, if your own service is called via JAX-RS. You can also @Inject anything you need. If this is still not sufficient and you really need to pass things from the service call, you can use a custom @RequestScope bean, e.g.:

@RequestScope
class CustomHeader {
    private String name;
    private String value;

    // getters/setters
}

public class CustomClientHeadersFactory implements ClientHeadersFactory {
    @Inject CustomHeader customHeader;

    @Override public MultivaluedMap<String, String> update(
        MultivaluedMap<String, String> incomingHeaders,
        MultivaluedMap<String, String> clientOutgoingHeaders
    ) {
        MultivaluedMap<String, String> returnVal = new MultivaluedHashMap<>();
        returnVal.putAll(clientOutgoingHeaders);
        returnVal.putSingle(customHeader.getName(), customHeader.getValue());
        return returnVal;
    }
}

class Client {
    @Inject CustomHeader customHeader;

    void call() {
        customHeader.setName("MyHeader");
        customHeader.setValue("generated");

        ...

        Response response = genericRestClient.sendMessage(path, value);
    }
}
rü-
  • 2,129
  • 17
  • 37
0

Add ClientRequestHeader to your client as follows:

@POST
// read from application.properties
@ClientRequestHeader(name=“myHeader1”, value="${myProperty}")
// read from a method
@ClientRequestHeader(name=“myHeader2”, value="{addHeaderMethod}")
Response sendMessage();

default String addHeaderMethod() {
   //put your logic here
   return “my dynamic value”;
}
Serkan
  • 639
  • 5
  • 14