GraphQL Client for Unreal Engine

A production-ready, high-performance network client built to integrate GraphQL APIs natively into Unreal Engine. Execute queries and mutations completely non-blocking via C++ or optimized Async Blueprint nodes, manage text-based queries seamlessly, and parse complex relational responses with zero boilerplate.

Features

Native GraphQL Operations

Out-of-the-box support for queries, mutations, complex operation names, and dynamic JSON variables.

Disk-Driven Workflows

Stop pasting massive, unformatted query text blocks into Blueprints or C++. Load and execute .graphql or .txt files directly from your game's content directory.

Type-Safe Value Representation

Native FGraphQLValue wrapper enclosing nested array/object topologies via a unified type engine.

Inline Fallback Coalescing

Define clean fallback defaults inline directly within your graphs for optional or null schema fields, eliminating branching boilerplate.

Installation

  1. Get the GraphQL Client plugin from Fab.
  2. Click Install to Engine from the Epic Games Launcher to add it to your Unreal Engine installation.
  3. Open your project, navigate to Edit > Plugins, search for GraphQL Client, and check Enabled.
  4. Restart the Unreal Editor.

Blueprint Workflows

1. Creating & Initializing the Client

Before you can make any network requests, you must construct and configure your persistent client instance using the static factory node.

The client is UObject-based, and can be stored in the GameInstance for example to persist level changes.

Unreal Engine Blueprint graph showing the Create GraphQL Client node initialized with a target Host URL, connected to a Make Map node feeding custom Authorization Bearer token headers, with the resulting object reference saved to a persistent variable.
  • Create Client: Use the Create GraphQL Client node.
  • Configure Endpoint & Headers: Pass your GraphQL API endpoint URL (e.g., https://api.yourgame.com/graphql) and optional initial headers directly to the constructor node.
  • Dynamic Modifiers: Use Set Host or Set Header dynamically at runtime to modify authorization states or update endpoints.
Blueprint graph demonstrating the Set Header function called on a GraphQL Client object reference variable to dynamically append an Authorization key and a Bearer token string.

2. The Async Execution Node

Place the Execute GraphQL Query async node anywhere in your graphs to fetch data asynchronously.

Blueprint graph displaying the asynchronous Execute GraphQL Query action node with input pins for the GraphQL Client reference, the raw query string block, and a TMap of variables, branching out into Executed and Error output execution paths carrying the FGraphQLResult struct.
  • Client Reference: Connect your initialized GraphQLClient instance to the target pin.
  • Query Input: Input your raw GraphQL query/mutation syntax directly into the multi-line pin.
  • Variables Input: Pass parameters dynamically using a map constructed from native type conversion nodes (->).
  • Execution Routing: Use the explicit Executed (Success) and Error (Failure) pins to safely handle your network responses without nesting branching logic. Both pins carry the FGraphQLResult payload for custom processing.

3. Disk-Based Execution (ExecuteFile)

Avoid embedding massive, unformatted query strings inside your graphs.

Blueprint graph displaying the Execute GraphQL File node, showing the Path input pin configured with a relative content path to a raw GraphQL query file on disk, with standard success and failure flow routing pins.
  • Save your queries as .graphql or .txt assets inside your project content directory (e.g., /Content/Queries/GetInventory.graphql).
  • Use the Execute GraphQL File node and point the path pin directly to that relative content path.
  • This allows designers and backend engineers to modify queries externally in their favorite IDE without changing or recompiling Blueprint graphs.

4. Rapid Data Extraction (WalkResult Node)

Since GraphQL payloads are deeply nested, use the built-in path navigation helpers to pluck fields in one step instead of chaining multiple nested object getters.

Blueprint graph comparing the single-node Walk Result helper resolving a nested path with dot-notation to extract a nested value, contrasted against a messy sequence of manual Get Field and As Object nodes.
  • Provide a simple dot-notation path, such as viewer.inventory.equippedWeapon.id.
  • The node instantly resolves and returns the specific target value.
  • Array Index Access: WalkResult can also access indexed arrays directly. For example, passing users.3.name will resolve and return the name of the fourth element (index 3) in the users array.

5. Array & Nested Object Parsing

While WalkResult is ideal for extracting singular nested fields, complex responses often return JSON objects or lists (arrays) that require manual iteration and destructuring. The Blueprint library provides clean conversion nodes to handle these structures.

Blueprint graph showing the parsing of a nested array of items. An FGraphQLValue object is processed using the AsStringArray and AsObject nodes, feeding into a standard Blueprint For Each Loop to reconstruct custom structs.
  • Array Extraction: Convert list payloads directly using typed helpers to avoid manual element conversion:
    • AsStringArray / AsIntArray / AsInt64Array
    • AsBoolArray / AsFloatArray / AsDoubleArray / AsByteArray
  • Iterating Generic Arrays: For mixed arrays or arrays of nested objects, extract them using AsArray to get a TArray<FGraphQLValue>. You can then loop through them with a standard Blueprint ForEachLoop.
  • Object Key Traversal: Extract values using the GetField node. You can convert the object representation into a key-value map using AsObject for dynamic property scanning.

6. Inline Fallback Assignment (Coalesce Nodes)

GraphQL properties are nullable by default. Assign default fallback values inline without messy branching conditions or select nodes.

Blueprint graph showing the Coalesce String node accepting an optional FGraphQLValue, displaying a default string value fallback pin set to 'anonymous', and outputting a sanitized FString output.
  • Route your extracted value through any helper in the Coalesce suite:
    • CoalesceString
    • CoalesceInt / CoalesceInt64
    • CoalesceFloat / CoalesceDouble
  • If the server returns a null value for an optional field, the node instantly substitutes it with your defined fallback default value inline.

7. JSON Serialization (ToJSON Node)

For logging, saving data locally, or passing raw payloads to other subsystems, you can serialize any FGraphQLValue back into a standard formatted JSON string.

Blueprint graph displaying the To JSON node accepting an FGraphQLValue parameter and outputting a serialized JSON-formatted FString.
  • Serialization: Use the To JSON node to easily dump complex nested GraphQL values or complete data payloads into standard string outputs.

C++ Quick Start

If you are working in a C++ project, first open your project's *.Build.cs file and add the module dependency:

PublicDependencyModuleNames.AddRange(new string[] { "GraphQLClient" });

1. Initializing the Client

Create and configure an instance of the GraphQL client using the static factory method or standard initialization.

#include "GraphQL.h"

// Optional initial headers
TMap<FString, FString> Headers;
Headers.Add(TEXT("Authorization"), TEXT("Bearer your_jwt_token"));

// Create the client instance using the static factory
UGraphQLClient* const Client = UGraphQLClient::CreateClient(
  TEXT("https://api.yourgame.com/graphql"), 
  Headers
);

// Modify endpoints or headers later if needed
Client->SetHeader(TEXT("X-Custom-Header"), TEXT("CustomValue"));

2. Executing a Query with Variables

Pass variables dynamically using FGraphQLValue maps and handle the async delegate callback.

// Construct native variables using FGraphQLValue constructor wrappers
TMap<FString, FGraphQLValue> Variables;
Variables.Add(TEXT("playerId"), FString(TEXT("PLR_89234")));

FString Query = TEXT("query GetPlayer($playerId: ID!) { player(id: $playerId) { name gold } }");

// Bind to delegate callback and execute
Client->Execute(
  Query, 
  Variables, 
  FGraphQLResultDelegate::CreateUObject(this, &AMyGameMode::OnPlayerLoaded)
);

// Callback Implementation
void AMyGameMode::OnPlayerLoaded(const FGraphQLResult& Result)
{
    if (!Result.HasErrors())
    {
        // Extract nested fields safely from the FGraphQLValue "Data" property
        FGraphQLValue Player = Result.Data.GetField(TEXT("player"));
        
        FString Name = Player.GetField(TEXT("name")).AsString();
        int32 Gold = Player.GetField(TEXT("gold")).AsInt();
        
        UE_LOG(LogTemp, Log, TEXT("Player %s loaded with %d gold."), *Name, Gold);
    }
    else
    {
        // Output error messages from the payload
        for (const FGraphQLError& Error : Result.Errors)
        {
            UE_LOG(LogTemp, Error, TEXT("GraphQL Error [%d]: %s"), Error.Code, *Error.Message);
        }
    }
}

Support

For support or feature requests, please contact us directly at pandores.marketplace@gmail.com.