FluentHttpBuilder 1.0.4

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

FluentHttpBuilder

A fluent, type-safe HTTP request builder for .NET 🚀

✨ Features

  • 🎯 Fluent API - Easy to read and write
  • 🔒 Type-Safe - Compiler protects you from mistakes
  • 🌐 All HTTP Methods - GET, POST, PUT, DELETE, PATCH
  • 📦 JSON Support - Automatic serialization/deserialization
  • 🔑 Authentication - Bearer tokens and custom headers
  • ⚙️ Configurable - Timeout, headers, and more
  • Error Handling - Graceful error responses
  • 🛡️ Circuit Breaker - Built-in resiliency, zero dependencies

📦 Installation

dotnet add package FluentHttpBuilder

Or via Package Manager:

Install-Package FluentHttpBuilder

🚀 Quick Start

Simple GET Request

using FluentHttpBuilder;

var response = await HttpRequestBuilder.Create()
    .WithUrl("https://jsonplaceholder.typicode.com/posts/1")
    .Get()
    .SendAsync();

Console.WriteLine($"Status: {response.StatusCode}");
Console.WriteLine($"Content: {response.Content}");

POST Request with JSON

var newPost = new { 
    title = "My Post", 
    body = "This is the content", 
    userId = 1 
};

var response = await HttpRequestBuilder.Create()
    .WithUrl("https://api.example.com/posts")
    .Post()
    .WithJsonBody(newPost)
    .SendAsync();

if (response.IsSuccess)
{
    Console.WriteLine("Post created successfully!");
}

Authenticated Request

var response = await HttpRequestBuilder.Create()
    .WithUrl("https://api.example.com/users")
    .Get()
    .WithBearerToken("your-access-token")
    .SendAsync();

Custom Headers & Timeout

var response = await HttpRequestBuilder.Create()
    .WithUrl("https://api.example.com/data")
    .Get()
    .AddHeader("X-Custom-Header", "value")
    .AddHeader("X-API-Version", "2.0")
    .WithTimeout(60) // 60 seconds
    .SendAsync();

🛡️ Circuit Breaker

Protect your app from cascading failures caused by unreliable downstream services. The circuit breaker detects repeated failures and short-circuits calls before they hit the network, giving the failing service time to recover.

States

State Behavior
🟢 Closed Normal — requests flow, failures are tracked
🔴 Open Circuit tripped — requests are blocked immediately
🟡 HalfOpen One probe request allowed to test recovery

Usage

using FluentHttpBuilder.Resilience;

var request = HttpRequestBuilder.Create()
    .WithUrl("https://api.example.com/data")
    .Get()
    .WithTimeout(10)
    .WithCircuitBreaker(options =>
    {
        // Trip the breaker after 3 consecutive failures
        options.FailureThreshold = 3;

        // Keep the circuit open for 60 seconds before retrying
        options.OpenDuration = TimeSpan.FromSeconds(60);

        // Log every state transition
        options.OnStateChanged = (from, to) =>
            Console.WriteLine($"[CircuitBreaker] {from} → {to}");
    });

try
{
    var response = await request.SendAsync();

    if (response.IsSuccess)
        Console.WriteLine(response.Content);
}
catch (CircuitBreakerOpenException ex)
{
    // Circuit is open — fail fast, no network call was made
    Console.WriteLine($"Service unavailable: {ex.Message}");
    Console.WriteLine($"Current State: {ex.State}");

    // Implement fallback logic here (e.g. return cached data)
}

Configuration Options

Option Type Default Description
FailureThreshold int 5 Consecutive failures before opening the circuit
OpenDuration TimeSpan 30s How long the circuit stays open before trying again
FailureStatusCodes IReadOnlyList<HttpStatusCode> 500, 502, 503, 504 HTTP status codes treated as failures
OnStateChanged Action<State, State> null Callback fired on every state transition

How it works

         failures >= threshold
Closed ──────────────────────► Open
  ▲                               │
  │    probe succeeds             │ openDuration elapsed
  └──────────────── HalfOpen ◄───┘
                       │
                       │ probe fails
                       └──────────► Open

Zero dependencies — the circuit breaker is built from scratch using pure .NET. No Polly or any third-party packages required.


📚 API Reference

HTTP Methods

Method Description
Get() HTTP GET request
Post() HTTP POST request (requires body)
Put() HTTP PUT request (requires body)
Delete() HTTP DELETE request
Patch() HTTP PATCH request (requires body)

Configuration Methods

Method Description
WithUrl(string) Set the request URL (required)
WithJsonBody<T>(T) Add JSON body (auto-serialized)
WithBody(string, contentType) Add custom body
WithBearerToken(string) Add Bearer authentication
AddHeader(key, value) Add custom header
WithTimeout(int) Set timeout in seconds
WithCircuitBreaker(options) Enable circuit breaker resiliency
SendAsync() Execute the request
Build() Build request without executing

🎯 Advanced Examples

PUT Request

var updateData = new { 
    title = "Updated Title",
    completed = true 
};

var response = await HttpRequestBuilder.Create()
    .WithUrl("https://api.example.com/posts/1")
    .Put()
    .WithJsonBody(updateData)
    .WithBearerToken("token")
    .SendAsync();

DELETE Request

var response = await HttpRequestBuilder.Create()
    .WithUrl("https://api.example.com/posts/1")
    .Delete()
    .WithBearerToken("token")
    .SendAsync();

Console.WriteLine(response.IsSuccess ? "Deleted!" : "Failed");

Build Without Executing (for testing)

var request = HttpRequestBuilder.Create()
    .WithUrl("https://api.example.com/data")
    .Post()
    .WithJsonBody(new { test = "data" })
    .Build();

Console.WriteLine($"Will send {request.Method} to {request.Url}");
Console.WriteLine($"Body: {request.Body}");

🔧 Response Object

public class FluentHttpResponse
{
    public int StatusCode { get; init; }                      // HTTP status code (200, 404, etc.)
    public string Content { get; init; }                      // Response body as string
    public bool IsSuccess { get; init; }                      // True if 2xx status
    public Dictionary<string, string> Headers { get; init; }  // Response headers
}

💡 Best Practices

  1. Reuse HttpClient - The builder uses a static HttpClient internally
  2. Handle Errors - Always check response.IsSuccess
  3. Set Timeouts - For slow APIs, increase timeout
  4. Use Async/Await - All methods are async
  5. Use Circuit Breaker - For any external API calls in production

⚠️ Error Handling

var response = await HttpRequestBuilder.Create()
    .WithUrl("https://api.example.com/data")
    .Get()
    .SendAsync();

if (!response.IsSuccess)
{
    Console.WriteLine($"Error: {response.StatusCode}");
    Console.WriteLine($"Message: {response.Content}");
}

🤝 Contributing

Contributions are welcome! Feel free to:

  • Report bugs
  • Suggest features
  • Submit pull requests

📄 License

MIT License - feel free to use in your projects!

📞 Support

For questions or support, please open an issue on GitHub.


Made with ❤️ for the .NET community

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 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 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.
  • net8.0

    • No dependencies.

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
1.0.4 57 4/8/2026
1.0.3 72 3/27/2026
1.0.2 61 3/27/2026
1.0.1 60 3/27/2026
1.0.0 58 3/27/2026