ValidateGraphQLClientAssembliesAsync
Validates every request type a client owns in a set of assemblies against that client's schema, so a query the server no longer accepts fails at startup or in a test instead of on first use. Call it after app.Build().
Signatures
public static Task ValidateGraphQLClientAssembliesAsync(
this IServiceProvider services,
params Assembly[] assemblies)
public static Task ValidateGraphQLClientAssembliesAsync(
this IServiceProvider services,
object serviceKey,
params Assembly[] assemblies)| Parameter | Type | Required | Description |
|---|---|---|---|
services | IServiceProvider | Yes | The built container, usually app.Services |
serviceKey | object | Keyed overload | The key the client was registered with by AddKeyedTraxGraphQLClient |
assemblies | Assembly[] | Yes | The assemblies to scan |
Returns: a Task that completes when every request has validated.
Which requests are checked
Every concrete class in assemblies that implements IGenericGraphQLClientRequest and belongs to the client:
- The unkeyed overload checks the types that carry no
[GraphQLClient]mark, against the unkeyed client's schema. - The keyed overload checks the types marked
[GraphQLClient(serviceKey)], against the schema of the client registered under that key.
Each type is created with RuntimeHelpers.GetUninitializedObject, without running a constructor, and its Query is validated. A Query must therefore not depend on state a constructor sets. A literal string, an embedded resource (GraphQLResourceRequest) and a TypedRequest all qualify. Validation stops at the first failure.
Exceptions
| Exception | When |
|---|---|
GraphQLValidationException | A query does not validate against the schema, has no operation, or has more than one. Query holds the failing text and Errors the validator's errors |
GraphQLSchemaIntrospectionException | The schema could not be loaded (introspection failed, the SDL file is missing or invalid) |
InvalidOperationException | No request type in assemblies belongs to this client, or (keyed overload) no client is registered under serviceKey |
Finding nothing to validate is refused on purpose: it almost always means a request was left unmarked or marked with a misspelt key, and passing would hide that.
Example
var app = builder.Build();
await app.Services.ValidateGraphQLClientAssembliesAsync(typeof(Program).Assembly);
await app.Services.ValidateGraphQLClientAssembliesAsync("billing", typeof(Program).Assembly);
app.Run();In a test, the same call over a container built with UseFileSchema checks every query against the checked-in schema with no server running.
Validating with a custom filter
IGraphQLClientValidator, which every client registers, carries an extension for scanning without the ownership rule:
public static Task ValidateAssembliesAsync(
this IGraphQLClientValidator validator,
IEnumerable<Assembly> assemblies,
CancellationToken cancellationToken = default)
public static Task ValidateAssembliesAsync(
this IGraphQLClientValidator validator,
IEnumerable<Assembly> assemblies,
Func<Type, bool>? typeFilter,
CancellationToken cancellationToken = default)It validates every request type typeFilter accepts (all of them when null), whatever its [GraphQLClient] mark, and does not fail when it finds none.
Remarks
- For host-startup gating,
UseStartupValidationon the builder does the same check from a hosted service, so the host refuses to start on a failure. - The validator caches each query text that passes, so validating at startup also warms the cache the executor uses.
Package
dotnet add package Trax.Api.GraphQL.Client