TraxGraphQLClientBuilder

The fluent builder returned by AddTraxGraphQLClient and AddKeyedTraxGraphQLClient. Each method changes the registration in place and returns the builder, so the chain can stop anywhere and the registration is consistent with the calls made so far. On a keyed builder every method applies to that key only.

services
    .AddTraxGraphQLClient(new Uri("https://api.example.com/graphql"))
    .UseFileSchema("schema.graphql")
    .WithStrictness(ResponseStrictness.WarnOnDrift)
    .ConfigureHttpClient(httpClient)
    .DisposeHttpClient();

Methods

MethodPackageDescription
UseIntrospection()ClientValidate against the schema the endpoint reports by introspection. The default
UseFileSchema(string sdlPath)ClientValidate against a checked-in SDL file
UseAssemblySchema(Action<IRequestExecutorBuilder>)Client.TraxBuild the server's HotChocolate schema in-process
WithStrictness(ResponseStrictness)ClientHow strictly responses are checked
ConfigureHttpClient(HttpClient)ClientSupply the HttpClient requests go through
DisposeHttpClient(bool dispose = true)ClientDispose that HttpClient with the client
ConfigureJson(JsonSerializerOptions)ClientReplace the options responses are deserialized with
Configure(Action<GraphQLClientConfigurationBuilder>)ClientSet any option directly
UseStartupValidation(params Assembly[])Client.TraxValidate this client's requests when the host starts

The Services property exposes the IServiceCollection the client was registered against.

Schema source

The three Use* schema methods replace one another: the last one called decides where the schema comes from. Every provider loads the schema on first use and shares it after that. A load that fails is not kept, so the next validation tries again.

UseIntrospection

public TraxGraphQLClientBuilder UseIntrospection()

Validates against the schema the endpoint returns for a standard introspection query. This is what you get when no schema method is called; call it to say so explicitly, or to switch back after another Use* call.

The subscription root is dropped from the introspected schema by default (see RemoveSubscriptionsFromSchema under Configure). Custom scalars the server declares are accepted as any value.

A Trax server answers introspection only in Development unless its host allows the client with AllowIntrospection. Against a production Trax server use UseFileSchema or UseAssemblySchema. A failed introspection throws GraphQLSchemaIntrospectionException from the validation that triggered it.

UseFileSchema

public TraxGraphQLClientBuilder UseFileSchema(string sdlPath)
ParameterTypeRequiredDescription
sdlPathstringYesAbsolute path, or one relative to the process's working directory, of an SDL file such as schema.graphql

Validates against a checked-in schema snapshot. Use it when the endpoint is unreachable at startup (CI, air-gapped builds) or when you want validation against a known schema rather than whatever the endpoint returns today. The file is read on first use, not at registration. A missing, empty or invalid file throws GraphQLSchemaIntrospectionException from that validation.

Throws: ArgumentException when sdlPath is null, empty or whitespace.

Keep the snapshot fresh with a separate job that introspects the server and alerts on a difference, so "queries validate" and "the snapshot is current" are two signals.

UseAssemblySchema

public static TraxGraphQLClientBuilder UseAssemblySchema(
    this TraxGraphQLClientBuilder builder,
    Action<IRequestExecutorBuilder> configureSchema)
ParameterTypeRequiredDescription
configureSchemaAction<IRequestExecutorBuilder>YesThe same HotChocolate configuration delegate the server's Program.cs uses

Builds the server's schema in-process from the server's own configuration, so there is no network call and no file to drift. The calling process takes a binary dependency on the assembly that defines configureSchema. In Trax.Api.GraphQL.Client.Trax.

Responses

WithStrictness

public TraxGraphQLClientBuilder WithStrictness(ResponseStrictness strictness)

Sets how the executor treats a response whose fields differ from the response type's properties. Default Lenient. See ResponseStrictness.

ConfigureJson

public TraxGraphQLClientBuilder ConfigureJson(JsonSerializerOptions options)

Replaces the JsonSerializerOptions the executor deserializes responses with. The defaults are:

  • PropertyNameCaseInsensitive = true
  • a JsonStringEnumConverter with JsonNamingPolicy.SnakeCaseUpper, so a GraphQL enum value GOLD_TIER reads into GoldTier
  • a DateOnly converter

The supplied options replace these rather than adding to them. Response-shape checking matches JSON fields to properties ignoring case, and names properties through PropertyNamingPolicy when one is set, so keep case-insensitive matching and add your own enum converter when you replace them.

Throws: ArgumentNullException when options is null.

services.AddTraxGraphQLClient(uri).ConfigureJson(new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true,
    Converters = { new JsonStringEnumConverter(JsonNamingPolicy.SnakeCaseUpper) },
    NumberHandling = JsonNumberHandling.AllowReadingFromString,
});

HTTP

ConfigureHttpClient

public TraxGraphQLClientBuilder ConfigureHttpClient(HttpClient httpClient)

Supplies the HttpClient that requests and introspection go through. Use it to attach authentication handlers, logging delegates or timeouts. The client's BaseAddress is overwritten with the URI the client was registered with.

By default the library creates its own HttpClient. A supplied one is not disposed by the library unless you call DisposeHttpClient().

Throws: ArgumentNullException when httpClient is null.

var handler = new AuthHeaderHandler(tokens) { InnerHandler = new HttpClientHandler() };
 
services.AddTraxGraphQLClient(uri)
        .ConfigureHttpClient(new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(10) })
        .DisposeHttpClient();

DisposeHttpClient

public TraxGraphQLClientBuilder DisposeHttpClient(bool dispose = true)
ParameterTypeRequiredDescription
disposeboolNotrue (the default when called) to dispose the HttpClient with the client; false to leave it to you

Without this call the caller owns the HttpClient, and only the GraphQL.Client wrapper around it is disposed when the container disposes the client's configuration. Call it when the HttpClient you passed to ConfigureHttpClient belongs to this client alone. Leave it off when the HttpClient is shared or comes from IHttpClientFactory.

Escape hatch

Configure

public TraxGraphQLClientBuilder Configure(Action<GraphQLClientConfigurationBuilder> mutate)

Runs mutate immediately against the underlying GraphQLClientConfigurationBuilder, for options without a dedicated method. Its settable properties:

PropertyTypeDefaultDescription
HttpClientHttpClienta new HttpClientSame as ConfigureHttpClient
DisposeHttpClientboolfalseSame as DisposeHttpClient()
JsonSerializerOptionsJsonSerializerOptionssee ConfigureJsonSame as ConfigureJson
ResponseStrictnessResponseStrictnessLenientSame as WithStrictness
GraphQLClientOptionsGraphQLHttpClientOptionsnew()GraphQL.Client's own transport options
WebsocketJsonSerializerIGraphQLWebsocketJsonSerializerSystemTextJsonSerializerThe serializer GraphQL.Client uses for request and response envelopes
RemoveSubscriptionsFromSchemabooltrueDrop the subscription root from an introspected schema. Applies to UseIntrospection only

Throws: ArgumentNullException when mutate is null.

Startup validation

UseStartupValidation

public static TraxGraphQLClientBuilder UseStartupValidation(
    this TraxGraphQLClientBuilder builder,
    params Assembly[] assemblies)

Registers a hosted service that validates this client's request types in assemblies when the host starts. A query the schema rejects throws GraphQLValidationException, logged with the query, and the host does not start. In Trax.Api.GraphQL.Client.Trax.

An unkeyed client validates the request types with no [GraphQLClient] mark; a keyed client validates those marked with its key. Finding no request type for the client also stops startup, because that is a request someone forgot to mark rather than nothing to check.

Throws: ArgumentNullException when assemblies is null; ArgumentException when it is empty.

Without the .Trax package, call ValidateGraphQLClientAssembliesAsync after the app is built.

Packages

dotnet add package Trax.Api.GraphQL.Client
dotnet add package Trax.Api.GraphQL.Client.Trax   # UseAssemblySchema, UseStartupValidation