Features: - Complete .NET client SDK for LittleShop API - JWT authentication with automatic token management - Catalog service for products and categories - Order service with payment creation - Retry policies using Polly for resilience - Error handling middleware - Dependency injection support - Comprehensive documentation and examples SDK Components: - Authentication service with token refresh - Strongly-typed models for all API responses - HTTP handlers for retry and error handling - Extension methods for easy DI registration - Example console application demonstrating usage Test Updates: - Fixed test compilation errors - Updated test data builders for new models - Corrected service constructor dependencies - Fixed enum value changes (PaymentStatus, OrderStatus) Documentation: - Complete project README with features and usage - Client SDK README with detailed examples - API endpoint documentation - Security considerations - Deployment guidelines Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
39 lines
1.4 KiB
C#
39 lines
1.4 KiB
C#
using System.Net;
|
|
using Microsoft.Extensions.Logging;
|
|
using Polly;
|
|
using Polly.Extensions.Http;
|
|
|
|
namespace LittleShop.Client.Http;
|
|
|
|
public class RetryPolicyHandler : DelegatingHandler
|
|
{
|
|
private readonly ILogger<RetryPolicyHandler> _logger;
|
|
private readonly IAsyncPolicy<HttpResponseMessage> _retryPolicy;
|
|
|
|
public RetryPolicyHandler(ILogger<RetryPolicyHandler> logger, int maxRetryAttempts = 3)
|
|
{
|
|
_logger = logger;
|
|
|
|
_retryPolicy = HttpPolicyExtensions
|
|
.HandleTransientHttpError()
|
|
.OrResult(msg => !msg.IsSuccessStatusCode && msg.StatusCode != HttpStatusCode.Unauthorized)
|
|
.WaitAndRetryAsync(
|
|
maxRetryAttempts,
|
|
retryAttempt => TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)),
|
|
onRetry: (outcome, timespan, retryCount, context) =>
|
|
{
|
|
var reason = outcome.Result?.StatusCode.ToString() ?? outcome.Exception?.Message;
|
|
_logger.LogWarning(
|
|
"Retry {RetryCount} after {TimeSpan}ms due to: {Reason}",
|
|
retryCount, timespan.TotalMilliseconds, reason);
|
|
});
|
|
}
|
|
|
|
protected override async Task<HttpResponseMessage> SendAsync(
|
|
HttpRequestMessage request,
|
|
CancellationToken cancellationToken)
|
|
{
|
|
return await _retryPolicy.ExecuteAsync(async () =>
|
|
await base.SendAsync(request, cancellationToken));
|
|
}
|
|
} |