Introduction
Flurl treats URLs as mutable objects and HTTP calls as natural extensions of URL construction. Instead of juggling UriBuilder, HttpClient, and StringContent separately, you chain everything into one readable expression. Its test infrastructure lets you fake HTTP responses without touching a real server.
What Flurl Does
- Builds URLs fluently with path segments, query parameters, and fragment handling
- Makes GET, POST, PUT, PATCH, and DELETE requests as extension methods on URL strings
- Deserializes JSON, receives streams, and uploads multipart forms inline
- Provides a fake HTTP layer for unit testing without mocking HttpClient
- Manages HttpClient instances per host with automatic connection pooling
Architecture Overview
Flurl consists of two packages. Flurl (core) is a URL builder that extends string and Uri with chainable methods. Flurl.Http adds an HTTP layer built on HttpClient with a FlurlClient that manages per-host connection pooling via IFlurlClientCache. Configuration flows through a settings object at global, client, or per-request scope. The testing module provides HttpTest which intercepts requests and returns fake responses.
Self-Hosting & Configuration
- Install
Flurl.Httpvia NuGet (includes the core Flurl URL builder) - Configure defaults globally:
FlurlHttp.Clients.WithDefaults(s => s.WithTimeout(30)) - Register named or typed clients with
IFlurlClientCachefor DI-friendly usage - Override JSON serialization with System.Text.Json or Newtonsoft.Json
- Use
HttpTestin tests to intercept and assert HTTP calls without network access
Key Features
- Chainable URL construction that reads like a sentence
- Automatic JSON serialization and deserialization on requests and responses
- Per-host HttpClient management to avoid socket exhaustion
- Built-in testability:
HttpTestintercepts all Flurl calls in its scope - Configurable retry, timeout, redirect, and error handling policies
Comparison with Similar Tools
- HttpClient — low-level; Flurl wraps it with a fluent API and manages pooling for you
- RestSharp — similar convenience but no URL builder; Flurl's fluent chaining is more concise
- Refit — interface-to-API mapper; Flurl is better for ad-hoc or dynamic URL construction
- HTTPX (Python) — Python's fluent HTTP client; Flurl brings the same ergonomics to .NET
- axios (JS) — promise-based HTTP; Flurl's chaining achieves a similar feel in C#
FAQ
Q: Does Flurl manage HttpClient lifecycle automatically? A: Yes. Flurl pools HttpClient instances per host URL by default, preventing socket exhaustion without manual management.
Q: How do I test code that uses Flurl?
A: Wrap your test in using var httpTest = new HttpTest(); and call httpTest.RespondWithJson(data). All Flurl calls within that scope are intercepted.
Q: Can I use Flurl with dependency injection?
A: Yes. Register IFlurlClientCache as a singleton and inject named or typed IFlurlClient instances into your services.
Q: Does Flurl support file uploads?
A: Yes. Use .PostMultipartAsync(mp => mp.AddFile("file", stream, "name.pdf")) for multipart form uploads.