Zyga.SeriRestClient
0.1.0
dotnet add package Zyga.SeriRestClient --version 0.1.0
NuGet\Install-Package Zyga.SeriRestClient -Version 0.1.0
<PackageReference Include="Zyga.SeriRestClient" Version="0.1.0" />
<PackageVersion Include="Zyga.SeriRestClient" Version="0.1.0" />
<PackageReference Include="Zyga.SeriRestClient" />
paket add Zyga.SeriRestClient --version 0.1.0
#r "nuget: Zyga.SeriRestClient, 0.1.0"
#:package Zyga.SeriRestClient@0.1.0
#addin nuget:?package=Zyga.SeriRestClient&version=0.1.0
#tool nuget:?package=Zyga.SeriRestClient&version=0.1.0
Zyga.SeriRestClient
A logging-enhanced REST client library that wraps RestSharp with integrated Serilog logging capabilities for comprehensive HTTP request and response logging.
Features
- 🔍 Comprehensive HTTP Logging - Automatically logs all request and response details
- 📝 Pretty Formatting - JSON and XML payloads are automatically formatted for readability
- 🍪 Cookie Tracking - Logs all cookies sent and received
- ⚡ Performance Metrics - Records request duration
- 🎯 Keyed Services - Supports multiple REST clients with different configurations
- 🔌 DI Integration - Easy integration with Microsoft.Extensions.DependencyInjection
Install
dotnet add package Zyga.SeriRestClient
Targets .NET 8, .NET 9 and .NET 10.
Quick Start
1. Register the Service
using Zyga.SeriRestClient;
var builder = WebApplication.CreateBuilder(args);
// Add Serilog
builder.Host.UseSerilog((context, configuration) =>
configuration.ReadFrom.Configuration(context.Configuration));
// Register the client with a keyed service
builder.Services.AddSeriRestClient(
"MyApi",
(sp, key) => new RestClientOptions("https://api.example.com")
{
ThrowOnAnyError = false,
Timeout = TimeSpan.FromSeconds(30)
}
);
2. Inject and Use
using Microsoft.AspNetCore.Mvc;
using RestSharp;
using Zyga.SeriRestClient;
[ApiController]
[Route("[controller]")]
public class UsersController : ControllerBase
{
private readonly ILoggingRestClient _client;
public UsersController([FromKeyedServices("MyApi")] ILoggingRestClient client)
{
_client = client;
}
[HttpGet("{id}")]
public IActionResult GetUser(int id)
{
var request = new RestRequest("users/{id}");
request.AddUrlSegment("id", id);
var response = _client.LogRequest<User>(request, Method.Get);
if (response.IsSuccessful)
return Ok(response.Data);
return StatusCode((int)response.StatusCode, response.ErrorMessage);
}
}
Logging Output
The client logs detailed information at different levels:
- Debug: Request/response details, headers, cookies, body
- Warning: Non-success status codes with successful HTTP completion
- Error: Failed HTTP requests
Example log output:
[DBG] REQUEST [Get][https://api.example.com/users/123]
[DBG] [QueryParameter]->[limit]: [10]
[DBG] [Cookie]->[session]: [abc123]
[DBG] RESPONSE [OK]
[DBG] [Payload]: {
"id": 123,
"name": "John Doe",
"email": "john@example.com"
}
[DBG] REQUEST -> RESPONSE: 00:00:01.2345678
Multiple REST Clients
Register multiple clients with different configurations:
services.AddSeriRestClient(
"UsersApi",
(sp, key) => new RestClientOptions("https://users.api.example.com"));
services.AddSeriRestClient(
"OrdersApi",
(sp, key) => new RestClientOptions("https://orders.api.example.com"));
// Inject specific clients
public MyService(
[FromKeyedServices("UsersApi")] ILoggingRestClient usersClient,
[FromKeyedServices("OrdersApi")] ILoggingRestClient ordersClient)
{
// Use different clients for different APIs
}
Configuration
Accessing Base RestClient Methods
If you need access to the full RestSharp RestClient API, inject the concrete type instead of the interface:
public MyService([FromKeyedServices("MyApi")] LoggingRestClient client)
{
// Access all RestClient methods
var response = client.ExecuteAsync(request);
}
Note that the interface and concrete-type registrations are separate DI entries with separate factories — resolving both under the same key in one scope gives you two distinct client instances, not the same one seen through two types.
Customizing Log Levels
Each client's logger is enriched with a SourceContext of the exact form
"REST: {BaseUrl}" — the literal text REST: followed by the client's base URL,
including the trailing slash RestClientOptions.BaseUrl adds because it is a Uri.
A targeted override must be set in code, not appsettings.json. Two things rule
out a JSON override: Serilog only matches a MinimumLevel.Override key as an exact or
dot-segmented prefix of SourceContext, and REST: {BaseUrl} has no dot segment after
REST — so "SeriRestClient", "REST" and "REST:" all match nothing. And even the
complete, correct string can't be written in appsettings.json, because it contains a
colon, which Microsoft.Extensions.Configuration treats as its own section separator
and splits before Serilog ever sees the key.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
// The key must be the client's complete SourceContext: the literal text "REST: "
// followed by the base URL, including the trailing slash. One entry per registered client.
.MinimumLevel.Override("REST: https://api.example.com/", LogEventLevel.Debug)
.WriteTo.Console()
.CreateLogger();
If your configuration lives entirely in appsettings.json, you can raise the global
minimum level instead — this affects every logger in the process, not just this client:
{
"Serilog": {
"MinimumLevel": { "Default": "Debug" }
}
}
Requirements
- .NET 8, .NET 9, or .NET 10
- RestSharp 114.0.0+
- Serilog 4.4.0+
Documentation
See CLAUDE.md for architecture notes and logging internals.
Contributing
Issues and pull requests are welcome. See CONTRIBUTING.md.
License
Version
This package uses MinVer for semantic versioning,
derived from v-prefixed git tags (e.g. v1.2.3). There is no <Version> element
anywhere in the source — maintainers cut a release by pushing a tag.
| Product | Versions 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 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. |
-
net10.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.11)
- Newtonsoft.Json (>= 13.0.4)
- RestSharp (>= 114.0.0)
- Serilog (>= 4.4.0)
-
net8.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.11)
- Newtonsoft.Json (>= 13.0.4)
- RestSharp (>= 114.0.0)
- Serilog (>= 4.4.0)
-
net9.0
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.11)
- Newtonsoft.Json (>= 13.0.4)
- RestSharp (>= 114.0.0)
- Serilog (>= 4.4.0)
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.1.0 | 31 | 10/5/2026 |