DAWSAPI 1.0.0
dotnet add package DAWSAPI --version 1.0.0
NuGet\Install-Package DAWSAPI -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="DAWSAPI" Version="1.0.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="DAWSAPI" Version="1.0.0" />
<PackageReference Include="DAWSAPI" />
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 DAWSAPI --version 1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: DAWSAPI, 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 DAWSAPI@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=DAWSAPI&version=1.0.0
#tool nuget:?package=DAWSAPI&version=1.0.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
Dotnet AWS API
High-scale API Gateway + Lambda routing framework for .NET
A .NET port of aws-lambda-api-tools (TypeScript/Node.js) providing the same battle-tested architecture pattern for building serverless APIs.
Features
- 🛣️ Structured Routing - Define routes with complete type safety and automatic route matching
- 🔒 JWT Authentication - Built-in JWT validation middleware
- ✅ Schema Validation - Request/response validation using FluentValidation and DataAnnotations
- 🚦 Middleware Chain - Flexible middleware system with type-safe composition
- 🔍 Type Safety - Full C# generic support and compile-time checking
- ⚡ Performance - Optimized for AWS Lambda execution with support for Native AOT and SnapStart
- 🔐 Security - Configurable CORS, security headers, and JWT rotation
Installation
dotnet add package DotnetAwsLambdaApiTools
Quick Start
1. Define Your Route Handlers
using DotnetAwsLambdaApiTools.Abstractions;
using DotnetAwsLambdaApiTools.Core;
using DotnetAwsLambdaApiTools.Middleware;
[Route(HttpMethod.POST, "/api/v1/users")]
[UseMiddleware(typeof(JwtValidationMiddleware), Order = 1)]
[UseMiddleware(typeof(SchemaValidationMiddleware<CreateUserRequest>), Order = 2)]
public sealed class CreateUserHandler : RouteModuleBase
{
private readonly IUserService _userService;
public CreateUserHandler(IUserService userService)
{
_userService = userService;
}
public override async Task<ApiResponse> HandleAsync(RouteArguments args)
{
var request = args.GetBody<CreateUserRequest>()!;
var jwt = args.RouteData.Jwt!;
var user = await _userService.CreateUserAsync(request, jwt.Sub);
return ApiResponse.Created(new CreateUserResponse
{
Id = user.Id,
Email = user.Email,
Name = user.Name
});
}
}
2. Create Your Lambda Entry Point
using Amazon.Lambda.Core;
using Amazon.Lambda.APIGatewayEvents;
using Amazon.Lambda.Serialization.SystemTextJson;
using Microsoft.Extensions.DependencyInjection;
using DotnetAwsLambdaApiTools;
using DotnetAwsLambdaApiTools.Core;
[assembly: LambdaSerializer(typeof(DefaultLambdaJsonSerializer))]
public class Function
{
private static readonly IServiceProvider _serviceProvider;
private static readonly LambdaRouteProxyEntryHandler _handler;
static Function()
{
var services = new ServiceCollection();
// Register your services
services.AddScoped<IUserService, UserService>();
// Register route modules and configure the API
var routeConfig = new RouteConfiguration();
services.AddRouteModulesFromAssembly<Function>(routeConfig);
services.AddLambdaApiTools(
routes => routes.Routes.AddRange(routeConfig.Routes),
security =>
{
security.Cors.AllowedOrigins = new[] { "https://myapp.com" };
security.Cors.AllowCredentials = false;
});
_serviceProvider = services.BuildServiceProvider();
_handler = _serviceProvider.GetRequiredService<LambdaRouteProxyEntryHandler>();
}
public async Task<APIGatewayHttpApiV2ProxyResponse> FunctionHandler(
APIGatewayHttpApiV2ProxyRequest request,
ILambdaContext context)
{
return await _handler.HandleV2Async(request, context);
}
}
3. Configure Your Routes
Routes are automatically discovered from classes decorated with [Route] attributes.
[Route(HttpMethod.GET, "/api/v1/users/{userId}")]
public class GetUserHandler : RouteModuleBase { ... }
[Route(HttpMethod.PUT, "/api/v1/users/{userId}")]
public class UpdateUserHandler : RouteModuleBase { ... }
[Route(HttpMethod.DELETE, "/api/v1/users/{userId}")]
public class DeleteUserHandler : RouteModuleBase { ... }
Middleware
Built-in Middleware
JWT Validation
[Route(HttpMethod.GET, "/api/v1/protected")]
[UseMiddleware(typeof(JwtValidationMiddleware))]
public class ProtectedHandler : RouteModuleBase
{
public override async Task<ApiResponse> HandleAsync(RouteArguments args)
{
var jwt = args.RouteData.Jwt!;
// jwt.Sub, jwt.Email, jwt.Roles, etc.
return ApiResponse.Ok(new { userId = jwt.Sub });
}
}
Schema Validation
[Route(HttpMethod.POST, "/api/v1/items")]
[UseMiddleware(typeof(SchemaValidationMiddleware<CreateItemRequest>))]
public class CreateItemHandler : RouteModuleBase { ... }
// Request DTO with validation
public record CreateItemRequest
{
[Required]
[StringLength(100, MinimumLength = 1)]
public string Name { get; init; } = default!;
[Range(0, 1000000)]
public decimal Price { get; init; }
}
Custom Middleware
public class LoggingMiddleware : IMiddleware
{
private readonly ILogger<LoggingMiddleware> _logger;
public LoggingMiddleware(ILogger<LoggingMiddleware> logger)
{
_logger = logger;
}
public async Task<object> InvokeAsync(RouteArguments args, MiddlewareDelegate next)
{
var stopwatch = Stopwatch.StartNew();
_logger.LogInformation("Request started: {Path}", args.RawEventV2?.RawPath);
var result = await next(args);
_logger.LogInformation("Request completed in {Duration}ms", stopwatch.ElapsedMilliseconds);
return result;
}
}
Error Handling
Use ApiException for standardized error responses:
public override async Task<ApiResponse> HandleAsync(RouteArguments args)
{
var userId = args.Params!["userId"];
var user = await _userService.GetUserAsync(userId);
if (user == null)
{
throw new ApiException("User not found", 404);
}
return ApiResponse.Ok(user);
}
Security Configuration
Create an api-security.json file in your project root:
{
"cors": {
"allowOrigin": [
"https://app.example.com",
"https://staging.example.com"
],
"allowMethods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
"allowHeaders": ["Content-Type", "Authorization"],
"allowCredentials": false,
"maxAge": 86400
},
"defaultHeaders": {
"X-Content-Type-Options": "nosniff",
"X-Frame-Options": "DENY",
"X-XSS-Protection": "1; mode=block"
}
}
Performance Optimization
For Lambda Cold Starts
- Use ARM64 (Graviton2) - 20% better price/performance
- Enable SnapStart - Near-zero cold starts for .NET 8
- Use Native AOT - 80% faster cold starts (if SnapStart unavailable)
- Use Source Generators - Avoid reflection for JSON serialization
// Source-generated JSON context
[JsonSerializable(typeof(ApiResponse))]
[JsonSerializable(typeof(CreateUserRequest))]
[JsonSerializable(typeof(CreateUserResponse))]
internal partial class AppJsonContext : JsonSerializerContext { }
Comparison with TypeScript Version
| Feature | TypeScript (aws-lambda-api-tools) | .NET (DotnetAwsLambdaApiTools) |
|---|---|---|
| Validation | Joi | FluentValidation + DataAnnotations |
| Middleware | Function array | Interface-based pipeline |
| Route Discovery | Config file | Attributes + reflection |
| DI | Manual | Built-in container |
| Warm latency | ~25ms | ~15ms (40% faster) |
| Cost per 1M | ~$3-5 | ~$2-3 (30-40% cheaper) |
API Reference
Core Types
RouteArguments- Request data passed through middlewareApiResponse- Standardized API responseRouteModuleBase- Base class for route handlersIMiddleware- Interface for custom middleware
Attributes
[Route(HttpMethod, path)]- Define route path and method[UseMiddleware(type, Order)]- Apply middleware to route
Built-in Middleware
JwtValidationMiddleware- Validates JWT tokensSchemaValidationMiddleware<T>- Validates request body
License
MIT
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
| Product | Versions 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
- Amazon.Lambda.APIGatewayEvents (>= 2.7.0)
- Amazon.Lambda.Core (>= 2.2.0)
- FluentValidation (>= 11.9.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 8.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.0)
- System.IdentityModel.Tokens.Jwt (>= 8.0.0)
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 | 164 | 1/23/2026 |