ServiceStack
5 minute read
is a versatile and feature-rich framework that includes powerful HTTP client libraries for consuming REST APIs. While ServiceStack is primarily known as a complete web service framework, its client libraries can be used independently with any REST API.
ServiceStack’s HTTP client offerings are part of a broader ecosystem and come in two main variants:
- ServiceStack.HttpClient - A strongly-typed client with built-in serialization and comprehensive features
- HTTP Utils - A lightweight, string-based fluent API for quick and simple HTTP requests
These client libraries provide multiple approaches to API consumption, from simple one-liners to sophisticated typed clients with advanced features.
Info | Link |
---|---|
License | Free for OSS / Commercial for Business |
Downloads | |
Latest Version | |
Issues | |
Contributors |
Key Features
ServiceStack’s HTTP client libraries offer several advantages:
- Multiple serialization formats - Support for JSON, XML, CSV, MessagePack, Protocol Buffers and more
- Request/response filters - Intercept and modify requests and responses
- Automatic error handling - Detailed error responses with strong typing
- Authentication support - Built-in support for various authentication methods
- Timeout and retry policies - Configurable timeout settings and automatic retries
- Streaming support - Efficient handling of large responses
- Caching - Built-in response caching mechanisms
- Metrics and logging - Detailed request/response logging and performance metrics
ServiceStack.HttpClient
ServiceStack’s JsonHttpClient
(and related clients) provide a strongly-typed approach to consuming REST APIs with built-in serialization and deserialization. This is the recommended approach for most applications, especially when working with complex APIs.
Basic Usage
// Create a client with base URL
IServiceClient client = new JsonHttpClient("https://api.example.com");
// Get single task
TaskApiModel? task = await client.GetAsync<TaskApiModel?>("tasks/123");
// Get all tasks
List<TaskApiModel> tasks = await client.GetAsync<List<TaskApiModel>>("tasks");
// Add new task
TaskApiCreateModel newTask = new TaskApiCreateModel { Title = "Buy flowers" };
TaskApiModel addedTask = await client.PostAsync<TaskApiModel>("tasks", newTask);
// Update task
TaskApiUpdateModel updateModel = new TaskApiUpdateModel { Title = "Buy roses instead" };
await client.PutAsync<TaskApiModel>("tasks/123", updateModel);
// Delete task
await client.DeleteAsync<object>("tasks/123");
Advanced Features
ServiceStack’s HTTP client libraries offer several advanced capabilities:
Authentication
// Basic authentication
client.SetCredentials("username", "password");
// Bearer token authentication
client.BearerToken = "your-oauth-token";
// API key in header
client.Headers["X-API-Key"] = "your-api-key";
Request Filters
// Add global request filter
client.RequestFilter = req => {
req.Headers["Custom-Header"] = "CustomValue";
Console.WriteLine($"Requesting: {req.RequestUri}");
};
// Add global response filter
client.ResponseFilter = (req, res) => {
Console.WriteLine($"Response status: {res.StatusCode}");
};
Timeout and Retry Configuration
// Set timeout
client.Timeout = TimeSpan.FromSeconds(30);
// Configure retries
client.RetryCount = 3;
client.RetryOnAny = true;
The major advantages of ServiceStack’s HTTP client include its integration with the broader ServiceStack ecosystem, comprehensive feature set, and excellent performance characteristics.
ServiceStack.HttpUtils
ServiceStack’s HTTP Utils provide a lightweight, string-based approach to making HTTP requests with a fluent API. These utilities are particularly useful for quick, one-off API calls or when working with APIs that don’t warrant creating a full client implementation.
Basic Usage
// Get single task - two-step approach with manual deserialization
string taskResponse = await "https://api.example.com/tasks/123".GetJsonFromUrlAsync();
TaskApiModel? task = taskResponse.FromJson<TaskApiModel?>();
// Get all tasks
string tasksResponse = await "https://api.example.com/tasks".GetJsonFromUrlAsync();
List<TaskApiModel> tasks = tasksResponse.FromJson<List<TaskApiModel>>();
// Add new task
TaskApiCreateModel newTask = new TaskApiCreateModel { Title = "Buy flowers" };
string addedTaskResponse = await "https://api.example.com/tasks".PostJsonToUrlAsync(newTask);
TaskApiModel addedTask = addedTaskResponse.FromJson<TaskApiModel>();
// Update task
TaskApiUpdateModel updateModel = new TaskApiUpdateModel { Title = "Buy roses instead" };
await $"https://api.example.com/tasks/123".PutJsonToUrlAsync(updateModel);
// Delete task
await $"https://api.example.com/tasks/123".DeleteFromUrlAsync();
Simplified Approach with Combined Methods
ServiceStack also offers combined methods that handle both HTTP requests and deserialization in one step:
// Get single task with automatic deserialization
TaskApiModel? task = await "https://api.example.com/tasks/123".GetFromJsonAsync<TaskApiModel?>();
// Get all tasks
List<TaskApiModel> tasks = await "https://api.example.com/tasks".GetFromJsonAsync<List<TaskApiModel>>();
// Add new task
TaskApiCreateModel newTask = new TaskApiCreateModel { Title = "Buy flowers" };
TaskApiModel addedTask = await "https://api.example.com/tasks".PostJsonToUrlAsync(newTask).FromJson<TaskApiModel>();
Customizing Requests
// Add headers
var task = await "https://api.example.com/tasks/123"
.WithHeader("Authorization", "Bearer token")
.WithHeader("Accept-Language", "en-US")
.GetFromJsonAsync<TaskApiModel?>();
// Configure timeout
var tasks = await "https://api.example.com/tasks"
.WithTimeout(TimeSpan.FromSeconds(30))
.GetFromJsonAsync<List<TaskApiModel>>();
While HTTP Utils provide great flexibility and simplicity, they lack some of the more advanced features found in the full ServiceStack client. The main trade-offs include:
- Manual serialization/deserialization steps (in the basic approach)
- Less built-in error handling
- Fewer configuration options
- Limited type safety compared to the strongly-typed client
ServiceStack.Text
A key component that powers ServiceStack’s HTTP clients is the high-performance ServiceStack.Text
library, which provides:
- Fast JSON, JSV, and CSV serialization/deserialization
- Support for custom serialization
- Dynamic object support
- Flexible type conversion utilities
This library can be used independently and is worth considering even when not using the rest of ServiceStack.
// Serialize an object to JSON
string json = myObject.ToJson();
// Deserialize from JSON
MyType result = json.FromJson<MyType>();
// Convert between types
int number = "42".To<int>();
Integration with Dependency Injection
ServiceStack HTTP clients integrate well with dependency injection frameworks:
// Register in ASP.NET Core
services.AddSingleton<IServiceClient>(c =>
new JsonServiceClient("https://api.example.com") {
RequestFilter = req => req.Headers["X-API-Key"] = "api-key"
});
// Inject into your services
public class TaskService
{
private readonly IServiceClient _client;
public TaskService(IServiceClient client)
{
_client = client;
}
public Task<List<TaskApiModel>> GetAllTasksAsync() =>
_client.GetAsync<List<TaskApiModel>>("tasks");
}
Comparison
- Comprehensive feature set with support for multiple serialization formats
- Excellent performance with minimal overhead
- Built-in support for authentication, caching, and error handling
- Flexible with both high-level and low-level APIs (HttpClient and HttpUtils)
- Well-documented with extensive examples
- Active development and community support
- Commercial licensing required for business use beyond free quotas
- Learning curve slightly steeper than some alternatives
- Part of a larger framework which may be overkill if you only need HTTP client functionality
- Some advanced features require additional ServiceStack packages
When to Choose ServiceStack
ServiceStack HTTP clients are particularly well-suited for:
- Applications already using other ServiceStack components
- Projects requiring high-performance API consumption
- Scenarios needing support for multiple serialization formats
- Applications with complex authentication requirements
- Teams familiar with the ServiceStack ecosystem
Full Sample
See the full sample on GitHub: https://github.com/BenjaminAbt/dotnet.rest-samples