RA.Utilities.Integrations
Version 10.2.1
ProxySettings is removed entirely. v10.2.0 had already removed the built-in proxy pipeline (ProxyMessageHandler, WithProxyFromSettings<TSettings>(...)) and kept ProxySettings as a configuration-only POCO; the class itself is now gone.
⚠️ Breaking Changes
ProxySettingsremoved: theRA.Utilities.Integrations.Options.ProxySettingsclass is deleted. Applications that kept it as a bindable options POCO must define their own proxy options type and wire the primary handler explicitly. TheUseProxyflag onIIntegrationSettings/BaseApiSettings<T>still exists but remains unconsumed by any package component. Migration:
// Before (v10.2.0)
public class MyApiSettings : BaseApiSettings<MyApiActions>
{
public ProxySettings? Proxy { get; set; }
}
// After (v10.2.1) — own options POCO
public sealed class ProxyOptions
{
[Required, Url] public string Address { get; set; } = default!;
public string? Username { get; set; }
public string? Password { get; set; }
public bool BypassProxyOnLocal { get; set; }
}
public class MyApiSettings : BaseApiSettings<MyApiActions>
{
public ProxyOptions? Proxy { get; set; }
}
// Wire the proxy yourself:
builder.Services.AddHttpClient("MyApi")
.ConfigurePrimaryHttpMessageHandler(_ => new HttpClientHandler
{
Proxy = new WebProxy(proxyOptions.Address),
UseProxy = true
});
Version 10.2.0
This release consolidates the registration API into C# 14 extension members grouped one class per receiver type, renames the logging infrastructure (RequestResponseLoggingHandler becomes LoggingHandler), and removes the built-in API key and proxy machinery.
⚠️ Breaking Changes
DependencyInjectionExtensionssplit intoServiceCollectionExtensionsandHttpClientBuilderExtensions: theIServiceCollectionmethods (AddHttpClientIntegration,AddScopedHttpMessageHandler<T>,AddTransientHttpMessageHandler<T>) now live inServiceCollectionExtensions, and theIHttpClientBuilderpipeline methods live inHttpClientBuilderExtensions. The namespace, method names, and signatures are unchanged — only code that references the class by name needs updating.
- var t = typeof(DependencyInjectionExtensions);
+ var t = typeof(ServiceCollectionExtensions); // or HttpClientBuilderExtensions
-
Pipeline methods renamed:
WithHttpLoggingHandler()→AddLoggingHandler()andWithInternalHeadersForwardingHandler()→AddInternalHeadersForwardingHandler(). -
RequestResponseLoggingHandlerrenamed toLoggingHandler: its constructor still takes only anILogger<LoggingHandler>; update manual constructions andAddScopedHttpMessageHandler<RequestResponseLoggingHandler>()registrations. -
HttpRequestMessageExtensionsrenamed toHttpRequestOptionsExtensions:GetClientIpAddress()call sites are unchanged; theToDictionary(...)helper was removed. -
API key support removed:
IApiKeySettings,ApiKeyAuthenticationHandler<TSettings>,WithApiKey(...), andWithApiKeyFromSettingsHandler<TSettings>()are gone. UseConfigureHttpClientfor a static key or a customDelegatingHandlerfor dynamic ones. -
Proxy support removed:
IProxySettings,ProxyMessageHandler, andWithProxyFromSettings<TSettings>(...)are gone.ProxySettingsremains as a configuration-only POCO; useConfigurePrimaryHttpMessageHandlerto route a client through a proxy. TheUseProxyflag onIIntegrationSettings/BaseApiSettings<T>is no longer consumed by any built-in component.
🔄 Behavior Changes
InternalHeadersForwardHandlerreads headers per request: instead of capturing theAuthorizationandx-request-idheaders once in the constructor (which could go stale when the pooled handler instance is reused), the handler now reads the current values fromIHttpContextAccessor.HttpContexton everySendAsync. No code changes are required.
📝 Improvements
- C# 14 extension members:
ServiceCollectionExtensions,HttpClientBuilderExtensions, andHttpRequestOptionsExtensionsdeclare their methods insideextension(...)blocks. Extension-method call sites keep compiling unchanged — only class-name references (typeof(...), static calls, reflection strings) need updating.
See the Migration Guide for detailed before/after examples.
Version 10.1.1
RequestResponseLoggingHandler is simplified and its slow-call logging made explicit: the handler now takes only an ILogger, and calls that exceed the warning threshold produce a dedicated Warning entry in addition to the Information request/response logs.
⚠️ Breaking Changes
RequestResponseLoggingHandlerconstructor simplified: theIHttpContextAccessorparameter was removed.
- public RequestResponseLoggingHandler(ILogger<RequestResponseLoggingHandler> logger, IHttpContextAccessor httpContextAccessor)
+ public RequestResponseLoggingHandler(ILogger<RequestResponseLoggingHandler> logger)
WithHttpLoggingHandler() handles the new signature automatically — only manual constructions/registrations need updating.
- Log templates no longer carry
RequestId/TraceIdentifier(viaRA.Utilities.Logging.Shared10.0.2): correlation now comes from the ambient log scope (LoggingConstants.XRequestId), e.g. the one created byLoggingMiddlewareor the SerilogRequestIdEnricher.
✨ Enhancements
- Dedicated slow-call warning: when a call exceeds the handler's warning threshold (35 seconds), an additional
Warningentry is written alongside theInformationresponse log.
_logger.LogInformation("HttpClient Response: {@ResponseDto}", responseDto);
+ if (stopwatch.Elapsed.TotalMilliseconds > _warningThresholdMilliseconds)
+ _logger.LogWarning("HttpClient call to {Method} {Url} took too long ({ElapsedMilliseconds} ms)", ...);
Version 10.1.0
This release overhauls the BaseHttpClient API with support for all four HTTP verbs and strongly-typed query string and header parameters, backed by a new Roslyn incremental source generator.
✨ New Features
-
Full HTTP Verb Coverage:
BaseHttpClientnow providesGetAsync,PostAsync,PutAsyncandDeleteAsync— each with a typed-response overload and a string overload — covering the complete CRUD surface for external APIs. -
Strongly-Typed Query String Parameters: Mark a
partialclass with[QueryParameters]and the source generator implementsIQueryStringRequestfor it, mapping each public property to a query string key-value pair. Null values are skipped,boolvalues are formatted astrue/false,DateTime/DateTimeOffsetvalues use the round-trip format, and collections are emitted as repeated keys. Override the emitted key per property with[QueryParameterName("...")]. -
Strongly-Typed Header Parameters: Mark a
partialclass with[HeaderParameters]and the generator implements the newIHeaderRequestcontract, mapping each public property to an HTTP header. Override the header name per property with[HeaderParameterName("...")], e.g.x-request-id. -
Compile-Time Code Generation: A new incremental Roslyn source generator, shipped inside the package as an analyzer, generates the parameter mappings at compile time — giving full IntelliSense and compile-time safety, with zero reflection.
-
Null-Safe Requests: Query and header parameters are optional; passing
nullbuilds a plain request instead of throwing. -
JSON Request Bodies:
PostAsyncandPutAsyncserialize request bodies as JSON (application/json; charset=utf-8) with camel-case property naming. -
Query String Utilities: The query string building logic is consolidated into the new
QueryUtilitiesclass, which replaces the oldDictionaryExtensions.ToQueryString(...)extension.
⚠️ Breaking Changes
IIntegrationSettingsno longer carriesMediaType/Encoding; JSON is now the fixed content type.BaseHttpClientmethods now acceptIHeaderRequest?instead ofDictionary<string, string>?for headers.- Typed-response overloads now return
Task<TResponse?>and yieldnullfor empty response bodies. AddOptionWithValidations(...)was removed fromDependencyInjectionExtensions; useAddHttpClientIntegrationfor validated integration settings.DictionaryExtensions.ToQueryString(...)was removed; useQueryUtilities.ToQueryString(QueryParams?)instead.- See the Migration Guide for detailed before/after examples.
🚀 Getting Started
using RA.Utilities.Integrations.Attributes;
[QueryParameters]
public partial class GetProductsQuery
{
[QueryParameterName("category_id")]
public int? CategoryId { get; init; }
}
[HeaderParameters]
public partial class RequestHeaders
{
[HeaderParameterName("x-request-id")]
public string? XCorrelationId { get; init; }
}
Product? product = await client.GetAsync<Product>(
"products",
new GetProductsQuery { CategoryId = 5 },
new RequestHeaders { XCorrelationId = "trace-1" });
await client.PostAsync<Product, Product>("products", product);
await client.PutAsync<Product, Product>($"products/{product.Id}", product);
await client.DeleteAsync("products/1");
Version 10.0.1
This release focuses on internal dependency updates and version synchronization within the RA.Utilities ecosystem.
✨ Improvements
- Ecosystem Alignment: Updated internal project references to
RA.Utilities.Core.ConstantsandRA.Utilities.Logging.Sharedto version 10.0.1. - Consistency: Synchronized the package version to maintain parity with the core components following the introduction of new semantic exceptions.
Version 10.0.0
Updated package version 10.0.9-rc (release candidate) to 10.0.0, indicating a transition to a stable release.
This change signifies that the project is no longer in the release candidate phase and is considered ready for production use, reflecting confidence in its stability and completeness.
Version 10.0.0-rc.2
This release modernizes the RA.Utilities.Integrations package, providing a robust and repeatable pattern for managing external API integrations.
It centralizes configuration, simplifies registration, and improves resilience with built-in retry policies.
✨ New Features
- Standardized Configuration: Centralizes HTTP client settings (Base URL, timeouts, headers) in
appsettings.jsonusing theHttpClientSettingsbase class. - Simplified Registration: Introduced the
AddIntegrationHttpClient<TClient, TSettings>extension method to register a typedHttpClient, bind its configuration, and apply default policies with a single line of code. - Built-in Resilience: Includes a default transient error handling policy (retry with exponential backoff) using Polly, improving the reliability of external API calls.
- Promotes Best Practices: Encourages the use of typed
HttpClients viaIHttpClientFactory, which provides better compile-time safety, intellisense, and connection management. - Updated Documentation: The
README.mdhas been updated to provide a clear, step-by-step guide for setting up a typed client, from configuration to implementation.