Reference

Typed requests

Source Trax.Api.GraphQL.Client.Typed/

TypedRequest<TResponse>, in Trax.Api.GraphQL.Client.Typed, generates a request's query from the request type and the response type instead of taking it as text. The query is generated on first access of Query, cached per request type, and validated against the schema like any other request.

using Trax.Api.GraphQL.Client.Typed;
 
[GraphQLType("Player")]
public sealed record TypedPlayer(string Id, string Name, int? Level, string Rank);
 
[GraphQLOperation(OperationType.Query, RootField = "player")]
public sealed class GetPlayerRequest : TypedRequest<TypedPlayer>
{
    [GraphQLArgument("String!", VariableName = "id")]
    public required string Id { get; init; }
}

generates

query GetPlayer($id: String!) {
  player(id: $id) {
    id
    name
    level
    rank
  }
}

TypedRequest<TResponse>

MemberDescription
QueryThe generated document. Throws InvalidOperationException when the request has no [GraphQLOperation], the response type (or its element type, for a list) has no [GraphQLType], or the response type refers back to itself.
VariablesA dictionary of each [GraphQLArgument] property's current value, keyed by variable name; null when the request declares no arguments.
UnwrapDataElement(data)Walks the data envelope through each Path segment, then into the root field. A missing field or a non-object on the way throws GraphQLExecutionException naming the field, the request type and what was found.

Attributes

AttributeOnArgumentsEffect
[GraphQLOperation(OperationType)]the request classOperationType (Query or Mutation), Name, RootField, PathMarks the class as a typed request. Required.
[GraphQLType(typeName)]a response classthe schema type's nameRequired on the response type or its list element type. Marks a nested class as an object type. typeName is not read when generating; field presence is checked at validation.
[GraphQLArgument(graphQLType)]a request propertythe full GraphQL type, such as String!; VariableNameDeclares $name: Type on the operation and passes it to the root field as the argument of the same name. VariableName defaults to the camel-cased property name.
[GraphQLField(fieldName)]a response propertythe schema field nameSelects that field, aliased to the property's response key when they differ.

GraphQLOperation properties

PropertyDefaultDescription
OperationType(constructor)Query or Mutation. Subscriptions are not supported.
Namethe request type name, without a trailing RequestThe operation name.
RootFieldthe camel-cased operation nameThe field selected on the root type.
PathnoneDot-separated wrapper fields above RootField, such as discover.netsuite. An empty string, an empty segment (a leading, trailing or doubled dot) or whitespace throws InvalidOperationException when the query is generated.

A Trax server groups a namespaced train's field under discover { <namespace> { ... } }, so a typed request reaches it with Path = "discover.<namespace>":

using Trax.Api.GraphQL.Client.Typed;
 
[GraphQLType("Customer")]
public sealed record TypedCustomer(string Id, string Email);
 
[GraphQLOperation(OperationType.Query, Path = "discover.netsuite", RootField = "typedCustomer")]
public sealed class FindCustomerByEmailRequest : TypedRequest<TypedCustomer?>
{
    [GraphQLArgument("String!", VariableName = "email")]
    public required string Email { get; init; }
}

How a property is selected

On the response propertySelected as
nothingthe property name camel-cased as System.Text.Json and HotChocolate do it: Level selects level, ID selects id, URLPath selects urlPath
[JsonPropertyName("rank")]that name
[GraphQLField("name")]the schema field, aliased to the response key when they differ: DisplayName selects displayName: name. A response key that is not a valid GraphQL name cannot be an alias, and generation throws
[JsonIgnore] (Condition = Always)nothing
[JsonIgnore(Condition = WhenWritingNull)], WhenWritingDefault, Neverthe property as usual; those conditions affect writing only
an indexernothing
Property typeSelected as
a class marked [GraphQLType]an object, with its own sub-selection
a class with public properties, outside the System namespacesan object, with its own sub-selection
a string, enum, struct, primitive, or a class in a System namespace (Uri, Version, JsonObject)a scalar
an array or IEnumerable<T>as its element type

The same naming applies to arguments, so URLPath binds $urlPath.

Refusals

CaseResult
A response type that leads back to itself, directly (Category.Parent is a Category) or through other typesInvalidOperationException naming the loop. The same type under two sibling properties is not a loop.
An open generic request type (PagedRequest<T>) found when an assembly is validatedSkipped; the closed request types deriving from it are validated.

See also

SDK Reference

IGraphQLClientRequest | ValidateGraphQLClientAssembliesAsync