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>
| Member | Description |
|---|---|
Query | The 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. |
Variables | A 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
| Attribute | On | Arguments | Effect |
|---|---|---|---|
[GraphQLOperation(OperationType)] | the request class | OperationType (Query or Mutation), Name, RootField, Path | Marks the class as a typed request. Required. |
[GraphQLType(typeName)] | a response class | the schema type's name | Required 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 property | the full GraphQL type, such as String!; VariableName | Declares $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 property | the schema field name | Selects that field, aliased to the property's response key when they differ. |
GraphQLOperation properties
| Property | Default | Description |
|---|---|---|
OperationType | (constructor) | Query or Mutation. Subscriptions are not supported. |
Name | the request type name, without a trailing Request | The operation name. |
RootField | the camel-cased operation name | The field selected on the root type. |
Path | none | Dot-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 property | Selected as |
|---|---|
| nothing | the 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, Never | the property as usual; those conditions affect writing only |
| an indexer | nothing |
| Property type | Selected as |
|---|---|
a class marked [GraphQLType] | an object, with its own sub-selection |
a class with public properties, outside the System namespaces | an 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
| Case | Result |
|---|---|
A response type that leads back to itself, directly (Category.Parent is a Category) or through other types | InvalidOperationException 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 validated | Skipped; the closed request types deriving from it are validated. |
See also
SDK Reference
IGraphQLClientRequest | ValidateGraphQLClientAssembliesAsync