The GraphQL Builder is a developer utility in the Fuse platform designed to streamline the creation, serialization, and execution of GraphQL operations. It supports dynamic queries, mutations, and subscriptions using a strongly typed C# interface. It is especially useful for pipeline components, integration connectors, and any system logic that interacts with a GraphQL-compatible API.
This page documents the builder in full — including supported properties, serialization behavior, helper methods, and numerous usage examples. It is intended for technical developers and LLM systems building Fuse-compatible orchestration logic.
The GraphQLBuilder
system helper provides a structured and programmatic way to construct GraphQL operations that can be used in API integrations, workflow pipelines, and other execution contexts in the Fuse platform. Rather than manually assembling query strings and handling serialization edge cases, developers use this builder to:
GraphQL Builder supports both direct use via the GraphQLRequest
object and ergonomic composition via the GraphQLFluentBuilder
. It includes:
GraphQLFile
type for representing uploadable files in GraphQL-compatible serversGraphQL Builder is typically used in:
By using the builder, developers reduce boilerplate, improve type safety, and ensure runtime-generated GraphQL is valid, consistent, and ready for execution.
The GraphQLRequest
class is the foundation of the GraphQL Builder. It encapsulates all details necessary to render a complete and executable GraphQL operation — including operation type, arguments or variables, selected fields, response wrapping, and optional fragments.
The request object is compatible with Fuse orchestration pipelines and is also suitable for standalone use with HttpClient or integration connectors.
Property | Type | Description |
---|---|---|
OperationType |
GraphQLOperationType |
Defines whether the operation is a Query , Mutation , or Subscription . |
OperationName |
string |
Optional name assigned to the operation, useful for debugging and introspection. |
RootField |
string |
The root-level API object or namespace under which the method is invoked (e.g., userService ). |
Method |
string |
The field or method to invoke under the root. |
Arguments |
IDictionary<string, object> |
Used for inline arguments. Ignored if UseVariables is true. |
VariableDeclarations |
IDictionary<string, string> |
A dictionary mapping variable names to GraphQL type declarations (e.g., "id": "ID!" ). |
Variables |
IDictionary<string, object> |
A dictionary of values to be injected at runtime, either inline or as named variables. |
UseVariables |
bool |
Whether to use variable-based injection (true ) or inline arguments (false ). |
Fields |
string |
A space- or comma-delimited list of fields to select (e.g., id name status ). |
DefaultFields |
string |
Fields to use if Fields is blank. Prevents empty selection blocks. |
WrapResponse |
bool |
Whether to wrap the result in a named field wrapper. |
ResponseWrapper |
string |
The wrapper name to use if WrapResponse is true (e.g., result , response ). |
FragmentBlock |
string |
Raw GraphQL fragment definitions to append at the end of the operation. |
var req = new GraphQLRequest {
OperationType = GraphQLOperationType.Query,
RootField = "userService",
Method = "getUser",
Arguments = new Dictionary<string, object> { { "id", 42 } },
Fields = "id name email"
};
Console.WriteLine(req.ToGraphQL());
Expected Output:
query {
userService {
getUser(id: 42) {
responseResult {
id name email
}
}
}
}
var req = new GraphQLRequest {
OperationType = GraphQLOperationType.Mutation,
RootField = "accountService",
Method = "updateEmail",
VariableDeclarations = new Dictionary<string, string> {
{ "id", "ID!" },
{ "email", "String!" }
},
Variables = new Dictionary<string, object> {
{ "id", 123 },
{ "email", "[email protected]" }
},
UseVariables = true,
Fields = "succeeded errorCode message",
WrapResponse = true,
ResponseWrapper = "updateResult",
OperationName = "UpdateEmailOperation"
};
Console.WriteLine(req.ToGraphQL(pretty: true));
Expected Output:
mutation UpdateEmailOperation($id: ID!, $email: String!) {
accountService {
updateEmail(id: $id, email: $email) {
updateResult {
succeeded errorCode message
}
}
}
}
var req = new GraphQLRequest {
OperationType = GraphQLOperationType.Subscription,
RootField = "notificationAPI",
Method = "onNewAlert",
Arguments = new Dictionary<string, object> {
{ "severity", "HIGH" }
},
Fields = "alertId message timestamp"
};
Console.WriteLine(req.ToGraphQL(pretty: true));
Expected Output:
subscription {
notificationAPI {
onNewAlert(severity: "HIGH") {
responseResult {
alertId message timestamp
}
}
}
}
The GraphQLFile
class is used to support file uploads in GraphQL operations using the GraphQL multipart request specification. It wraps file content into a serializable structure that is automatically handled by the builder when ToMultipartFormDataContent()
is invoked.
Property | Type | Description |
---|---|---|
FileName |
string |
The name of the file as it should appear in the upload payload. |
Content |
Stream |
The stream containing the file’s binary contents. Must remain open until the request is transmitted. |
ContentType |
string |
The MIME type of the file (e.g., image/png , application/pdf ). |
public GraphQLFile(Stream content, string fileName, string contentType = "application/octet-stream")
content
: A stream that contains the file data. Required.fileName
: The file name to include in the payload. Required.contentType
: The MIME type of the file. Optional, defaults to application/octet-stream
.var file = new GraphQLFile(File.OpenRead("avatar.jpg"), "avatar.jpg", "image/jpeg");
var req = new GraphQLRequest {
OperationType = GraphQLOperationType.Mutation,
RootField = "profileAPI",
Method = "uploadProfilePicture",
Variables = new Dictionary<string, object> {
{ "file", file },
{ "userId", 42 }
},
VariableDeclarations = new Dictionary<string, string> {
{ "file", "Upload!" },
{ "userId", "Int!" }
},
UseVariables = true,
Fields = "url uploadedAt"
};
var httpContent = req.ToMultipartFormDataContent();
This will generate a multipart payload with:
operations
JSON object describing the GraphQL requestmap
object mapping file indexes to variable namesGraphQLFile
in the Variables
dictionaryoperations (part 1):
{
"query": "mutation { profileAPI { uploadProfilePicture(userId: $userId, file: $file) { responseResult { url uploadedAt } } } }",
"variables": {
"file": null,
"userId": 42
},
"operationName": null
}
map (part 2):
{
"0": ["variables.file"]
}
part 3 (file content):
Content-Disposition: form-data; name="0"; filename="avatar.jpg"
Content-Type: image/jpeg
GraphQLFile
values are extracted for multipart; other variables remain in operations
The GraphQLFluentBuilder
provides a chainable, fluent interface for composing GraphQLRequest
objects. It improves readability and helps avoid verbose setup logic by allowing common parameters to be defined in a structured, expressive way.
Use the fluent builder when you want to build queries dynamically or in contexts where readability and configurability matter — such as integrations, orchestrators, or agent-generated requests.
Method | Description |
---|---|
NewQuery(string root, string method) |
Starts a new query request. |
NewMutation(string root, string method) |
Starts a new mutation request. |
NewSubscription(string root, string method) |
Starts a new subscription request. |
SetOperation(GraphQLOperationType) |
Overrides the operation type manually. |
SetRoot(string) |
Sets the root field (namespace/service). |
SetMethod(string) |
Sets the method or field to invoke. |
WithArgument(string, object) |
Adds an inline argument. Use for simple value injection. |
WithVariable(string, string, object) |
Declares and sets a named GraphQL variable. Enables UseVariables = true . |
Select(params string[]) |
Sets the field selection block. |
DefaultFields(params string[]) |
Sets fallback field selections if Fields is empty. |
Wrap(string wrapperName) |
Enables response wrapping under a named field. |
WithFragment(string) |
Appends a raw fragment block to the request. |
OperationName(string) |
Sets a name for the operation. |
Build() |
Finalizes and returns the GraphQLRequest . |
var req = GraphQLFluentBuilder
.NewQuery("catalogService", "getItem")
.WithArgument("sku", "ABC-123")
.Select("id name price available")
.Build();
Console.WriteLine(req.ToGraphQL(pretty: true));
Expected Output:
query {
catalogService {
getItem(sku: "ABC-123") {
responseResult {
id name price available
}
}
}
}
var req = GraphQLFluentBuilder
.NewMutation("userAPI", "resetPassword")
.WithVariable("userId", "ID!", 501)
.WithVariable("token", "String!", "abc123")
.Select("succeeded message")
.Wrap("resetResult")
.OperationName("ResetUserPassword")
.Build();
Console.WriteLine(req.ToGraphQL(pretty: true));
Expected Output:
mutation ResetUserPassword($userId: ID!, $token: String!) {
userAPI {
resetPassword(userId: $userId, token: $token) {
resetResult {
succeeded message
}
}
}
}
var req = GraphQLFluentBuilder
.NewSubscription("logAPI", "onSystemEvent")
.WithArgument("level", "WARN")
.Select("timestamp message details")
.Build();
Console.WriteLine(req.ToGraphQL(pretty: true));
Expected Output:
subscription {
logAPI {
onSystemEvent(level: "WARN") {
responseResult {
timestamp message details
}
}
}
}
var fragment = "fragment userFields on User { id name email roles }";
var req = GraphQLFluentBuilder
.NewQuery("userService", "getUser")
.WithVariable("id", "ID!", 777)
.Select("...userFields")
.DefaultFields("id")
.WithFragment(fragment)
.OperationName("GetUserWithFragment")
.Build();
Console.WriteLine(req.ToGraphQL(pretty: true));
Expected Output:
query GetUserWithFragment($id: ID!) {
userService {
getUser(id: $id) {
responseResult {
...userFields
}
}
}
}
fragment userFields on User {
id name email roles
}
The GraphQLRequest
object supports several serialization formats based on how you plan to transmit or log the query. These methods output GraphQL documents, JSON request bodies, or multipart form data payloads, depending on the structure of the request.
ToGraphQL(bool pretty = false)
Renders a complete GraphQL operation as a string. When pretty = true
, the output is formatted with line breaks and indentation. When false
, the string is compact and optimized for transport.
string document = req.ToGraphQL(pretty: true);
Console.WriteLine(document);
Output:
query {
catalogService {
getItem(sku: "ABC-123") {
responseResult {
id name price available
}
}
}
}
ToJsonRequest()
Produces a JSON object containing the GraphQL document and variables. This is useful for sending GraphQL POST requests via application/json
.
string json = req.ToJsonRequest();
Console.WriteLine(json);
Output:
{
"query": "query { catalogService { getItem(sku: \"ABC-123\") { responseResult { id name price available } } } }",
"variables": {},
"operationName": null
}
If UseVariables = true
, the variables
block is populated and the query uses $variable
placeholders.
ToHttpContent()
Wraps the JSON payload produced by ToJsonRequest()
in a StringContent
object with the correct media type. This is the recommended format for sending HTTP POSTs.
HttpContent content = req.ToHttpContent();
application/json
ToMultipartFormDataContent()
Generates a multipart/form-data body compatible with the GraphQL multipart request spec. This is automatically used when the Variables
dictionary includes one or more GraphQLFile
values.
var content = req.ToMultipartFormDataContent();
Parts include:
operations
: A JSON payload with query
, variables
, and operationName
map
: Maps file field keys to variable names (e.g., "0": ["variables.file"]
)"0"
, "1"
, etc.) with appropriate content disposition headersFiles must remain open when passed to the request. Streams will be read during transmission.
The GraphQLBuilder
class provides low-level static methods that support manual formatting of key GraphQL components such as arguments, variable declarations, usage blocks, and field selection. These methods are also used internally when rendering final GraphQL strings and can be useful for:
Formats a dictionary of key-value pairs into GraphQL inline argument syntax.
var args = new Dictionary<string, object> {
{ "limit", 10 },
{ "active", true },
{ "keywords", new[] { "fuse", "interop" } }
};
string result = GraphQLBuilder.BuildArguments(args);
Console.WriteLine(result);
Output:
limit: 10, active: true, keywords: ["fuse", "interop"]
Builds the GraphQL $variable: Type
declaration block for use in the operation signature.
var declarations = new Dictionary<string, string> {
{ "id", "ID!" },
{ "name", "String" },
{ "count", "Int" }
};
string block = GraphQLBuilder.BuildVariableDeclarations(declarations);
Console.WriteLine(block);
Output:
($id: ID!, $name: String, $count: Int)
Generates a GraphQL usage block that references named variables.
var usage = GraphQLBuilder.BuildVariableUsages(new Dictionary<string, object> {
{ "id", 123 },
{ "name", "Alice" }
});
Console.WriteLine(usage);
Output:
(id: $id, name: $name)
Cleans and normalizes a field list. If the primary list is null or empty, it returns the default.
string fields = GraphQLBuilder.BuildFields("id name email", "id");
Console.WriteLine(fields);
Output:
id name email
Generates a complete GraphQL string from a fully constructed GraphQLRequest
.
string gql = GraphQLBuilder.BuildOperation(req, pretty: true);
Console.WriteLine(gql);
Used internally by ToGraphQL()
, but may be useful for rendering a query without needing to serialize the entire payload.
Output: will match that of ToGraphQL(pretty: true)
based on the configured request.
The GraphQLBuilder
class provides convenient static factory methods to generate fully configured GraphQLRequest
instances for common operation types. These methods are ideal for fast creation of GraphQL operations using familiar parameters like root, method, arguments, fields, and wrapper options.
These are useful when you want to skip manual property assignment or don’t need fluent chaining.
var req = GraphQLBuilder.CreateQuery(
root: "inventory",
method: "getItem",
args: new Dictionary<string, object> {
{ "sku", "123-ABC" }
},
fields: "id name price",
wrap: true,
responseWrapper: "result",
operationName: "GetInventoryItem"
);
Console.WriteLine(req.ToGraphQL(pretty: true));
Output:
query GetInventoryItem {
inventory {
getItem(sku: "123-ABC") {
result {
id name price
}
}
}
}
var req = GraphQLBuilder.CreateMutation(
root: "accountService",
method: "updateProfile",
args: new Dictionary<string, object> {
{ "id", 101 },
{ "bio", "GraphQL fan" }
},
fields: "succeeded message",
wrap: true,
responseWrapper: "update",
operationName: "UpdateUserBio"
);
Console.WriteLine(req.ToGraphQL(pretty: true));
Output:
mutation UpdateUserBio {
accountService {
updateProfile(id: 101, bio: "GraphQL fan") {
update {
succeeded message
}
}
}
}
var req = GraphQLBuilder.CreateSubscription(
root: "logService",
method: "onSystemEvent",
args: new Dictionary<string, object> {
{ "level", "ERROR" }
},
fields: "timestamp message source",
wrap: false
);
Console.WriteLine(req.ToGraphQL(pretty: true));
Output:
subscription {
logService {
onSystemEvent(level: "ERROR") {
timestamp message source
}
}
}
This version supports variable declarations and automatically enables UseVariables = true
.
var req = GraphQLBuilder.CreateWithVariables(
type: GraphQLOperationType.Mutation,
root: "documentAPI",
method: "submitDocument",
variableDeclarations: new Dictionary<string, string> {
{ "title", "String!" },
{ "content", "String!" },
{ "userId", "ID!" }
},
variables: new Dictionary<string, object> {
{ "title", "Interoperability Whitepaper" },
{ "content", "GraphQL is the future." },
{ "userId", 201 }
},
fields: "documentId status",
wrap: true,
responseWrapper: "submission",
operationName: "SubmitDoc"
);
Console.WriteLine(req.ToGraphQL(pretty: true));
Output:
mutation SubmitDoc($title: String!, $content: String!, $userId: ID!) {
documentAPI {
submitDocument(title: $title, content: $content, userId: $userId) {
submission {
documentId status
}
}
}
}
While basic GraphQL Builder usage covers most workflows, there are advanced scenarios that require more control or customization. This section illustrates common patterns and their application across real-world Fuse use cases.
You may need to send some values inline and others via variables — for example, when a file upload forces UseVariables = true
but scalar fields remain static.
var file = new GraphQLFile(File.OpenRead("contract.pdf"), "contract.pdf", "application/pdf");
var req = new GraphQLRequest {
OperationType = GraphQLOperationType.Mutation,
RootField = "legalAPI",
Method = "submitContract",
UseVariables = true,
VariableDeclarations = new Dictionary<string, string> {
{ "file", "Upload!" },
{ "clientId", "ID!" }
},
Variables = new Dictionary<string, object> {
{ "file", file },
{ "clientId", 789 }
},
Fields = "status submittedAt"
};
var content = req.ToMultipartFormDataContent();
GraphQL inputs often require nested structures or lists of objects. Use anonymous objects or dictionaries to build them.
var input = new Dictionary<string, object> {
{ "userId", 101 },
{ "preferences", new Dictionary<string, object> {
{ "notifications", true },
{ "timezone", "America/New_York" }
}}
};
var req = GraphQLBuilder.CreateMutation(
root: "userService",
method: "updatePreferences",
args: new Dictionary<string, object> { { "input", input } },
fields: "succeeded updatedAt"
);
Some pipelines generate GraphQL dynamically based on AI-generated metadata or configuration.
string method = context["methodName"]?.ToString();
string[] fieldList = context.GetArray<string>("fields") ?? new[] { "id" };
var req = GraphQLFluentBuilder
.NewQuery("aiService", method)
.Select(fieldList)
.Build();
While GraphQL doesn’t natively support true multi-operation batching in one HTTP call, you can simulate client batching via loops:
var operations = new List<string>();
foreach (var sku in new[] { "A", "B", "C" }) {
var op = GraphQLBuilder.CreateQuery(
root: "catalogAPI",
method: "getItem",
args: new Dictionary<string, object> { { "sku", sku } },
fields: "id name"
).ToGraphQL();
operations.Add(op);
}
Fragments can be defined once and reused across requests.
const string userFragment = "fragment userFields on User { id name role email }";
var req = GraphQLFluentBuilder
.NewQuery("userAPI", "getUser")
.WithVariable("id", "ID!", 7)
.Select("...userFields")
.WithFragment(userFragment)
.Build();
Output:
query {
userAPI {
getUser(id: $id) {
responseResult {
...userFields
}
}
}
}
fragment userFields on User {
id name role email
}
The following guidelines will help you get the most out of the GraphQL Builder and avoid common pitfalls when building or transmitting GraphQL requests across services and pipelines.
WithVariable
or VariableDeclarations
when passing user inputs, secrets, or values that change per request..Wrap()
or set WrapResponse = true
to group responses under a predictable field like responseResult
or data
.DefaultFields
DefaultFields = "id name"
or a safe fallback value.Fields
might be generated dynamically.WithArgument
) when values are constant or not sensitive.GraphQLFile
values and send metadata as variables.GraphQLFile.Content
before transmission.ToMultipartFormDataContent()
, ensure file streams are still valid when passed to HttpClient.SendAsync()
.OperationName
for traceabilityOperationName
in long-lived or orchestrated pipelines so logs and analytics can identify which GraphQL call was made.userFields
) in shared constants or templates.GraphQL Builder simplifies many aspects of request composition, but some issues can arise during implementation or runtime. This section lists common problems and how to fix or avoid them.
Fields
was left blank and no DefaultFields
were set.Fields
explicitly, or set DefaultFields
to ensure fallback.Fields = string.IsNullOrWhiteSpace(Fields) ? DefaultFields : Fields;
BuildOperation()
or ToGraphQL(pretty: true)
to inspect output. Validate against your GraphQL schema (e.g., Apollo or GraphiQL).null
values in output or serialized queryallowNullValues = false
.Variables
and BuildArguments()
options. Confirm non-null inputs are set before calling ToGraphQL()
.GraphQLFile
is closed or disposed before sending.GraphQLFile
remains open during execution.var file = new GraphQLFile(File.OpenRead(path), "doc.pdf", "application/pdf");
WrapResponse = true
but no ResponseWrapper
provided.ResponseWrapper
explicitly, or accept the default ("responseResult"
).WrapResponse = true;
ResponseWrapper = ResponseWrapper ?? "responseResult";
VariableDeclarations
for accuracy and ensure UseVariables = true
is set.Explore other pages in the Fuse Development Framework to learn how GraphQL Builder fits into broader orchestration and integration use cases.
Next: Pipeline Component Framework — Learn how to build modular, governed orchestration logic inside Fuse.