Lyo.Config.Api.Client 1.0.1

dotnet add package Lyo.Config.Api.Client --version 1.0.1
                    
NuGet\Install-Package Lyo.Config.Api.Client -Version 1.0.1
                    
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="Lyo.Config.Api.Client" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Lyo.Config.Api.Client" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Lyo.Config.Api.Client" />
                    
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 Lyo.Config.Api.Client --version 1.0.1
                    
#r "nuget: Lyo.Config.Api.Client, 1.0.1"
                    
#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 Lyo.Config.Api.Client@1.0.1
                    
#: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=Lyo.Config.Api.Client&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Lyo.Config.Api.Client&version=1.0.1
                    
Install as a Cake Tool

Lyo.Config.Api.Client

Typed HTTP client for the central Lyo.Config.Apiconditional app-config reads with If-None-Match / ?version polling, an optional X-Api-Key header, and a single DI extension. The client deliberately exposes only the resolve route (/api/config/{appKind}/{appId}); the management API ( /manage/...) is intended for operator tools, not service callers.

References Lyo.Config.Api.Models for ConfigResolveConditionalResult / ConfigResolveOutcome, and Lyo.Config for AppConfigEntity slug validation and ResolvedConfigRecord. For a polling host that publishes config via IOptionsMonitor<T>, see Lyo.Config.Api.Hosting.

Features

  • Binds ConfigApiClientOptions from the section named by configSectionName (default "ConfigApi" via ConfigApiClientOptions.SectionName); the section is optional.
  • Registers IOptions<ConfigApiClientOptions> (only when not already present).
  • Calls services.AddHttpClient<IConfigApiClient, ConfigApiClient>(...) and returns the IHttpClientBuilder so callers can chain .AddHttpMessageHandler<…>() / .AddPolicyHandler(…) or replace the primary handler.
  • Wires the typed client:
  • BaseAddress = "{BaseUrl}/" when BaseUrl is non-empty.
  • Adds the X-Api-Key: <ApiKey> default request header when ApiKey is non-empty.
  • Appends gzip / deflate / br to Accept-Encoding based on AcceptEncodings.
  • Enables HttpClientHandler.AutomaticDecompression from AcceptEncodings when EnableAutoResponseDecompression == true.

Examples

Register services

using Lyo.Config.Api.Client;

services.AddConfigApiClientFromConfiguration(configuration);
// Optional override:
// services.AddConfigApiClientFromConfiguration(configuration, configSectionName: "MyConfigApi");

appsettings

{
  "ConfigApi": {
    "BaseUrl": "https://config.internal.example/",
    "ApiKey": "optional-shared-secret",
    "PollInterval": "00:01:30",
    "EnsureStatusCode": true,
    "AcceptEncodings": ["gzip", "br"],
    "EnableAutoResponseDecompression": true
  }
}

Registration

  • Binds ConfigApiClientOptions from the section named by configSectionName (default "ConfigApi" via ConfigApiClientOptions.SectionName); the section is optional.
  • Registers IOptions<ConfigApiClientOptions> (only when not already present).
  • Calls services.AddHttpClient<IConfigApiClient, ConfigApiClient>(...) and returns the IHttpClientBuilder so callers can chain .AddHttpMessageHandler<…>() / .AddPolicyHandler(…) or replace the primary handler.
  • Wires the typed client:
  • BaseAddress = "{BaseUrl}/" when BaseUrl is non-empty.
  • Adds the X-Api-Key: <ApiKey> default request header when ApiKey is non-empty.
  • Appends gzip / deflate / br to Accept-Encoding based on AcceptEncodings.
  • Enables HttpClientHandler.AutomaticDecompression from AcceptEncodings when EnableAutoResponseDecompression == true.

ConfigApiClientOptions

Section: ConfigApi by default. Inherits from Lyo.Api.Client.ApiClientOptions.

Property Default Purpose
BaseUrl null Base URL of the Config API host. Trimmed and suffixed with /.
ApiKey null When set, forwarded as X-Api-Key. The server only enforces it if ConfigApiSecurity.RequireApiKey == true (see Config.Api README).
PollInterval (TimeSpan?) null Advisory only. Not consumed by ConfigApiClient; bring your own scheduler, or pass an explicit TimeSpan to ConfigPolling.PollUntilChangedAsync.
EnsureStatusCode (bool) true When true, non-success responses (other than 304 Not Modified) call EnsureSuccessStatusCode() and throw HttpRequestException. When false, ResolveForAppAsync returns a ConfigResolveConditionalResult with Outcome = Failed and a populated Failure so the caller can inspect the status code without an exception.
AcceptEncodings ["gzip", "deflate", "br"] Advertised encodings; only gzip / deflate / br are honored (and br requires a non-netstandard2.0 target).
EnableAutoResponseDecompression true Toggles the matching HttpClientHandler.AutomaticDecompression flags.
RequestCompression ApiRequestCompressionType.None Inherited request-body compression — unused by the resolve route (GET / HEAD).
RequestCompressionMinBytes 1024 Inherited threshold for request-body compression.

IConfigApiClient

public interface IConfigApiClient : IApiClient
{
    Task<ConfigResolveConditionalResult> ResolveForAppAsync(
        string appKind,
        string appId,
        string? ifNoneMatch = null,
        string? version = null,
        bool headOnly = false,
        CancellationToken ct = default);
}

The interface inherits from Lyo.Api.Client.IApiClient, so callers receive the generic CRUD / Query helpers exposed by ApiClient on the same instance. Only the resolve method is added by this client.

IConfigApiClientResolveForAppAsync parameters

Parameter Required Description
appKind yes Process taxonomy slug (e.g. gateway, worker). Must match AppConfigEntity slug rules; otherwise an ArgumentException is thrown before the request is sent. URL-encoded into the path.
appId yes Instance id slug (e.g. prod-west, a GUID). Same slug rules; URL-encoded.
ifNoneMatch no Previous ETag (quoted or bare hex — the server normalizes weak prefixes / quotes). Sent verbatim as If-None-Match. When the server replies 304 Not Modified, the returned ConfigResolveConditionalResult.ETag falls back to this value.
version no Alternate fingerprint comparison sent as ?version=<bare-hex>. Empty / whitespace values are omitted. May be used together with If-None-Match; either match yields 304.
headOnly no When true, issues HEAD instead of GET and returns Outcome = Ok with Resolved = null on success. The server also responds 200 with no body for HEAD.
ct no Cancellation. Honored on SendAsync and JSON deserialization on modern targets.

IConfigApiClientEnsureStatusCode behavior in detail

  • HTTP 2xxConfigResolveConditionalResult { Outcome = Ok, ETag, Resolved }. If the server returns 204 No Content or the client used headOnly = true, Resolved is null.
  • HTTP 304 Not ModifiedConfigResolveConditionalResult { Outcome = NotModified, ETag = <server etag or ifNoneMatch fallback>, Resolved = null }. Always returned — even when EnsureStatusCode == true, because 304 is the expected polling response.
  • HTTP 4xx/5xx:
  • When EnsureStatusCode == true (default): response.EnsureSuccessStatusCode() is called and the resulting HttpRequestException propagates to the caller.
  • When EnsureStatusCode == false: the method returns ConfigResolveConditionalResult { Outcome = Failed, ETag, Resolved = null, Failure = (StatusCode, ReasonPhrase) } so callers can branch on the status code without using exceptions for control flow. Use this mode when, for example, you want to treat 409 Conflict (validation failure on the server) as a recoverable signal rather than a crash.

IConfigApiClient — Slug validation

appKind and appId are checked with AppConfigEntity.TryCreate(...) before any HTTP request. Invalid slugs throw ArgumentException with the same message the API would return as 400 Bad Request. There is no separate per-method validation toggle.

ConfigPolling.PollUntilChangedAsync

Helper for long-running pollers that simply want the next changed ResolvedConfigRecord:

var merged = await ConfigPolling.PollUntilChangedAsync(
    configClient,
    appKind: "api",
    appId: "checkout",
    ifNoneMatch: null,
    delayWhenNotModified: TimeSpan.FromSeconds(15),
    cancellationToken: ct);

Loop semantics:

Server outcome Action
Ok with Resolved Return the payload immediately.
NotModified Await delayWhenNotModified (cancellation-aware), reuse the latest ETag, and loop.
Failed Throw InvalidOperationException carrying the status code / reason phrase from Failure.

OperationHelpers.ThrowIfNull guards against a server returning Ok with no body; treat that as a contract bug.

Dependencies

Generated from ProjectReference / PackageReference (same model as docs/Lyo.ProjectGraph.html).

  • Lyo.Api.Client — (direct, lyo)
  • Lyo.Config.Api.Models — (direct, lyo)
  • Microsoft.Extensions.Http 10.0.5 — (direct, microsoft)
  • Microsoft.Extensions.Options.ConfigurationExtensions 10.0.5 — (direct, microsoft)
  • Lyo.Api.Models — (transitive, lyo)
  • Lyo.Common — (transitive, lyo)
  • Lyo.Config — (transitive, lyo)
  • Lyo.DateAndTime — (transitive, lyo)
  • Lyo.Diagnostic — (transitive, lyo)
  • Lyo.EntityReference.Models — (transitive, lyo)
  • Lyo.Exceptions — (transitive, lyo)
  • Lyo.Hashing — (transitive, lyo)
  • Lyo.PackageMetadata — (transitive, lyo)
  • Lyo.Query.Models — (transitive, lyo)
  • Microsoft.Extensions.DependencyInjection.Abstractions 10.0.5 — (transitive, microsoft)
  • Microsoft.Extensions.Logging.Abstractions 10.0.5 — (transitive, microsoft)
  • System.IO.Hashing 10.0.5 — (transitive, microsoft, net10.0)
  • System.Memory 4.6.3 — (transitive, microsoft, netstandard2.0)
  • System.Text.Json 10.0.5 — (transitive, microsoft, netstandard2.0)
  • System.Threading.Tasks.Extensions 4.6.3 — (transitive, microsoft)
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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 was computed.  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 is compatible.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on Lyo.Config.Api.Client:

Package Downloads
Lyo.Config.Api.Hosting

IHostedService polling + IOptionsMonitor binding from central Lyo Config API.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 27 8/18/2026
1.0.0 88 8/16/2026