How to Convert GraphQL Query to JSON in Java

When building Java applications that interact with GraphQL APIs, you'll often need to convert GraphQL query strings into JSON objects. This might be for caching, logging, transforming requests, or integrating with tools that expect JSON input.

Why Convert GraphQL to JSON?

GraphQL queries use a custom syntax that isn't natively understood by all systems. Converting to JSON enables:

  • Caching — Use the JSON representation as a cache key.
  • Serialization — Store or transmit queries in a universal format.
  • Transformation — Modify query structures programmatically.
  • Interoperability — Feed queries into tools that expect JSON.

Using graphql-java to Parse Queries

The graphql-java library provides a built-in parser that converts GraphQL query strings into a Document AST (Abstract Syntax Tree). From there, you can walk the AST and build a JSON representation.

Java GraphqlToJsonConverter.java
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import graphql.language.*;
import graphql.parser.Parser;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

public class GraphqlToJsonConverter {

    private static final ObjectMapper mapper = new ObjectMapper();

    public static JsonNode convert(String graphqlQuery) {
        Document document = Parser.parse(graphqlQuery);
        ObjectNode root = mapper.createObjectNode();
        List<Definition> definitions = document.getDefinitions();

        for (Definition def : definitions) {
            if (def instanceof OperationDefinition op) {
                root.set(op.getName(), convertOperation(op));
            }
        }
        return root;
    }

    private static JsonNode convertOperation(OperationDefinition op) {
        ObjectNode node = mapper.createObjectNode();
        node.put("operationType", op.getOperation().toString().toLowerCase());
        node.put("name", op.getName());
        ArrayNode fields = mapper.createArrayNode();
        for (Selection selection : op.getSelectionSet().getSelections()) {
            fields.add(convertSelection(selection));
        }
        node.set("fields", fields);
        return node;
    }

    private static JsonNode convertSelection(Selection selection) {
        if (selection instanceof Field field) {
            return convertField(field);
        }
        return mapper.createObjectNode();
    }

    private static JsonNode convertField(Field field) {
        ObjectNode node = mapper.createObjectNode();
        node.put("name", field.getName());
        node.put("alias", field.getAlias());
        if (field.getSelectionSet() != null) {
            ArrayNode subFields = mapper.createArrayNode();
            for (Selection sel : field.getSelectionSet().getSelections()) {
                subFields.add(convertSelection(sel));
            }
            node.set("fields", subFields);
        }
        if (!field.getArguments().isEmpty()) {
            ObjectNode args = mapper.createObjectNode();
            for (Argument arg : field.getArguments()) {
                args.put(arg.getName(), arg.getValue().toString());
            }
            node.set("arguments", args);
        }
        return node;
    }
}

Example Output

For the query { user(id: 1) { name email } }, the converter produces:

JSON
{
  "query": {
    "operationType": "query",
    "name": null,
    "fields": [
      {
        "name": "user",
        "alias": null,
        "arguments": { "id": "1" },
        "fields": [
          { "name": "name", "alias": null },
          { "name": "email", "alias": null }
        ]
      }
    ]
  }
}

Key Takeaways

  • graphql-java's Parser.parse() turns any valid GraphQL query into a Document AST.
  • Walk the AST using visitor or recursive methods to extract fields, arguments, and nested selections.
  • Use Jackson (or any JSON library) to build the output structure.
  • This approach works equally well for queries, mutations, and subscriptions.