All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.dft.api.shopify.ShopifyGraphQLSdk Maven / Gradle / Ivy

There is a newer version: 1.0.7
Show newest version
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