ServiceStack

Guide to using ServiceStack for REST service consumption in .NET applications

ServiceStack Repo stars 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:

  1. ServiceStack.HttpClient - A strongly-typed client with built-in serialization and comprehensive features
  2. 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.

InfoLink
LicenseFree for OSS / Commercial for Business
DownloadsNuget
Latest VersionGitHub release (latest by date)
IssuesGitHub issues
ContributorsGitHub 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

Pros

  • 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

Cons

  • 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:

  1. Applications already using other ServiceStack components
  2. Projects requiring high-performance API consumption
  3. Scenarios needing support for multiple serialization formats
  4. Applications with complex authentication requirements
  5. Teams familiar with the ServiceStack ecosystem

Full Sample

See the full sample on GitHub: https://github.com/BenjaminAbt/dotnet.rest-samples