Skip to main content
net8.0

Runs Hardened tests against a real DynamoDB in a container, rather than a fake.

Published
Sep 5, 2026
1mo ago
Total Downloads
1.1K
1,127

Install

dotnet add package Hardened.Amz.DynamoDbClient.Testing --version 0.21.0-rc1000
ProductVersions
.NET
net8.0

README

Hardened Hardened.Amz

Runs Hardened applications on AWS Lambda. The handlers, parameter binding, configuration and tests are the core framework's. This repository supplies what runs underneath: the Lambda runtimes, response streaming, the test harnesses, a DynamoDB client and CDK constructs.

AWS documentation: ipjohnson.github.io/Hardened.Docs/aws

Start here

The Framework templates generate Lambda projects directly:

dotnet new install Hardened.Templates
dotnet new hardened-web -n Todos --host aws-lambda        # web API behind API Gateway
dotnet new hardened-function -n OrderQueue --trigger sqs  # SQS batch processor

The first generates the same todo API the Kestrel host does, and a harness that runs it locally over HTTP. A Lambda application is an ordinary Hardened application with a runtime module on it, and the module is the only line that differs from the Kestrel bootstrap:

[HardenedModule]
[LambdaWebModule]         // [KestrelRuntime] in the Kestrel host
[TodosLibrary]
public partial class Application;

No handler, service or test in the library project knows which of the two it is running under. That is the whole migration.

The function template is a different shape: a handler marked [HardenedFunction] rather than a route, invoked with the message body bound to its parameter.

[HardenedModule]
[LambdaFunctionModule]
[SqsLambda]
public partial class Application;

public class OrderHandler(OrderLog log) {
    [HardenedFunction]
    public Task Process(Order order) {
        log.Record(order);

        return Task.CompletedTask;
    }
}

The runtime module is not optional. An application without one compiles, then throws 'Application' is missing [LambdaFunctionModule] the moment it is constructed. Lambda application types covers the project shape, handler and test setup for each transport.

Pick your trigger

You are handling Module Runtime package
HTTP behind API Gateway or a function URL [LambdaWebModule] Hardened.Amz.Web.Lambda.Runtime
Direct invocation [LambdaFunctionModule] Hardened.Amz.Function.Lambda.Runtime
SQS batches [LambdaFunctionModule] + [SqsLambda] Hardened.Amz.Function.Sqs.Runtime
DynamoDB Streams [LambdaFunctionModule] + [DynamoStreamLambda] Hardened.Amz.Function.DDB.Runtime

SQS and DynamoDB Streams take a second attribute because they are event sources layered on the direct-invoke path. The SQS runtime deserialises each message body into your handler's parameter type and reports partial batch failures, so a throwing handler fails one message rather than the batch.

Every application runs on Amazon.Lambda.RuntimeSupport's bootstrap through a generated Main. Response streaming is a deployment setting rather than a separate host: with HARDENED_LAMBDA_RESPONSE_MODE=stream behind a function URL in RESPONSE_STREAM invoke mode, every response opens a stream at its first body byte, and a handler returning IAsyncEnumerable<T> writes one chunk per item. Hardened.Amz.Cdk sets the variable and the invoke mode together; see Response mode.

Testing without AWS

Each runtime has a matching harness that drives the real pipeline in-process. No deployed function, and no mocked SDK types:

  • LambdaTestApp (Hardened.Amz.Function.Lambda.Testing) invokes function handlers.
  • TestSqsApp (Hardened.Amz.Function.Sqs.Testing) delivers batches and asserts partial failures.
  • Hardened.Amz.Function.DDB.Testing feeds stream records.
  • [LocalDynamoDb] (Hardened.Amz.DynamoDbClient.Testing) runs DynamoDB in Testcontainers.
  • Hardened.Amz.Web.Lambda.Harness puts the API Gateway pipeline behind a local HTTP listener, streaming when the application is deployed in stream mode.

See testing AWS handlers and testing conventions.

Clients and infrastructure

Hardened.Amz.DynamoDbClient provides IDynamoDbClientProvider and DynamoDB extensions (docs). There is no SQS client package β€” the SQS runtime consumes a queue; writing to one means taking a direct AWSSDK.SQS dependency. Hardened.Amz.Cdk carries the CDK constructs (docs).

All packages ship to nuget.org as Hardened.Amz.*, releasing in step with the Framework's version line. The full list is in the package reference.

Building from source

dotnet build Hardened.Amz.sln
dotnet test  Hardened.Amz.sln

src/Directory.Build.targets prefers a sibling ../Hardened.Framework checkout over the pinned packages when one exists, so the two repositories can be edited together. A checkout at an incompatible commit fails the build with errors in the other repository's files. Force either side explicitly:

dotnet build Hardened.Amz.sln -p:UseLocalHardenedFramework=false   # pinned packages, as CI builds
dotnet build Hardened.Amz.sln -p:UseLocalHardenedFramework=true    # sibling checkout

CI adds -p:ContinuousIntegrationBuild=true, which turns warnings into errors β€” run a build with it set before opening a pull request. The DynamoDB client tests need a running Docker daemon, and fail rather than skip without one β€” see testing conventions.

Related repositories

Changes from Previous Version

No structural changes between v0.20.0-rc1000 and v0.21.0-rc1000.

Adoption Assessment

Assess this package against its supported frameworks, license, maintenance signals and dependency graph before making it a project standard.

This version is marked prerelease. Validate its API and upgrade path before production use.Compatibility metadata lists 1 target framework; confirm the exact target used by your application.

Related Guides & Workflows

Learn how to evaluate, integrate, or audit this package in your .NET project.