SitecoreAPIGraphQLClient 0.9.0

There is a newer version of this package available.
See the version list below for details.
dotnet add package SitecoreAPIGraphQLClient --version 0.9.0
                    
NuGet\Install-Package SitecoreAPIGraphQLClient -Version 0.9.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="SitecoreAPIGraphQLClient" Version="0.9.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SitecoreAPIGraphQLClient" Version="0.9.0" />
                    
Directory.Packages.props
<PackageReference Include="SitecoreAPIGraphQLClient" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add SitecoreAPIGraphQLClient --version 0.9.0
                    
#r "nuget: SitecoreAPIGraphQLClient, 0.9.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package SitecoreAPIGraphQLClient@0.9.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=SitecoreAPIGraphQLClient&version=0.9.0
                    
Install as a Cake Addin
#tool nuget:?package=SitecoreAPIGraphQLClient&version=0.9.0
                    
Install as a Cake Tool

SitecoreAPIGraphQLClient

NuGet

PR Check NuGet Release Pipeline License .NET

A .NET 8 class library that provides a DI-friendly, thread-safe factory for GraphQL clients targeting Sitecore endpoints. It integrates with an authorization service to inject bearer tokens and supports configurable token refresh behavior.

Features

  • Thread-safe GraphQL client factory with per-URL and credential caching (key: url::clientId)
  • Token injection via HttpClient DelegatingHandler using ISitecoreTokenService
  • Configurable refresh on 401 Unauthorized (EnableUnauthorizedRefresh, MaxUnauthorizedRetries)
  • Manual token refresh API: ISitecoreGraphQLFactory.RefreshTokenAsync()
  • Options binding, validation, and DI extension for easy setup
  • Named clients support via configuration (multiple endpoints/credentials)
  • Optional internal logging setup toggle to assist authorization service logging without requiring host AddLogging
  • Unit tests using xUnit, Shouldly, and Moq

Requirements

  • .NET 8 SDK/runtime

Installation

  • NuGet package ID: SitecoreGraphQLClient
  • Using CLI
    dotnet add package SitecoreGraphQLClient
    
  • Using PackageReference
    <ItemGroup>
      <PackageReference Include="SitecoreGraphQLClient" Version="x.y.z" />
    </ItemGroup>
    

Configuration (appsettings.json)

{
  "Sitecore": {
    "GraphQL": {
      "Endpoint": "https://your.sitecore/graphql",
      "ClientId": "your-client-id",
      "ClientSecret": "your-client-secret",
      "EnableUnauthorizedRefresh": true,
      "MaxUnauthorizedRetries": 1,
      "EnableInternalLoggingSetup": true,
      "Clients": {
        "content": {
          "Endpoint": "https://content/graphql",
          "ClientId": "content-id",
          "ClientSecret": "content-secret"
        },
        "search": {
          "Endpoint": "https://search/graphql",
          "ClientId": "search-id",
          "ClientSecret": "search-secret"
        }
      }
    }
  }
}

Registration (Program.cs)

var builder = WebApplication.CreateBuilder(args);
// Bind options and register factory + HTTP pipeline
builder.Services.AddSitecoreGraphQL(builder.Configuration);
// Also register an ISitecoreTokenService implementation provided by Sitecore API Authorization

Optional internal logging setup

By default, AddSitecoreGraphQL will try to register minimal logging services (LoggerFactory and ILogger<T>) if the host did not already add logging, so that downstream services like the Sitecore Token Service can receive ILogger<T>. To opt out, set EnableInternalLoggingSetup to false in configuration.

Basic usage

public class Consumer
{
    private readonly ISitecoreGraphQLFactory _factory;
    public Consumer(ISitecoreGraphQLFactory factory) => _factory = factory;

    public async Task QueryAsync(CancellationToken ct = default)
    {
        // Uses Endpoint, ClientId, ClientSecret from configuration
        var client = await _factory.CreateClientAsync(ct);

        var request = new GraphQL.Client.Abstractions.GraphQLRequest
        {
            Query = "query Example { ping }"
        };
        var response = await client.SendQueryAsync<System.Text.Json.JsonDocument>(request, ct);
        var data = response.Data;
    }
}

Named clients usage

// appsettings.json contains Sitecore:GraphQL:Clients:content and :search

var contentClient = await factory.CreateClientByNameAsync("content", ct);
var searchClient  = await factory.CreateClientByNameAsync("search", ct);

// contentClient and searchClient are cached independently by url::clientId

Advanced: named client from sub-section configuration

// You can bind a sub-section rather than full configuration, e.g. from an options object
var graphQlSection = builder.Configuration.GetSection("Sitecore:GraphQL");
builder.Services.AddSitecoreGraphQL(new ConfigurationBuilder().AddConfiguration(graphQlSection).Build());

// Or compose programmatic options (e.g., in tests)
services.Configure<SitecoreGraphQLOptions>(o =>
{
    o.Clients["analytics"] = new SitecoreGraphQLClientOptions
    {
        Endpoint = "https://analytics/graphql",
        ClientId = env["ANALYTICS_ID"],
        ClientSecret = env["ANALYTICS_SECRET"]
    };
});
var analytics = await factory.CreateClientByNameAsync("analytics", ct);

Overloads

// 1) Explicit endpoint (uses configured credentials)
var c1 = await factory.CreateClientAsync("https://your.sitecore/graphql", ct);

// 2) Explicit endpoint and explicit credentials (bypasses configured credentials)
var c2 = await factory.CreateClientAsync(
    url: "https://another/graphql",
    clientId: "client-id",
    clientSecret: "client-secret",
    cancellationToken: ct);

// 3) Default endpoint and credentials from configuration
var c3 = await factory.CreateClientAsync(ct);

// 4) Named client from configuration
var c4 = await factory.CreateClientByNameAsync("content", ct);

Manual token refresh

var refreshed = await factory.RefreshTokenAsync(ct);
if (!refreshed)
{
    // handle refresh failure (log, alert, etc.)
}

Options reference

  • Endpoint: default GraphQL endpoint used when not passing a URL into CreateClientAsync (must be valid http/https if provided)
  • ClientId: OAuth client id used to acquire tokens
  • ClientSecret: OAuth client secret used to acquire tokens
  • EnableUnauthorizedRefresh: when true, refresh and retry on 401 responses
  • MaxUnauthorizedRetries: number of additional retries after the first 401 (0 disables retries)
  • EnableInternalLoggingSetup: when true (default), DI will TryAdd minimal logging so downstream services can receive ILogger<T>; set to false to opt out
  • Clients: named client map; each entry requires Endpoint (valid http/https), ClientId, ClientSecret

API surface

  • Interfaces
    • ISitecoreGraphQLFactory
      • Task<IGraphQLClient> CreateClientAsync(string url, string clientId, string clientSecret, CancellationToken ct = default)
      • Task<IGraphQLClient> CreateClientAsync(string url, CancellationToken ct = default)
      • Task<IGraphQLClient> CreateClientAsync(CancellationToken ct = default)
      • Task<IGraphQLClient> CreateClientByNameAsync(string clientName, CancellationToken ct = default)
      • Task<bool> RefreshTokenAsync(CancellationToken ct = default)
    • ITokenValueAccessor (advanced)
      • string GetAccessToken(SitecoreAuthToken token)
    • ISitecoreTokenCache (advanced)
      • string? CurrentToken { get; }
      • Task<string?> GetOrRefreshAsync(CancellationToken ct)
      • Task<string?> ForceRefreshAsync(CancellationToken ct)
  • Classes
    • DependencyInjection.ServiceCollectionExtensions
      • IServiceCollection AddSitecoreGraphQL(IConfiguration configuration)
    • SitecoreGraphQLOptions
      • string? Endpoint, string? ClientId, string? ClientSecret
      • bool EnableUnauthorizedRefresh (default true), int MaxUnauthorizedRetries (default 1)
      • bool EnableInternalLoggingSetup (default true)
      • Dictionary<string, SitecoreGraphQLClientOptions> Clients
    • Http.SitecoreTokenHandler
      • DelegatingHandler that injects Authorization: Bearer and retries on 401 with exponential backoff
    • SitecoreGraphQLFactory
      • public const string NamedHttpClient = "SitecoreGraphQL"

Testing

  • Run tests locally
    dotnet test -v minimal
    
  • Generate coverage locally (example)
    dotnet test --configuration Release --collect:"XPlat Code Coverage"
    
  • Stack: xUnit, Shouldly, Moq
  • Pattern: Arrange�Act�Assert

CI

  • GitHub Actions workflows build and test on .NET SDK 8 and 9
  • Coverage artifacts are uploaded from CI
  • NuGet publishing triggered on version tags (v*)

Versioning and changelog

  • See CHANGELOG.md for release notes

License

  • See LICENSE for terms
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.9.3 127 8/19/2025
0.9.2 124 8/18/2025
0.9.1 122 8/18/2025
0.9.0 123 8/18/2025