com.dft.api.shopify.ShopifyGraphQLSdk Maven / Gradle / Ivy
package com.dft.api.shopify;
import com.dft.api.shopify.model.auth.AccessCredential;
import com.dft.api.shopify.v202410.model.common.GraphQlQuery;
import com.dft.api.shopify.v202410.model.common.QueryResponse;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.CompletableFuture;
import static com.dft.api.shopify.constantcode.ConstantCodes.ACCESS_TOKEN_HEADER;
import static com.dft.api.shopify.constantcode.ConstantCodes.HTTPS;
import static com.dft.api.shopify.constantcode.ConstantCodes.HTTP_HEADER_CONTENT_TYPE;
import static com.dft.api.shopify.constantcode.ConstantCodes.HTTP_HEADER_VALUE_APPLICATION_JSON;
import static com.dft.api.shopify.constantcode.ConstantCodes.MAX_ATTEMPTS;
import static com.dft.api.shopify.constantcode.ConstantCodes.TIME_OUT_DURATION;
public class ShopifyGraphQLSdk {
private static final String JSON_SUFFIX = ".json";
private static final String ADMIN_API_ENDPOINT = "/admin/api";
private static final String SHOPIFY_DOMAIN_SUFFIX = ".myshopify.com";
private static final String VERSION_2024_10_ENDPOINT = "/2024-10/graphql.json";
protected String baseUrl;
protected HttpClient client;
protected ObjectMapper objectMapper;
protected AccessCredential accessCredential;
public ShopifyGraphQLSdk(AccessCredential accessCredential) {
this.client = HttpClient.newHttpClient();
this.objectMapper = new ObjectMapper();
this.accessCredential = accessCredential;
this.baseUrl = HTTPS + getStoreDomain() + ADMIN_API_ENDPOINT;
}
protected QueryResponse getQueryData(GraphQlQuery graphQlQuery, TypeReference> queryResponse) {
URI uri = URI.create(baseUrl + VERSION_2024_10_ENDPOINT);
HttpRequest request = postWithObject(uri, graphQlQuery);
return getRequestWrapped(request, queryResponse);
}
private String getStoreDomain() {
String domain = this.accessCredential.getStoreDomain();
if (!domain.endsWith(SHOPIFY_DOMAIN_SUFFIX)) {
domain += SHOPIFY_DOMAIN_SUFFIX;
}
return domain;
}
public URI baseUrl(String version, String path) {
return URI.create(baseUrl + version + path + JSON_SUFFIX);
}
@SneakyThrows
protected HttpRequest postWithObject(URI uri, Object object) {
String jsonBody = objectMapper.writeValueAsString(object);
return HttpRequest.newBuilder(uri)
.header(ACCESS_TOKEN_HEADER, this.accessCredential.getAccessToken())
.header(HTTP_HEADER_CONTENT_TYPE, HTTP_HEADER_VALUE_APPLICATION_JSON)
.POST(HttpRequest.BodyPublishers.ofString(jsonBody)).build();
}
@SneakyThrows
protected T getRequestWrapped(HttpRequest request, Class tClass) {
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenComposeAsync(response -> tryResend(client, request, HttpResponse.BodyHandlers.ofString(), response, 1))
.thenApplyAsync(HttpResponse::body)
.thenApplyAsync(responseBody -> convertBody(responseBody, tClass))
.get();
}
@SneakyThrows
protected QueryResponse getRequestWrapped(HttpRequest request, TypeReference> tClass) {
return client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenComposeAsync(response -> tryResend(client, request, HttpResponse.BodyHandlers.ofString(), response, 1))
.thenApplyAsync(HttpResponse::body)
.thenApplyAsync(responseBody -> convertBody(responseBody, tClass))
.get();
}
@SneakyThrows
protected CompletableFuture> tryResend(HttpClient client, HttpRequest request, HttpResponse.BodyHandler handler, HttpResponse resp, Integer count) {
if (resp.statusCode() == 429 && count < MAX_ATTEMPTS) {
Thread.sleep(TIME_OUT_DURATION);
return client.sendAsync(request, handler).thenComposeAsync(response -> tryResend(client, request, handler, response, count + 1));
}
return CompletableFuture.completedFuture(resp);
}
@SneakyThrows
private T convertBody(String body, Class tClass) {
return objectMapper.readValue(body, tClass);
}
@SneakyThrows
private T convertBody(String body, TypeReference typeReference) {
return objectMapper.readValue(body, typeReference);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy