dotnet tool NuGet v1.0.0 MIT

MetaEngine.CSharp.GraphQL.HttpClient.Tool

GraphQL SDL → C# HttpClient services and System.Text.Json models with typed queries, mutations & subscriptions (subscriptions surface as IAsyncEnumerable<T> over a ClientWebSocket using the graphql-transport-ws subprotocol), plus bearer/basic auth, retries, custom headers, smart HTTP-status error handling, fragments and @oneOf inputs. Ships as a NuGet library plus a dotnet tool CLI.

GraphQL SDLMetaEngine IRC# · HttpClient
Install

Pick your registry

The same generator, published to every ecosystem we support. Install however your project expects.

dotnet toolPrimaryMetaEngine.CSharp.GraphQL.HttpClient.Tool
$dotnet tool install --global MetaEngine.CSharp.GraphQL.HttpClient.Tool
v1.0.0
NuGetMetaEngine.CSharp.GraphQL.HttpClient
$dotnet add package MetaEngine.CSharp.GraphQL.HttpClient
v1.0.0
Usage

Drive it from the CLI or programmatically

dotnet tool ships a zero-config CLI. NuGet ships the same generator as a C# fluent API — same options, same output.

NuGet · dotnet tool · CI-friendly

After install, point the CLI at your schema. It writes the generated tree to your chosen output directory.

Basic syntax
terminal
metaengine-graphql-csharp-httpclient <input> <output> <namespace> [options]

Generates C# HttpClient services and System.Text.Json models from a GraphQL SDL schema — typed queries, mutations & subscriptions (subscriptions surface as IAsyncEnumerable<T> over a ClientWebSocket using the graphql-transport-ws subprotocol). Install as a global .NET tool with: dotnet tool install --global MetaEngine.CSharp.GraphQL.HttpClient.Tool (requires the .NET 8.0+ SDK).

Quick examples
Install the tool
dotnet tool install --global MetaEngine.CSharp.GraphQL.HttpClient.Tool
Fragments, XML docs and retries
metaengine-graphql-csharp-httpclient ./schema.graphql ./Generated Shop.Client \
  --fragments \
  --documentation \
  --retries 3
Bearer auth, smart error handling and a custom scalar
metaengine-graphql-csharp-httpclient ./schema.graphql ./Generated Shop.Client \
  --bearer-auth API_TOKEN \
  --error-handling \
  --custom-scalar DateTime=System.DateTime
DI middleware and a baked subscription path
metaengine-graphql-csharp-httpclient ./schema.graphql ./Generated Shop.Client \
  --middleware \
  --subscription-url /api/graphql
CLI options
Option
Description
--options-threshold <n>
Parameter count at which an operation collapses its arguments into an options object [default: 4]
--documentation
Generate XML doc comments from GraphQL SDL descriptions
--middleware
Generate middleware infrastructure (ApiDelegatingHandler + ServiceCollectionExtensions)
--error-handling
Enable smart error handling based on HTTP status semantics
--bearer-auth [env-var]
Bearer token from an env var (default API_TOKEN); adds an Authorization header to all requests
--basic-auth
Basic auth from env vars (API_USERNAME / API_PASSWORD)
--retries [max-attempts]
Enable retries with exponential backoff; optional value sets max attempts
--custom-header <name=env-var>
Static header from an env var. Repeatable (e.g. X-Tenant-ID=TENANT_ID)
--subscription-url <path>
Path appended to the WebSocket base URL for GraphQL subscriptions (default /graphql); baked into the generated BaseHttpClient
--fragments
Emit reusable named fragments for object-type selections (...TypeFields spreads)
--oneof-inputs
Generate idiomatic @oneOf input types (tagged-union inputs)
--custom-scalar <GraphQLScalar=DotNetType>
Map a GraphQL custom scalar to a fully-qualified .NET type (e.g. DateTime=System.DateTime). Repeatable
--include-types <types>
Only generate these GraphQL types (comma-separated type names)
--clean
Clean the destination directory before generating
--verbose
Enable verbose logging
Options reference

Every knob, documented

Every option is available on the C# fluent API as a method, and most are also exposed as CLI flags. Cross-cutting auth, headers, retries and timeouts apply across frameworks.

C# Output

2
  • WithMiddleware()Generate middleware infrastructure (ApiDelegatingHandler + ServiceCollectionExtensions) for DI-ready registration
  • WithOptionsObjectThreshold(int)Parameter count at which an operation collapses its arguments into a single options object (default: 4)

Auth · Headers · Resilience

11
  • WithErrorHandling()Smart error handling based on HTTP status semantics (404 / 403 → null · 400 / 422 / 409 → error body · 401 / 5xx → throw). GraphQL operations travel over HTTP POST.
  • WithErrorHandling(errors => errors...)Per-status routing: ReturnNullFor(404, 403) · ReturnErrorFor(400, 422) · ThrowFor(401, 500)
  • WithBearerAuth()Bearer token from env var (default API_TOKEN) — adds an Authorization header
  • WithBearerAuth(string)Bearer token from a specific env var name
  • WithBearerAuth(string, string)Bearer token from an env var with a custom header name
  • WithBasicAuth()HTTP Basic auth from default env vars (API_USERNAME / API_PASSWORD)
  • WithBasicAuth(string, string)HTTP Basic auth from username + password env vars
  • WithCustomHeader(string, string)Static header read from an env var. Repeatable (e.g. X-Tenant-ID ← TENANT_ID)
  • WithRetries()Retries with exponential backoff (default status 429, 503)
  • WithRetries(int)Retries with a custom max-attempts count
  • WithRetries(int, double, double, int[])Retries with full custom settings: max attempts · base delay · max delay · retryable status codes

GraphQL Options

6
  • WithDocumentation()Generate XML doc comments (///) on services and models from SDL type & field descriptions
  • WithFragments()Emit reusable named fragments for object-type selections (...TypeFields spreads)
  • WithOneOfInputs()Generate idiomatic @oneOf input types (tagged-union inputs where exactly one field is set)
  • WithCustomScalar(string, Type)Map a GraphQL custom scalar to a .NET type (e.g. DateTime → System.DateTime). Unmapped scalars default to string
  • WithTypeFilter(Func)Filter extracted GraphQL types before registration — only types returning true are generated (e.g. t => t.IsUsed)
  • WithMethodNames(Func)Custom method naming rule

Subscriptions (WebSocket)

1
  • WithSubscriptionUrl(string)Path appended to the WebSocket base URL (after http→ws / https→wss upgrade of baseUrl) for GraphQL subscriptions (default /graphql). Baked into the generated BaseHttpClient at generation time. Subscriptions surface as IAsyncEnumerable<T> over a ClientWebSocket using the graphql-transport-ws subprotocol.

Naming Transformations

3
  • Types(Func)Transform type names
  • Paths(Func)Transform output paths
  • FileNames(Func)Transform file names

File Management

5
  • CleanDestination()Clean output directory before generation
  • AlwaysOverwrite()Always overwrite existing files
  • OnlyWhenModelChanged()Update only when model changes
  • OnlyWhenNew()Write only new files, preserve existing
  • CleanDirectories(...)Clean specific subdirectories

Diagnostics

2
  • Verbose()Enable verbose logging
  • WithLogger(Action<string>)Route generation log output to a custom sink
Features

Why this package is different

Deterministic output
Same spec + same options produce byte-identical files. Safe to commit, safe to diff in review, safe to cache in CI.
Flexible naming
Case conventions are configurable per role — types, properties, operations, enums. Idiomatic in the target by default.
Semver-honest
Spec diff drives the version bump. Additive changes = minor, removed operations = major. Never a surprise in your lockfile.