GraphQL.Client Documentation

repository·master·Indexed 20 days ago

https://github.com/graphql-dotnet/graphql-client

A .NET Standard GraphQL client for HTTP and WebSocket communication. It provides a thread-safe, high-performance implementation for executing queries, mutations, and subscriptions. Features include support for Automatic Persisted Queries (APQ) since version 6.1.0, multiple serialization options via Newtonsoft.Json and System.Text.Json, and integration with Blazor WebAssembly.

Tokens
2.1K
Snippets
5
Records
7
Agent score
21%

What's inside GraphQL.Client

  1. Enable Automatic Persisted Queries (APQ)

    master

    Automatic Persisted Queries (APQ) are supported starting from version 6.1.0. APQ reduces bandwidth by sending a hash of the query instead of the full string.

    To enable APQ, set EnableAutomaticPersistedQueries to true in GraphQLHttpClientOptions.

    Behavior:

    • If the server returns a PersistedQueryNotSupported error or a 400/600 HTTP status code, the client automatically disables APQ for the current session.
    • To re-enable APQ after it has been disabled, you must dispose of and recreate the GraphQLHttpClient.
    • Optimization Tip: Use the GraphQLQuery class instead of raw strings in GraphQLRequest. When using GraphQLQuery, the hash is computed once during construction, which is more efficient for reusing queries.
    // Configuration
    var options = new GraphQLHttpClientOptions {
        EnableAutomaticPersistedQueries = true
    };
    
    // Optimized usage with GraphQLQuery
    GraphQLQuery query = new("query PersonAndFilms($id: ID) { ... }");
                             
    var graphQLResponse = await graphQLClient.SendQueryAsync<ResponseType>(
        query, 
        "PersonAndFilms",
        new { id = "cGVvcGxlOjE=" });
  2. Install GraphQL.Client packages

    master

    GraphQL.Client is distributed via NuGet. Depending on your needs, you may need the following packages:

    • GraphQL.Client: The core client.
    • GraphQL.Client.Abstractions: Core abstractions.
    • GraphQL.Client.Abstractions.Websocket: For WebSocket support.
    • GraphQL.Client.Serializer.Newtonsoft: For Newtonsoft.Json serialization.
    • GraphQL.Client.Serializer.SystemTextJson: For System.Text.Json serialization.
    • GraphQL.Client.LocalExecution: For local execution capabilities.
  3. Execute Query or Mutation

    master

    Use SendQueryAsync<T> to execute a query or mutation.

    Note on Response Mapping: The GraphQL response contains a data field. When deserializing, your response type T must model the structure inside that data field. A common mistake is to use the entity type (e.g., PersonType) directly as the response type, whereas you actually need a wrapper class that contains the property matching the GraphQL field name (e.g., ResponseType containing a Person property).

    You can also use an extension method for anonymously typed responses from the GraphQL.Client.Abstractions namespace.

    // Using a wrapper class for the response
    public class ResponseType 
    {
        public PersonType Person { get; set; }
    }
    
    public class PersonType 
    {
        public string Name { get; set; }
        public FilmConnectionType FilmConnection { get; set; }    
    }
    
    public class FilmConnectionType {
        public List<FilmContentType> Films { get; set; }    
    }
    
    public class FilmContentType {
        public string Title { get; set; }
    }
    
    var graphQLResponse = await graphQLClient.SendQueryAsync<ResponseType>(personAndFilmsRequest);
    var personName = graphQLResponse.Data.Person.Name;
    
    // Alternative: Using an extension method for anonymous responses
    var graphQLResponse = await graphQLClient.SendQueryAsync(
        personAndFilmsRequest, 
        () => new { person = new PersonType()});
    var personName = graphQLResponse.Data.person.Name;
  4. Use Subscriptions

    master

    Subscriptions are handled via CreateSubscriptionStream<T>, which returns an IObservable<GraphQLResponse<T>>. You can then Subscribe to the stream to receive updates. To stop receiving updates, call Dispose() on the subscription object.

    public class UserJoinedSubscriptionResult {
        public ChatUser UserJoined { get; set; }
    
        public class ChatUser {
            public string DisplayName { get; set; }
            public string Id { get; set; }
        }
    }
    
    var userJoinedRequest = new GraphQLRequest {
        Query = @"
        subscription {
            userJoined{
                displayName
                id
            }
        }"
    };
    
    IObservable<GraphQLResponse<UserJoinedSubscriptionResult>> subscriptionStream 
        = client.CreateSubscriptionStream<UserJoinedSubscriptionResult>(userJoinedRequest);
    
    var subscription = subscriptionStream.Subscribe(response => 
        {
            Console.WriteLine($"user '{response.Data.UserJoined.DisplayName}' joined")
        });
    
    // End Subscription
    subscription.Dispose();
  5. Create a GraphQLHttpClient

    master

    To use the client, instantiate GraphQLHttpClient with the endpoint URL and a serializer.

    Important: GraphQLHttpClient is designed to be a long-lived, thread-safe instance. You should register it as a singleton in your Dependency Injection (DI) system and reuse it for multiple requests rather than creating a new instance per request.

    // To use NewtonsoftJsonSerializer, add a reference to 
    // NuGet package GraphQL.Client.Serializer.Newtonsoft
    var graphQLClient = new GraphQLHttpClient(
        "https://api.example.com/graphql", 
        new NewtonsoftJsonSerializer());
  6. Create a GraphQLRequest

    master

    You can define requests using the GraphQLRequest class. You can provide a simple query, or a more complex request including an OperationName and Variables.

    WARNING

    When using byte[] in your variables object, most JSON serializers treat it as binary data (often base64-encoded). If you need to send a list of bytes as a JSON array of numbers, convert your byte[] to a List<byte> first.

    // Simple Request
    var heroRequest = new GraphQLRequest {
        Query = """
        {
            hero {
                name
            }
        }
        ""
    };
    
    // OperationName and Variables Request
    var personAndFilmsRequest = new GraphQLRequest {
        Query = """
        query PersonAndFilms($id: ID) {
            person(id: $id) {
                name
                filmConnection {
                    films {
                        title
                    }
                }
            }
        }
        """,
        OperationName = "PersonAndFilms",
        Variables = new {
            id = "cGVvcGxlOjE="
        }
    };