Stardust.Interstellar.Rest 5.7.2

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

Stardust.Interstellar.Rest

Define once. Generate everywhere.
Generate strongly-typed HTTP clients from decorated interfaces.

NuGet


What is Stardust.Rest?

Stardust.Rest lets you define your REST API as a C# interface�then automatically generates both client proxies and server controllers. No more handwriting HttpClient boilerplate or scaffolding controllers.

[Api("api/users")]
public interface IUserService
{
    [Get("{id}")]
    Task<User> GetAsync([InPath] string id);

    [Post]
    Task<User> CreateAsync([InBody] User user);
}

That's it. Share this interface between your client and server projects. The ecosystem handles the rest.

Ecosystem Packages

Package What it does
Annotations Define your API contract
Client Generate HTTP clients from interfaces ? you are here
Server Generate ASP.NET Core controllers from interfaces

Why use it?

  • ?? Contract-first � One interface = perfect client/server alignment
  • ? Zero boilerplate � No manual HTTP code or controller scaffolding
  • ??? Built-in resilience � Circuit breakers, retries, error handling
  • ?? Extensible � Custom auth, headers, serialization, error handlers

Installation

dotnet add package Stardust.Interstellar.Rest

Quick Start

1. Define your interface

using Stardust.Interstellar.Rest.Annotations;

[Api("api/users")]
public interface IUserService
{
    [Get("{id}")]
    Task<User> GetUserAsync([InPath] string id);

    [Get]
    Task<IEnumerable<User>> GetAllAsync();

    [Post]
    Task<User> CreateAsync([InBody] User user);

    [Put("{id}")]
    Task<User> UpdateAsync([InPath] string id, [InBody] User user);

    [Delete("{id}")]
    Task DeleteAsync([InPath] string id);
}

2. Register the client

services.AddInterstellar();
services.AddTransient(sp => sp.CreateRestClient<IUserService>("https://api.example.com"));

3. Use it

public class MyController
{
    private readonly IUserService _users;
    public MyController(IUserService users) => _users = users;

    public async Task<User> GetUser(string id) => await _users.GetUserAsync(id);
}

Creating Clients

Basic registration

services.AddTransient(sp => sp.CreateRestClient<IUserService>("https://api.example.com"));

With extras collector

Capture request metadata:

services.AddTransient(sp => sp.CreateRestClient<IUserService>(
    "https://api.example.com",
    extras => {
        var retryCount = extras.ContainsKey("retryCount") ? extras["retryCount"] : 0;
    }));

Using IProxyFactory

public class MyService
{
    private readonly IProxyFactory _factory;
    public MyService(IProxyFactory factory) => _factory = factory;

    public async Task DoWork()
    {
        var client = _factory.CreateInstance<IExternalApi>("https://api.external.com");
        var result = await client.GetDataAsync();
    }
}

HttpClient Management

Default Provider (Backward Compatible)

By default, the framework uses a static dictionary to cache HttpClient instances per base URL. This prevents socket exhaustion but doesn't handle DNS changes.

For production workloads, use the IHttpClientFactory integration for proper connection lifetime management:

// Program.cs or Startup.cs
services.AddStardustHttpClientFactory()
    .SetHandlerLifetime(TimeSpan.FromMinutes(15));  // DNS refresh interval

// Or with custom configuration
services.AddStardustHttpClientFactory(client =>
{
    client.Timeout = TimeSpan.FromSeconds(30);
    client.DefaultRequestHeaders.Add("User-Agent", "MyApp/1.0");
});

Benefits of IHttpClientFactory:

  • ? DNS change handling through connection recycling
  • ? Proper connection pooling with configurable lifetime
  • ? Automatic disposal of expired connections
  • ? Integration with Polly for resilience policies

Parameter Binding

[Get("search")]
Task<SearchResult> SearchAsync(
    [InQuery("q")] string searchQuery,           // ?q=laptop
    [InQuery("page_size")] int pageSize,         // ?page_size=10
    [InHeader("X-Api-Key")] string apiKey);      // X-Api-Key header

[Get("filter")]
Task<Data> GetFiltered([InQuery] Dictionary<string, string> filters);
// Expands to: ?key1=value1&key2=value2

Resilience

Circuit Breaker

Prevents cascading failures by stopping calls to failing services:

[CircuitBreaker(
    threshold: 5,           // Failures before opening
    timeoutInMinutes: 1,    // Time circuit stays open
    resetTimeout: 2)]       // Time before half-open
public interface IExternalService { }

Scoped circuit breakers isolate failures by user, client, or both:

[CircuitBreaker(5, 1, 2, CircuitBreakerScope.User)]          // Per user
[CircuitBreaker(5, 1, 2, CircuitBreakerScope.Client)]        // Per client
[CircuitBreaker(5, 1, 2, CircuitBreakerScope.UserAndClient)] // Multi-tenant

Retry Policies

Automatic retry with exponential backoff:

[Retry(numberOfRetries: 3, retryInterval: 1000, incremetalWait: true)]
public interface IResilientService { }

Custom error categorization:

public class TransientErrorCategorizer : IErrorCategorizer
{
    public bool IsTransientError(Exception ex) => ex is HttpRequestException 
        { StatusCode: HttpStatusCode.ServiceUnavailable or HttpStatusCode.TooManyRequests };
}

[Retry(3, 1000, true, ErrorCategorizer = typeof(TransientErrorCategorizer))]
public interface IService { }

Authentication

Implement IAuthenticationHandler:

public class BearerTokenHandler : IAuthenticationHandler
{
    private readonly string _token;
    public BearerTokenHandler(string token) => _token = token;

    public void Apply(HttpRequestMessage req)
    {
        req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
    }

    public Task ApplyAsync(HttpRequestMessage req) { Apply(req); return Task.CompletedTask; }
    public void BodyData(byte[] body) { } // For signature-based auth (HMAC)
}

// Register
services.AddScoped<IAuthenticationHandler, BearerTokenHandler>();

Header Handling

Custom headers via IHeaderHandler:

public class CorrelationIdHandler : IHeaderHandler
{
    public int ProcessingOrder => 0;
    public void SetHeader(HttpRequestMessage req)
    {
        req.Headers.Add("X-Correlation-Id", Activity.Current?.Id ?? Guid.NewGuid().ToString());
    }
    // ... other interface members
}

services.AddScoped<IHeaderHandler, CorrelationIdHandler>();

Runtime Configuration

Fluent configuration on client instances:

var client = sp.CreateRestClient<IUserService>("https://api.example.com");

client
    .AddHeaderValue("X-Custom-Header", "value")
    .SetVersion("v2")                              // Path: /v2/api/users
    .SetQueryStringVersion("api-version", "2.0")   // Query: ?api-version=2.0
    .SetHeaderVersion("X-API-Version", "2.0")      // Header version
    .SetProxy(new WebProxy("http://proxy:8080"));

Error Handling

All HTTP errors are wrapped in RestWrapperException:

try
{
    var user = await userService.GetUserAsync("123");
}
catch (RestWrapperException ex)
{
    Console.WriteLine($"Status: {ex.StatusCode}");
    Console.WriteLine($"Body: {ex.Value}");
}

Custom error handler:

public class ApiErrorHandler : IErrorHandler
{
    public Exception ProduceClientException(
        string message, HttpStatusCode statusCode, 
        Exception innerException, string responseBody)
    {
        var error = JsonSerializer.Deserialize<ApiError>(responseBody);
        return new ApiException(error.Code, error.Message, statusCode);
    }
}

[ErrorHandler(typeof(ApiErrorHandler))]
public interface IApiService { }

Serialization

JSON (default) uses Newtonsoft.Json. XML is also supported:

[UseXml]
public interface IXmlService { }

Global Settings

ClientGlobalSettings.Timeout = 30;                          // HTTP timeout (seconds)
ClientGlobalSettings.PooledConnectionLifetime = TimeSpan.FromMinutes(15);  // DNS refresh
ClientGlobalSettings.MaxConnectionsPerServer = 100;         // Connection limit

ProxyFactory.RunAuthProviderBeforeAppendingBody = true;     // Auth before body
ProxyFactory.EnableExpectContinue100ForPost = true;         // Expect: 100-continue

?? Security Considerations

The client library provides several built-in security features, but some security aspects require developer implementation.

Built-in Security Features

Feature Status Description
HTTP Header Injection Prevention ? Built-in Header names and values are automatically sanitized per RFC 7230
HttpClient Connection Management ? Built-in IHttpClientFactory support for proper DNS handling
TLS/HTTPS ? Uses System Default Inherits .NET's default TLS configuration

Developer Responsibilities

?? Authentication Handler Security

When implementing IAuthenticationHandler, follow these best practices:

public class SecureBearerTokenHandler : IAuthenticationHandler
{
    private readonly ITokenProvider _tokenProvider;
    
    public SecureBearerTokenHandler(ITokenProvider tokenProvider)
    {
        _tokenProvider = tokenProvider ?? throw new ArgumentNullException(nameof(tokenProvider));
    }

    public async Task ApplyAsync(HttpRequestMessage req)
    {
        // ? Get token from secure provider (Azure Key Vault, DPAPI, etc.)
        var token = await _tokenProvider.GetTokenAsync();
        
        if (!string.IsNullOrEmpty(token))
        {
            req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
        }
    }

    // ...
}

?? Security Checklist:

  • ? Never hardcode credentials in source code
  • ? Never store tokens in plain text configuration
  • ? Use secure token storage (Azure Key Vault, DPAPI, Credential Manager)
  • ? Implement token refresh/rotation
  • ? Handle 401 responses gracefully (re-authenticate and retry)
?? Custom Header Handler Security

When implementing IHeaderHandler, ensure values are sanitized:

public class SecureHeaderHandler : IHeaderHandler
{
    public void SetHeader(HttpRequestMessage req)
    {
        // ? Framework automatically sanitizes header values via SanitizeHttpHeaderValue()
        // ? Framework automatically validates header names via SanitizeHttpHeaderName()
        // ?? If bypassing framework methods, sanitize manually:
        
        var userInput = GetUserInput();
        // Remove CR/LF and other injection characters
        var sanitized = userInput?.Replace("\r", "").Replace("\n", "") ?? "";
        req.Headers.Add("X-Custom-Header", sanitized);
    }
}
?? Response Deserialization Security

The framework uses Newtonsoft.Json for deserialization. For secure deserialization:

// Configure secure JSON settings for a service type
var settings = new JsonSerializerSettings
{
    TypeNameHandling = TypeNameHandling.None,  // ?? Prevent type confusion attacks
    MaxDepth = 64                               // Prevent stack overflow
};

settings.AddClientSerializer<IMyService>();

?? Security Checklist:

  • ? Set TypeNameHandling = TypeNameHandling.None (default)
  • ? Validate expected response schemas
  • ?? Be cautious with IClientResponseInjector implementations
?? Connection Security

For production environments, use IHttpClientFactory with proper TLS configuration:

services.AddStardustHttpClientFactory()
    .ConfigurePrimaryHttpMessageHandler(() => new SocketsHttpHandler
    {
        SslOptions = new SslClientAuthenticationOptions
        {
            EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13,
            // Optional: Certificate pinning
            RemoteCertificateValidationCallback = ValidateCertificate
        },
        PooledConnectionLifetime = TimeSpan.FromMinutes(15),
        MaxConnectionsPerServer = 100
    });

Security Testing Checklist

Before deploying to production:

  • Authentication handler uses secure credential storage
  • TLS 1.2+ enforced for all connections
  • No sensitive data logged in error handlers
  • Circuit breaker thresholds prevent DoS amplification
  • Response size limits configured for large payload protection

Target Framework

.NET Standard 2.0

Dependencies

  • Stardust.Interstellar.Rest.Annotations
  • Microsoft.Extensions.DependencyInjection.Abstractions
  • Microsoft.Extensions.Http (for IHttpClientFactory support)
  • Newtonsoft.Json

License

Apache-2.0

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (15)

Showing the top 5 NuGet packages that depend on Stardust.Interstellar.Rest:

Package Downloads
Veracity.Services.Api

SDK for accessing Veracity MyServices and Profile api. Veracity MyServices is your access point for engagement of digital interaction with DNV GL. You will find digital services like “Rules and Standards”, digital tools such as our OnDemand hosted service “Secure File Transfer“, our collaboration solution “Meeting Places” (SharePoint) and many other services. Some of the services are open to all users (like “Rules and Standards” and “Secure File Transfer”), while other services require an invitation from a DNV GL employee

Stardust.Interstellar.Rest.Service.AspNetCore

Create webapi controllers based on decorated interfaces. For use with aspnetcore on netcore or .net framework

Stardust.Interstellar

Stardust servicecontainer implementation of the rest api generator.

Stardust.Continuum.Client

Client for the continuum live log stream service

Stardust.Nucleus.Web

mvc and webapi integration of Stardust.Nucleus

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.7.2 156 1/26/2026
5.7.1 98 1/21/2026
5.7.0 255 1/6/2026
5.6.1 4,997 8/9/2024
5.6.0 4,574 3/5/2024
5.5.5 674 11/10/2023
5.5.3 33,736 8/24/2022
5.5.2 37,055 5/23/2022
5.5.1 1,500 5/21/2022
5.5.0 1,916 5/16/2022
5.5.0-rc1 3,167 9/6/2021
5.0.1 59,611 4/6/2021
5.0.0 11,503 2/24/2021
Loading failed

Bugfix: nullreference when action parameters has null values
Enhancement: set WebProxy for IConfigurableService services
Bugfix: fixed over eager circuit breaker
Enhancement: Added IHttpClientProvider for proper HttpClient management with IHttpClientFactory support