Simform.ApiResponseWrapper 1.0.0

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

Simform.ApiResponseWrapper

NuGet Version NuGet Downloads License: MIT

A comprehensive .NET library that provides standardized API response wrapping for ASP.NET Core applications. This package helps maintain consistent response formats across your entire API, includes automatic error handling, pagination support, and extensive customization options.

๐Ÿš€ Features

  • Standardized Response Format: Consistent API responses across your entire application
  • Automatic Error Handling: Built-in exception handling with proper HTTP status codes
  • Pagination Support: Ready-to-use pagination with metadata
  • Fluent API Design: Easy-to-use fluent interfaces
  • ASP.NET Core Integration: Seamless integration with controllers and middleware
  • Configurable Options: Extensive customization options
  • Development & Production Modes: Different configurations for different environments
  • Trace ID Support: Built-in request tracking
  • Execution Time Tracking: Optional performance monitoring
  • Validation Support: Comprehensive validation error handling

๐Ÿ“ฆ Installation

Install the package via NuGet Package Manager:

dotnet add package Simform.ApiResponseWrapper

Or via Package Manager Console:

Install-Package Simform.ApiResponseWrapper

๐Ÿ Quick Start

1. Register Services

In your Program.cs or Startup.cs:

using Simform.ApiResponseWrapper.Extensions;

var builder = WebApplication.CreateBuilder(args);

// Add API Response Wrapper
builder.Services.AddApiResponseWrapper();

// For development with detailed error info
// builder.Services.AddApiResponseWrapperForDevelopment();

// For production with security-focused settings
// builder.Services.AddApiResponseWrapperForProduction();

var app = builder.Build();

// Use the middleware
app.UseApiResponseWrapper();

app.Run();

2. Use in Controllers

using Microsoft.AspNetCore.Mvc;
using Simform.ApiResponseWrapper.Extensions;
using Simform.ApiResponseWrapper.Models;

[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
    [HttpGet("{id}")]
    public async Task<IActionResult> GetUser(int id)
    {
        var user = await GetUserFromDatabase(id);
        
        if (user == null)
            return this.NotFound("User", "User not found");
            
        return this.Success(user, "User retrieved successfully");
    }
    
    [HttpPost]
    public async Task<IActionResult> CreateUser([FromBody] CreateUserRequest request)
    {
        if (!ModelState.IsValid)
            return this.ValidationError();
            
        var user = await CreateUserInDatabase(request);
        return this.Created(user, $"/api/users/{user.Id}", "User created successfully");
    }
    
    [HttpGet]
    public async Task<IActionResult> GetUsers(int page = 1, int size = 10)
    {
        var (users, totalCount) = await GetUsersFromDatabase(page, size);
        return this.Paginated(users, page, size, totalCount);
    }
}

๐Ÿ“‹ Response Format

All responses follow this standardized format:

Success Response

{
  "success": true,
  "data": {
    "id": 1,
    "name": "John Doe",
    "email": "john@example.com"
  },
  "message": "User retrieved successfully",
  "statusCode": 200,
  "timestamp": "2023-10-05T10:30:00Z",
  "traceId": "0HN7SPBFQK8BK:00000001",
  "metadata": {
    "executionTimeMs": 45
  }
}

Error Response

{
  "success": false,
  "data": null,
  "message": "Validation failed",
  "errors": [
    {
      "code": "VALIDATION_ERROR",
      "message": "Email is required",
      "field": "email"
    }
  ],
  "statusCode": 400,
  "timestamp": "2023-10-05T10:30:00Z",
  "traceId": "0HN7SPBFQK8BK:00000001"
}

Paginated Response

{
  "success": true,
  "data": [
    { "id": 1, "name": "User 1" },
    { "id": 2, "name": "User 2" }
  ],
  "pagination": {
    "pageNumber": 1,
    "pageSize": 10,
    "totalCount": 25,
    "totalPages": 3,
    "hasNextPage": true,
    "hasPreviousPage": false
  },
  "message": "Retrieved 10 items",
  "statusCode": 200,
  "timestamp": "2023-10-05T10:30:00Z"
}

๐Ÿ”ง Configuration

Basic Configuration

builder.Services.AddApiResponseWrapper(options =>
{
    options.EnableAutoWrapping = true;
    options.IncludeStackTrace = false;
    options.IncludeExceptionDetails = false;
    options.EnableTraceId = true;
    options.EnableLogging = true;
    options.DefaultPageSize = 10;
    options.MaxPageSize = 100;
});

Configuration from appsettings.json

{
  "ApiResponseWrapper": {
    "EnableAutoWrapping": true,
    "IncludeStackTrace": false,
    "IncludeExceptionDetails": false,
    "EnableTraceId": true,
    "EnableLogging": true,
    "DefaultPageSize": 10,
    "MaxPageSize": 100,
    "CustomErrorMessages": {
      "404": "The requested resource was not found",
      "500": "An internal error occurred"
    },
    "ExcludedActions": [
      "Health.*",
      "Metrics.Get"
    ],
    "CustomHeaders": {
      "X-API-Version": "1.0"
    }
  }
}

Then register:

builder.Services.AddApiResponseWrapper(builder.Configuration);

๐ŸŽฏ Controller Extensions

The package provides numerous extension methods for controllers:

// Success responses
return this.Success(data);
return this.Success(data, "Custom message");
return this.Success(); // No data

// Error responses
return this.Error("Something went wrong");
return this.NotFound("User", "User not found");
return this.Unauthorized();
return this.Forbidden("Insufficient permissions");
return this.Conflict("Email already exists");

// Creation responses
return this.Created(newUser, "/api/users/123");
return this.Accepted("/api/operations/456");
return this.NoContent();

// Validation responses
return this.ValidationError(); // From ModelState
return this.ValidationError(validationErrors);

// Paginated responses
return this.Paginated(users, pageNumber, pageSize, totalCount);

๐Ÿ›ก๏ธ Exception Handling

The library automatically handles common exceptions:

// Custom exceptions that are automatically handled
throw new NotFoundException("User", "User with specified ID not found");
throw new UnauthorizedException("Invalid credentials");
throw new ForbiddenException("Access denied");
throw new ConflictException("Email already exists");
throw new ValidationException("Validation failed", validationErrors);

๐Ÿ“„ Pagination

Use the built-in pagination support:

// In your controller
public async Task<IActionResult> GetUsers([FromQuery] PaginationRequest request)
{
    var query = _context.Users.AsQueryable();
    
    // Using extension method
    var result = query.ToPaginatedResponse(request.Page, request.Size);
    
    return this.Success(result);
}

// Or manually
var (users, totalCount) = await GetUsersAsync(page, size);
return this.Paginated(users, page, size, totalCount);

๐Ÿ” Middleware Options

You can use different middleware combinations:

// Full middleware pipeline
app.UseApiResponseWrapper();

// Only exception handling
app.UseApiExceptionHandling();

// Only response wrapping
app.UseApiResponseWrapping();

// Environment-specific
app.UseApiResponseWrapperForDevelopment();
app.UseApiResponseWrapperForProduction();

๐ŸŽจ Customization

Custom Error Messages

builder.Services.AddApiResponseWrapper(options =>
{
    options.CustomErrorMessages[404] = "Resource not found";
    options.CustomErrorMessages[500] = "Internal server error occurred";
});

Excluding Actions

builder.Services.AddApiResponseWrapper(options =>
{
    options.ExcludedActions.Add("Health.*");
    options.ExcludedActions.Add("Swagger.*");
    options.ExcludedStatusCodes.Add(204); // No Content
});

Custom Headers

builder.Services.AddApiResponseWrapper(options =>
{
    options.CustomHeaders["X-API-Version"] = "1.0";
    options.CustomHeaders["X-Powered-By"] = "Simform.ApiResponseWrapper";
});

๐Ÿ“Š Metadata and Tracking

Add custom metadata to responses:

return this.Success(data)
    .WithMetadata("source", "database")
    .WithMetadata("cacheHit", false);

// Or using HttpContext extensions
HttpContext.AddResponseMetadata("queryTime", "150ms");

๐Ÿงช Testing

The library is designed to be testable:

[Test]
public void Should_Return_Success_Response()
{
    // Arrange
    var controller = new UsersController();
    var user = new User { Id = 1, Name = "Test" };
    
    // Act
    var result = controller.Success(user) as ObjectResult;
    var response = result?.Value as ApiResponse<User>;
    
    // Assert
    Assert.That(response?.Success, Is.True);
    Assert.That(response?.Data, Is.EqualTo(user));
}

๐Ÿ“ˆ Performance Considerations

  • Minimal Allocations: Optimized for performance with minimal memory allocations
  • Async Support: Full async/await support throughout
  • Conditional Features: Disable features you don't need
  • Efficient Serialization: Uses System.Text.Json for optimal performance

๐Ÿค Contributing

We welcome contributions! Please see our Contributing Guidelines for details.

๐Ÿ“ License

This project is licensed under the MIT License - see the LICENSE file for details.

๐Ÿ“ž Support

๐Ÿท๏ธ Version History

  • 1.0.0: Initial release with core functionality
    • Standardized response format
    • Automatic error handling
    • Pagination support
    • ASP.NET Core integration
    • Configurable options

Made with โค๏ธ by Simform

Product Compatible and additional computed target framework versions.
.NET 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 212 10/29/2025

Initial release with core API response wrapper functionality.