Dmytro Chasovskyi
Dmytro Chasovskyi

Reputation: 3651

How to compose requests for communication between Java back-end and 3rd party GraphQL API?

I am trying to integrate (create flawless data-communication) my Java-based back-end and 3rd party GraphQL API.

I have found similar question that partially answers mine. How to access the GitHub GraphQL API?

All requests I searched on the search engine or snippets I found on Github are related to how to create GraphQL API on the server side, so my Back-end will have GraphQL wrapper/endpoint. That is not the case for me.

The question is the following, if there are any wrappers, annotations that I can use that simplify creature of querys and mutations from the POJOs. The reason why I want it, instead of creation hard-coded strings my objects can be dynamic and include, exclude fields. I need any examples for both mutations and queries. Naturally, I don't want to create a lot of custom resolvers.

Upvotes: 0

Views: 254

Answers (1)

Dmytro Chasovskyi
Dmytro Chasovskyi

Reputation: 3651

Since I have not found any answer or library with significant enough documentation during the time of writing code. I created my own wrapper for wrapping POJO into mutation and query.

This implementation may not work for all GraphQL APIs. Therefore, the important note is that this implementation was created specifically for Xledger integration.

Main wrapper

public String simpleResolver(String operationName, String requestName, Map<String, Object> requestedParams, List<String> requestedFields, String objectNestingStructure) {
        String params = nvl(requestedParams).entrySet().stream().map(p -> p.getKey() + ":" + wrapWithQuotes(p.getValue())).collect(joining(","));

        String[] obejctNesting = nvl(objectNestingStructure).split("\\.");
        String fields = nvl(requestedFields).stream().collect(joining("\n"));
        return "{ \"query\":\"" + operationName + "{\n"  + requestName + "(" + params + ") {\n" + buildObjectNestingStructure(obejctNesting, fields) + "}\n}\n\"," +
               "\"variables\":" + null + "," +
               "\"operationName\":" + null + "}";
    }

Parser and wrapper for nested GraphQL-like structure

public String buildObjectNestingStructure(String[] objectNestingStructure, String fields) {
    StringBuilder objectHead = new StringBuilder();
    StringBuilder objectTail = new StringBuilder();

    for (String objectNesting : objectNestingStructure) {
        objectHead.append(objectNesting);
        objectHead.append(" {\n");

        objectTail.append("\n}");
    }
    objectHead.append(fields);
    objectHead.append(objectTail);

    return objectHead.toString();
}

POJO wrapper to requestParams

public <T> Map<String, Object> getParams(T entity) {
    Map<String, Object> params = new HashMap<String, Object>();

    Class<?> cls = entity.getClass();
    for (Field field : cls.getDeclaredFields()) {
        try {
            String fieldName = field.getName();
            Object fieldValue = field.get(entity);
            if (fieldValue != null) {
                params.put(fieldName, fieldValue);
            }
        } catch(IllegalArgumentException | IllegalAccessException e) {
            logger.error(e.getMessage());
        }
    }
    return params;
}

This solution works for both query and mutation, since both of them have param and in my case, I always took, at least, dbId field.

Also nvl is utility function for substituting null objects with default value.

Upvotes: 0

Related Questions