How to pass request headers when using java netflix graphql client?

How to pass request headers when using java netflix graphql client?


0

I am using com.netflix.graphql.dgs:graphql-dgs-client:4.9.16 along with HttpClient (JDK 17)

I am creating graphql client using below.

GraphQLCLient graphQLClient = GraphQLClient.createCustom(
        host-url,
        requestExecutor::exec);

And my request executor is based on HttpClient and it’s implementation is roughly as below –

import com.netflix.graphql.dgs.client.HttpResponse;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpClient.Version;
import java.net.http.HttpRequest;
import java.net.http.HttpRequest.BodyPublishers;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Stream;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.SneakyThrows;

public class RequestExecutor {

  private final Supplier<String> bearer;
  private final HttpClient httpClient;

  public RequestExecutor(HttpClient httpClient) {
    this(httpClient, null);
  }

  public RequestExecutor(HttpClient httpClient, Supplier<String> bearer) {
    this.httpClient = httpClient;
    this.bearer = bearer;
  }

  @SneakyThrows
  public HttpResponse exec(
      String url,
      Map<String, ? extends List<String>> headers,
      String body
  ) {
    var requestBuilder = HttpRequest
        .newBuilder(URI.create(url))
        .headers(Util.flattenHeaders(headers))
        .POST(BodyPublishers.ofString(body))
        .version(Version.HTTP_1_1);

    if (bearer != null) {
      requestBuilder.header("Authorization", String.format("Bearer %s", bearer.get()));
    }

    var response = httpClient.send(
        requestBuilder.build(),
        java.net.http.HttpResponse.BodyHandlers.ofString()
    );

    return processResponse(body, response);
  }

  protected HttpResponse processResponse(String request, java.net.http.HttpResponse<String> response) {
    return new HttpResponse(
        response.statusCode(),
        response.body(),
        response.headers().map()
    );
  }

  @NoArgsConstructor(access = AccessLevel.PRIVATE)
  private static class Util {

    public static String[] flattenHeaders(Map<String, ? extends List<String>> headers) {
      return headers.entrySet().stream()
          .flatMap(x -> x.getValue()
              .stream()
              .flatMap(y -> Stream.of(x.getKey(), y))
          )
          .toArray(String[]::new);
    }
  }
}


the requestExecutor.exec(String url, Map<String, ? extends List<String>> headers, String body) method can accept the headers but I am not seeing a graphql client method that can pass or accept httpheader.

What I am currently using is –

var request = new GraphQLQueryRequest(
        OurStoreGraphQLQuery.newRequest().oneStoreId(oneStoreId).build(),
        RESPONSE_PROJECTION; 

GraphQLResponse response = graphQLClient.executeQuery(request.serialize());

Neither of the above i.e. GraphQLQueryRequest constructor or executeQuery method has a overloaded equivalent that accept HttpHeader and in-turn pass it to requestExecutor::exec method.

  1. What is the point of exec method accepting headers if it can not be passed by the user code with out creating a new instance of RequestExecutor.

  2. Now how can i pass header to the graphql request?


Probably I can use the below style as mentioned in java-client/#plug-in-your-own-http-client docs –

CustomGraphQLClient client = GraphQLClient.createCustom(url,  (url, headers, body) -> {
    HttpHeaders httpHeaders = new HttpHeaders();
    headers.forEach(httpHeaders::addAll);
    ResponseEntity<String> exchange = restTemplate.exchange(url, HttpMethod.POST, new HttpEntity<>(body, httpHeaders),String.class);
    return new HttpResponse(exchange.getStatusCodeValue(), exchange.getBody());
});

GraphQLResponse graphQLResponse = client.executeQuery(query, emptyMap(), "SubmitReview");
String submittedBy = graphQLResponse.extractValueAsObject("submitReview.submittedBy", String.class);

— but looks like i will have to create a custom client each time my header changes. Is that right??


Load 5 more related questions


Show fewer related questions

0



Leave a Reply

Your email address will not be published. Required fields are marked *