Stardust.Interstellar.Rest.Annotations 5.7.1

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

Stardust.Interstellar.Rest.Annotations

Define once. Generate everywhere.
Core attributes for building contract-first REST APIs in .NET.

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 ? you are here
Client Generate HTTP clients from interfaces
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.Annotations

Quick Reference

HTTP Verbs

[Get("route")]      // GET request
[Post("route")]     // POST request
[Put("route")]      // PUT request
[Delete("route")]   // DELETE request
[Patch("route")]    // PATCH request

Parameter Binding

[Get("users/{id}")]
Task<User> GetUserAsync(
    [InPath] string id,                              // URL path segment
    [InQuery("page_size")] int pageSize,             // Query string (?page_size=10)
    [InHeader("X-Api-Key")] string apiKey,           // HTTP header
    [InBody] UpdateRequest request);                 // Request body

Route Configuration

[Api("api/v1/products")]                             // Base route prefix
[Api("api/users", "User Management API")]            // With description

Attributes Reference

Verb Attributes

Attribute HTTP Method
[Get] / [Get("path")] GET
[Post] / [Post("path")] POST
[Put] / [Put("path")] PUT
[Delete] / [Delete("path")] DELETE
[Patch] / [Patch("path")] PATCH
[Head] / [Head("path")] HEAD
[Options] / [Options("path")] OPTIONS

Parameter Attributes

Attribute Location Example
[InPath] URL path /users/{id} ? [InPath] string id
[InQuery] or [InQuery("name")] Query string ?filter=active
[InHeader] or [InHeader("X-Name")] HTTP header Custom headers
[InBody] Request body JSON/XML payload

All parameter attributes support Description for OpenAPI documentation:

[InQuery("q", Description = "Search query text")] string searchQuery

Resilience Attributes

// Circuit breaker - stops calling failing services
[CircuitBreaker(threshold: 5, timeoutInMinutes: 1, resetTimeout: 2)]

// Retry with exponential backoff
[Retry(numberOfRetries: 3, retryInterval: 1000, incremetalWait: true)]

// Rate limiting
[Throttling(maxRequestsPerSecound: 10)]

Circuit Breaker Scopes

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

Authorization

[AuthorizeWrapper]                        // Require authentication
[AuthorizeWrapper(Roles = "Admin")]       // Require role
[AuthorizeWrapper(Policy = "CanDelete")]  // Require policy

Response Handling

[SuccessStatusCode(HttpStatusCode.Created)]    // Return 201 on success
[SuccessStatusCode(HttpStatusCode.NoContent)]  // Return 204 on success

API Versioning

[Api("api/users")]
[Version("1.0")]
public interface IUserServiceV1 { }

[Api("api/users")]
[Version("2.0", Deprecated = true)]
public interface IUserServiceV2 { }

OpenAPI Documentation

[Api("api/users")]
[ServiceDescription("User management", Tags = "Users", Summary = "CRUD operations")]
public interface IUserService
{
    [Get("{id}", "Get user by ID")]
    Task<User> GetAsync([InPath(Description = "Unique user ID")] string id);
}

Endpoint Routing Policies (.NET 6+)

[Api("api/items")]
[EndpointRoutingPolicy("SecurityHeaders")]  // Apply to all endpoints
public interface IItemService
{
    [Get]
    [EndpointRoutingPolicy("Caching")]      // Endpoint-specific
    Task<List<Item>> GetItemsAsync();
}

Extensibility Interfaces

IAuthenticationHandler

Custom authentication logic:

public class BearerTokenHandler : IAuthenticationHandler
{
    public void Apply(HttpRequestMessage req)
    {
        req.Headers.Authorization = new AuthenticationHeaderValue("Bearer", _token);
    }
    // ... other members
}

IHeaderHandler

Custom header processing:

public class CorrelationIdHandler : IHeaderHandler
{
    public void SetHeader(HttpRequestMessage req)
    {
        req.Headers.Add("X-Correlation-Id", Guid.NewGuid().ToString());
    }
    // ... other members
}

IErrorHandler

Custom error handling:

public class CustomErrorHandler : IErrorHandler
{
    public Exception ProduceClientException(
        string message, HttpStatusCode statusCode, 
        Exception innerException, string body)
    {
        return new CustomApiException(message, statusCode, body);
    }
}

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

IErrorCategorizer

Control retry behavior:

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

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

?? Security Considerations for Extensibility Interfaces

When implementing the extensibility interfaces, you take responsibility for certain security aspects. Follow these guidelines to ensure your implementations are secure.

?? IAuthenticationHandler Security

Your Responsibilities:

  • Secure credential storage and retrieval
  • Token lifecycle management (refresh, rotation, expiration)
  • Protection against credential leakage
/// <summary>
/// SECURITY: Implementations must:
/// - Never hardcode credentials
/// - Use secure storage (Azure Key Vault, DPAPI, etc.)
/// - Implement proper token refresh logic
/// - Clear sensitive data from memory when possible
/// </summary>
public class SecureAuthHandler : IAuthenticationHandler
{
    private readonly ISecureTokenProvider _tokenProvider;
    
    public SecureAuthHandler(ISecureTokenProvider tokenProvider)
    {
        _tokenProvider = tokenProvider ?? throw new ArgumentNullException(nameof(tokenProvider));
    }

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

    public void Apply(HttpRequestMessage req)
    {
        ApplyAsync(req).GetAwaiter().GetResult();
    }

    public void BodyData(byte[] body)
    {
        // For HMAC-based auth: compute signature over body
        // ?? Ensure signing key is securely stored
    }
}

?? Anti-patterns to avoid:

// ? DON'T: Hardcoded credentials
public class InsecureHandler : IAuthenticationHandler
{
    private const string ApiKey = "sk-12345...";  // ? Never do this!
}

// ? DON'T: Plain text configuration
public class InsecureHandler : IAuthenticationHandler
{
    public InsecureHandler(IConfiguration config)
    {
        _token = config["ApiToken"];  // ? Not secure for production
    }
}

?? IHeaderHandler Security

Your Responsibilities:

  • Header value sanitization (the framework handles standard headers automatically)
  • Prevention of header injection attacks
  • Protection of sensitive data in headers
/// <summary>
/// SECURITY: Implementations must sanitize header values to prevent injection.
/// The framework provides SanitizeHttpHeaderValue() for this purpose.
/// </summary>
public class SecureHeaderHandler : IHeaderHandler
{
    public int ProcessingOrder => 0;

    public void SetHeader(HttpRequestMessage req)
    {
        var correlationId = Activity.Current?.Id ?? Guid.NewGuid().ToString();
        
        // ? Use only alphanumeric/dash characters in custom headers
        // ? Framework automatically sanitizes standard parameter headers
        req.Headers.Add("X-Correlation-Id", correlationId);
    }

    public void GetHeader(HttpResponseMessage response)
    {
        // ?? Don't log sensitive header values
        // ? Validate expected header formats before use
    }
}

Header Injection Prevention: The framework automatically sanitizes header names and values per RFC 7230, removing:

  • CR (\r) and LF (\n) characters
  • URL-encoded variants (%0d, %0a)
  • Double-encoded variants (%250d, %250a)
  • Unicode line separators (\u2028, \u2029)

?? IErrorHandler Security

Your Responsibilities:

  • Preventing sensitive information disclosure in error responses
  • Logging errors securely (no credentials in logs)
  • Providing meaningful but safe error messages to clients
/// <summary>
/// SECURITY: Error handlers must not expose:
/// - Stack traces in production
/// - Internal system details
/// - Database connection strings
/// - File paths
/// - PII (emails, SSNs, etc.)
/// </summary>
public class SecureErrorHandler : IErrorHandler
{
    private readonly ILogger _logger;
    private readonly bool _isDevelopment;

    public SecureErrorHandler(ILogger logger, IHostEnvironment env)
    {
        _logger = logger;
        _isDevelopment = env.IsDevelopment();
    }

    public Exception ProduceClientException(
        string message, 
        HttpStatusCode statusCode, 
        Exception innerException, 
        string responseBody)
    {
        // ? Generate error ID for correlation
        var errorId = Guid.NewGuid().ToString("N");
        
        // ? Log full details internally
        _logger.LogError(innerException, "Error {ErrorId}: {Message}", errorId, message);
        
        // ? Return sanitized message to client
        var clientMessage = _isDevelopment 
            ? message 
            : $"An error occurred. Reference ID: {errorId}";
        
        return new ApiException(clientMessage, statusCode, errorId);
    }
}

?? IInputInterceptor Security

Your Responsibilities:

  • Input validation before processing
  • Protection against injection attacks (SQL, XSS, command injection)
  • Rate limiting and request throttling
/// <summary>
/// SECURITY: Input interceptors should validate:
/// - Required fields are present
/// - Data types and formats are correct
/// - Values are within acceptable ranges
/// - No injection attack patterns
/// </summary>
public class SecureInputValidator : IInputInterceptor
{
    public bool Intercept(object[] values, StateDictionary state, 
        out string message, out HttpStatusCode statusCode)
    {
        var errors = new List<string>();
        
        foreach (var value in values.Where(v => v != null))
        {
            // ? Use Data Annotations validation
            var context = new ValidationContext(value);
            var results = new List<ValidationResult>();
            
            if (!Validator.TryValidateObject(value, context, results, true))
            {
                errors.AddRange(results.Select(r => r.ErrorMessage));
            }
            
            // ? Additional security checks
            if (value is string str && ContainsInjectionPattern(str))
            {
                errors.Add("Invalid characters in input");
            }
        }
        
        if (errors.Any())
        {
            message = string.Join("; ", errors);
            statusCode = HttpStatusCode.BadRequest;
            return true;  // Cancel request
        }
        
        message = null;
        statusCode = HttpStatusCode.OK;
        return false;
    }

    private bool ContainsInjectionPattern(string input)
    {
        // ?? This is defense-in-depth only
        // ? Always use parameterized queries for database access
        return input.Contains("<script", StringComparison.OrdinalIgnoreCase) ||
               input.Contains("javascript:", StringComparison.OrdinalIgnoreCase);
    }
}

??? ISerializer Security (XML)

Your Responsibilities:

  • XXE (XML External Entity) prevention
  • Denial of service protection via size limits
  • Schema validation
/// <summary>
/// SECURITY: XML serializer implementations MUST:
/// - Disable DTD processing
/// - Disable external entity resolution
/// - Set maximum document size limits
/// </summary>
public class SecureXmlSerializer : ISerializer
{
    public string SerializationType => "xml";

    public object Deserialize(Stream stream, Type type)
    {
        // ? Secure XML reader settings
        var settings = new XmlReaderSettings
        {
            DtdProcessing = DtdProcessing.Prohibit,    // Prevent XXE
            XmlResolver = null,                         // No external entities
            MaxCharactersInDocument = 10_000_000,       // Size limit
            MaxCharactersFromEntities = 1000            // Entity expansion limit
        };

        using (var reader = XmlReader.Create(stream, settings))
        {
            var serializer = new XmlSerializer(type);
            return serializer.Deserialize(reader);
        }
    }

    // ... other members
}

Security Implementation Checklist

Before deploying implementations of extensibility interfaces:

IAuthenticationHandler:

  • Credentials retrieved from secure storage
  • No hardcoded secrets
  • Token refresh implemented
  • Sensitive data cleared from memory

IHeaderHandler:

  • User input sanitized before adding to headers
  • No sensitive data in custom headers
  • Correlation IDs use safe formats

IErrorHandler:

  • Stack traces hidden in production
  • No PII in error messages
  • Error IDs generated for correlation
  • Full errors logged internally

IInputInterceptor:

  • Required field validation
  • Type and format validation
  • Injection pattern detection
  • Size/length limits enforced

ISerializer (XML):

  • DTD processing disabled
  • External entities blocked
  • Document size limits set

Target Frameworks

.NET Standard 2.0 | .NET 6.0 | .NET 7.0 | .NET 8.0

License

Apache-2.0

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  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 is compatible.  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 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. 
.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 (14)

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

Package Downloads
Stardust.Interstellar.Rest

Create rest service proxies based on decorated interfaces.

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

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
5.7.1 183 1/26/2026
5.7.0 344 1/6/2026
5.6.1 10,175 8/9/2024
5.6.0 3,645 3/5/2024
5.5.1 42,820 5/23/2022
5.5.0 3,087 5/16/2022
5.5.0-rc1 3,319 9/6/2021
5.0.1 60,374 4/6/2021
5.0.0 24,960 2/24/2021
5.0.0-rc1 4,219 2/16/2021
4.2.0 14,650 2/10/2020
4.1.1 26,493 8/20/2019
4.0.1 1,414 8/20/2019
4.0.0 9,460 8/5/2019
3.4.8 11,031 5/14/2019
3.4.6 4,602 2/7/2019
3.4.5 8,436 12/7/2018
3.4.3 3,369 12/3/2018
3.4.1 8,884 10/4/2018
3.4.0 3,639 10/4/2018
3.3.1 3,407 10/2/2018
3.3.0 4,336 10/1/2018
3.2.0 4,201 9/18/2018
3.1.0 9,254 6/26/2018
3.1.0-pre014 2,652 6/26/2018
3.1.0-pre013 1,435 6/25/2018
2.0.0.3 5,547 3/19/2018
2.0.0.2 4,594 3/5/2018
2.0.0.1-pre006 2,066 3/5/2018
2.0.0.1-pre005 2,317 2/23/2018
2.0.0.1-pre004 1,418 2/21/2018
2.0.0.1-pre003 1,218 2/21/2018
2.0.0.1-pre002 1,674 2/20/2018
2.0.0.1-pre001 1,158 2/20/2018
2.0.0.1-pre 2,297 12/15/2017
2.0.0-pre 4,181 8/29/2017
1.6.3 2,715 10/23/2017
1.6.0 10,355 3/8/2017
1.5.4 3,500 2/22/2017
1.5.3 1,532 2/20/2017
1.5.2 1,556 2/14/2017
1.5.0 4,968 1/24/2017
1.4.3 1,793 1/9/2017
1.4.2 1,591 12/29/2016
1.4.1.1 1,475 12/20/2016
1.4.1 6,935 11/30/2016
1.4.0 2,769 11/23/2016
1.3.1 13,922 8/18/2016
1.3.0 4,259 8/18/2016
1.2.6 6,490 6/24/2016
1.2.5 1,503 6/22/2016
1.2.4 1,465 6/22/2016
1.2.3 1,455 6/22/2016
1.2.2 1,489 6/22/2016
1.2.1 1,479 6/22/2016
1.2.0 5,968 6/14/2016
1.1.1 1,507 6/3/2016
1.1.0 12,220 6/2/2016
1.0.0.1 4,830 5/31/2016

Added Service Description options to Verb attributes