feat(envelopes): add modular envelope system for Lambda event handling#131
Merged
Conversation
…rialization - Introduced `ILambdaRequest` to define a deserialization contract for Lambda requests - Introduced `ILambdaResponse` to define a serialization contract for Lambda responses
- Added `AwsLambda.Host.APIGatewayEvents` project to the solution - Configured project to support multiple frameworks including `net8.0`, `net9.0`, and `net10.0` - Included `Amazon.Lambda.AP
…sponse support - Added `APIGatewayProxyRequest<T>` for typed deserialization of API Gateway requests - Added `APIGatewayProxyResponse<T>` for typed serialization of API Gateway responses - Enhanced flexibility with `JsonSerializerOptions` for request/response body handling
- Added `IsILambdaRequest` to `ParameterInfo` for better request type recognition - Added `IsResponseILambdaResponse` to `DelegateInfo` for response type validation - Introduced helper methods for detecting `ILambdaRequest` and `ILambdaResponse` interfaces
…e handling - Added reference to `AwsLambda.Host.APIGatewayEvents` project in test project - Introduced `VerifyTests/IRequestAndIResponseVerifyTests` for validating request/response mappings - Enhanced `GeneratorTestHelpers` to support `APIGatewayProxyResponse<>` in metadata references - Refactored `WithFeatures` usage for improved readability and maintainability
- Utilize `IOptions<JsonSerializerOptions>` for request/response serialization customization - Update template to conditionally handle `ILambdaRequest` and `ILambdaResponse` types - Enhance context-building with optional JSON options for event deserialization and serialization - Add helper logic to determine when JSON options are required based on type detection
…unit tests - Included `APIGatewayProxyResponse` type in metadata references within `GeneratorTestHelpers` - Added missing `using Amazon.Lambda.APIGatewayEvents` for required type definitions
…response handling - Introduced `IRequestAndIResponseVerifyTests` to validate Lambda handler mapping logic - Added snapshot testing for `MapHandlerInterceptor` ensuring correct request/response serialization - Verified usage of `ILambdaApplication`, `ILambdaHostContext`, and JSON options for customization
Signed-off-by: Jonas Ha <61319894+j-d-ha@users.noreply.github.com>
- Introduced `AwsLambda.Host.Example.Events` project to demonstrate event handling - Configured project for `net8.0` with support for Lambda execution and testing - Set up `launchSettings.json` with environment variables for local debugging - Included `appsettings.json` with logging configuration and Lambda-specific settings
…rialization and response handling - Added `AwsLambda.Host.SQSEvent` project to the solution targeting `net8.0`, `net9.0`, and `net10.0` - Implemented `SQSBatchResponse` inheriting from `Amazon.Lambda.SQSEvents.SQSBatchResponse` - Introduced `SQSEvent<T>` for strongly-typed deserialization of SQS events with custom message types - Configured references to `Amazon.Lambda.SQSEvents` and `Amazon.Lambda.Core` packages - Updated solution and package properties to include SQS events configuration
…th rules - Set `header-max-length` rule to [0] to disable validation for commit header length - Set `body-max-line-length` rule to [0] to disable validation for commit body line length
… body support - Added new `Body` property to `APIGatewayProxyResponse<T>` class for strongly-typed responses - Included `<inheritdoc>` and `<summary>` for better documentation and maintainability - Added `System.Runtime.Serialization` namespace for potential serialization extensions
- Updated `AwsLambda.Host.Example.Events` to include `AwsLambda.Host.SQSEvent` project reference - Demonstrated SQS event processing with deserialization and batch response handling - Showcased logging and failure case simulation in the new handler examples in `Program.cs`
…ialization - Introduced `IJsonSerializable` interface to support registering type-specific JSON converters - Defined `RegisterTypeInfo` method for declaring custom `JsonConverter` implementations - Enabled automatic discovery and invocation of `RegisterTypeInfo` in Lambda host for serialization
…vents - Introduced `SqsEnvelope<T>` extending `SQSEvent` to enable strongly-typed SQS event handling - Implemented `SqsEnvelopeJsonConverter<T>` for custom serialization and deserialization logic - Enabled seamless integration with type-specific JSON serialization via `RegisterTypeInfo` method
…ent handling - Deleted `SQSBatchResponse` and `SQSEvent` classes to streamline the library and reduce duplication - Rely directly on `Amazon.Lambda.SQSEvents` for SQS event and batch response handling
…ent handling - Renamed `AwsLambda.Host.SQSEvent` to `AwsLambda.Host.SQSEnvelopes` for clarity - Added `AwsLambda.Host.APIGatewayEnvelopes` project to the solution - Removed `AwsLambda.Host.APIGatewayEvents` project reference for a cleaner structure - Updated build configurations and nested project settings accordingly
… structure - Renamed `AwsLambda.Host.SQSEnvelopes` to `AwsLambda.Host.Envelopes.SQS` for consistency - Added new solution folder `Envelopes` to organize related projects better - Updated namespace references in SQS-related files to match the new project name - Adjusted solution and project configurations for the changes
…opes design - Deleted `AwsLambda.Host.APIGatewayEvents` project and its associated classes - Introduced `AwsLambda.Host.Envelopes.APIGateway` project for envelope-based approach - Added `ApiGatewayRequestEnvelope<T>` and `ApiGatewayResponseEnvelope<T>` with custom converters - Updated solution file to reflect project restructuring under the `Envelopes` folder - Improved consistency by renaming namespaces and classes to align with `Envelopes` conventions
- Added `<inheritdoc>` to `SqsEnvelope` and `SqsMessageEnvelope` for consistent documentation - Introduced `<summary>` for the `Body` property in `SqsMessageEnvelope` to improve clarity
- Replaced `APIGatewayProxyRequest` and `APIGatewayProxyResponse` with `ApiGatewayRequestEnvelope` and `ApiGatewayResponseEnvelope` for API Gateway events - Updated SQS event handlers to utilize `SqsEnvelope` for event deserialization and processing - Added support for multiple Lambda handlers with updated envelope-based approach - Adjusted JSON serializer configuration to register custom converters for envelopes - Updated project references to reflect renamed envelope projects
* feat(models): introduce TypeInfo for type metadata representation - Added `TypeInfo` record struct to encapsulate type-related information like generic status and interfaces - Implemented `Create` method to initialize `TypeInfo` from `ITypeSymbol` and optional `TypeSyntax` - Added extension methods for tasks and ValueTask to unwrap types for detailed type analysis * feat(models): add ReturnTypeInfo to DelegateInfo - Introduced optional `ReturnTypeInfo` property to `DelegateInfo` for capturing return type metadata - Updated default initialization of `DelegateInfo` to include the new property * refactor(testing, templates): remove unused references and clean up dependencies - Removed the unused `AwsLambda.Host.APIGatewayEvents` namespace in `GeneratorTestHelpers.cs` - Commented out metadata reference for generic `APIGatewayProxyResponse<>` in favor of non-generic reference - Removed the unused `System.Text.Json` and `Microsoft.Extensions.Options` namespaces in `MapHandler.scriban` template * feat(models): enhance DelegateInfo with detailed return type metadata - Updated `DelegateInfo` to require `ReturnTypeInfo` instead of making it optional - Refactored logic in `DelegateInfoExtractorExtensions` to handle `TypeInfo` creation for return types - Improved type analysis by leveraging `TypeInfo` for unwrapped and global type representation - Adjusted existing methods to retrieve and utilize detailed return type metadata more effectively * refactor(syntax-providers): replace `FullResponseType` with `ReturnTypeInfo` - Updated all references from `FullResponseType` to `ReturnTypeInfo.FullyQualifiedType` for consistent return type handling. - Enhanced `TypeInfo` with factory methods for creating common types like `Void` and `Task`. - Refactored `DelegateInfo` to remove `FullResponseType` and use `ReturnTypeInfo` uniformly. - Adjusted logic in `DelegateInfoExtractorExtensions` to calculate and populate `ReturnTypeInfo` accurately. - Simplified and cleaned up type analysis logic in affected syntax providers and output generators. * refactor(models, syntax-providers): replace `Type` with `TypeInfo` for parameter and return types - Replaced `Type` with `TypeInfo` in `ParameterInfo` and `DelegateInfo` to improve type metadata. - Updated all references and logic to utilize `TypeInfo.FullyQualifiedType` for consistency. - Simplified type analysis and removed obsolete methods for type unwrapping. - Refactored syntax providers and output generators to adapt to the new `TypeInfo` structure. - Consolidated extension methods for task and ValueTask type checks. - Removed unused properties like `IsResponseILambdaResponse` and `IsILambdaRequest`. * refactor(syntax-providers): replace method names with constants - Replaced hardcoded method names `"OnInit"` and `"MapHandler"` with constants from `GeneratorConstants`. - Improved maintainability and consistency by centralizing method name definitions. * refactor(templates): remove unused `JsonSerializerOptions` dependency from `MapHandler.scriban` - Eliminated unused logic for resolving `JsonSerializerOptions` to simplify the template. - Removed conditional checks for `is_json_options_needed`, `is_lambda_request`, and `is_lambda_response`. - Cleaned up redundant code for event deserialization and response serialization to improve clarity. * refactor(models): remove unused `AttributeInfo` and `GenericInfo` structs - Deleted `AttributeInfo` and `GenericInfo` from the `Models` namespace as they are no longer used. - Improved codebase maintainability by removing dead code.
- Deleted `ILambdaRequest` and `ILambdaResponse` interfaces from `AwsLambda.Host.Abstractions` - Removed related dependencies such as `Stream` and `JsonSerializerOptions` - Simplified the codebase by eliminating unused abstractions
…lace ILambdaSerializer dependency (#129) * feat(aws-lambda): enhance JSON serialization options in LambdaHostOptions - Replaced `ILambdaSerializer` with `JsonSerializerOptions` for Lambda JSON serialization - Added configurable default `JsonSerializerOptions` with AWS-specific conventions - Introduced `JsonWriterOptions` for improved control over JSON escaping - Registered custom converters to support AWS conventions (e.g., `DateTimeConverter`, etc.) - Provided flexibility to customize serialization behavior through new properties * feat(aws-lambda): add default JSON serializer for Lambda host - Introduced `DefaultLambdaHostJsonSerializer` implementing `ILambdaSerializer` interface - Added support for configurable `JsonSerializerOptions` and `JsonWriterOptions` - Enhanced serialization error handling with custom exception messages - Updated `LambdaApplicationBuilder` to ensure property naming policy aligns with AWS naming rules - Registered `DefaultLambdaHostJsonSerializer` as the default `ILambdaSerializer` if not already set * feat(aws-lambda): replace LambdaHostOptions with ILambdaSerializer in LambdaHandlerComposer - Removed `LambdaHostOptions` dependency in `LambdaHandlerComposer` constructor - Introduced `ILambdaSerializer` dependency for handling request and response serialization - Updated `_settings.LambdaSerializer` usage to `_lambdaSerializer` for serialization logic - Enhanced null checks to include `lambdaSerializer` in constructor - Improved code readability and alignment with AWS Lambda serialization standards * refactor(unit-tests): remove LambdaHostOptions and add ILambdaSerializer tests in LambdaHandlerComposerTest - Eliminated outdated `LambdaHostOptions` references in `LambdaHandlerComposer` unit tests. - Added initialization and validation tests for the new `ILambdaSerializer` dependency. - Updated test cases to reflect changes in constructor parameters. - Improved test readability and ensured full coverage for `ILambdaSerializer` null checks. * refactor(aws-lambda): update property names in LambdaHostOptions and related classes - Renamed `LambdaJsonSerializerOptions` to `JsonSerializerOptions` in `LambdaHostOptions` - Renamed `LambdaJsonWriterOptions` to `JsonWriterOptions` for consistency - Updated references in `DefaultLambdaHostJsonSerializer` and `LambdaApplicationBuilder` - Improved documentation to use fully-qualified names for clarity * refactor(examples): update serializer configuration and comment out duplicate handlers - Replaced outdated `LambdaSerializer` assignment with `TypeInfoResolverChain` customization - Commented out duplicate SQS event handlers to address compilation issues - Improved examples to align with updated JSON serialization approach in `LambdaHostOptions` * feat(aws-lambda): enhance DefaultLambdaHostJsonSerializer with detailed documentation - Added XML documentation for `DefaultLambdaHostJsonSerializer` class and its methods. - Included <summary> and <remarks> to explain configurable serialization options. - Detailed parameters, return types, and exceptions for constructors and methods. - Improved clarity on customization using `LambdaHostOptions`. * feat(docs): update README with enhanced JSON serialization guidelines - Replaced outdated `LambdaSerializer` registration with `JsonSerializerOptions` configuration - Documented new serialization customization using `TypeInfoResolverChain` and options - Added details on `DefaultLambdaHostJsonSerializer` automatic registration and usage - Included AOT-related project settings like `JsonSerializerIsReflectionEnabledByDefault` - Refined available options section to highlight JSON serialization improvements * feat(examples): disable reflection-based JSON serialization in HelloWorldAot example - Set `JsonSerializerIsReflectionEnabledByDefault` to `false` in the project configuration. - Enhanced trimming settings by explicitly disabling reflection-based JSON serialization. - Improved AOT compliance by aligning with recommended .NET serialization practices.
…ements - Added `[JsonIgnore]` to `Body` property in `ApiGatewayRequestEnvelope` and `ApiGatewayResponseEnvelope` to prevent serialization of deserialized payload. - Refactored `RegisterTypeInfo` to `RegisterConverter` for better clarity on purpose. - Modified `ApiGatewayRequestEnvelopeJsonConverter` to optimize deserialization logic with override methods. - Updated Scriban template to inject `LambdaHostOptions` and register serializers dynamically.
…lizable types - Added logic to collect and process parameters and return types implementing `IJsonSerializable` - Updated Scriban model to include `SerializableItems` for template generation - Enhanced `MapHandlerSources` for improved serialization support with minimal code adjustment
- Updated method name in `IJsonSerializable` interface to better reflect its functionality. - Maintains consistency with recent changes in serialization logic and conventions.
- Added `<summary>`, `<remarks>`, and `<seealso>` tags to improve clarity and usability of the method. - Documented the behavior of `IRequestEnvelope` and `IResponseEnvelope` processing in middleware. - Included exception details and return value for enhanced developer guidance.
- Renamed namespaces from `ApiGateway2` to `ApiGateway` and `Sqs2` to `Sqs` for better clarity. - Removed `NoWarn` settings and unused `RootNamespace` from project files. - Updated references in examples and dependent files to match new namespaces. - Enhanced XML documentation for exception handling and property definitions.
- Documented `JsonOptions` property in `EnvelopeOptions` with `<summary>` and `<remarks>` tags. - Included descriptions for configuring JSON serialization settings via `IRequestEnvelope` and `IResponseEnvelope`. - Improved clarity by specifying default behavior and usage scenarios.
- Added `<remarks>` to `StartAsync` to describe the application of default middleware. - Improved clarity of `<see cref="ILoggerFactory" />` logging configuration in XML comments. - Adjusted formatting of XML documentation for better readability and consistency.
- Replaced `JsonSerializerOptions.TypeInfoResolverChain` example with `AddLambdaSerializerWithContext`. - Improved clarity and instructions for registering source-generated JSON serializers. - Added explanation of compile-time serialization benefits and AOT configuration updates.
…ons` imports - Deleted redundant `using Microsoft.Extensions.Options` statements across multiple snapshot tests. - Updated `MapHandler.scriban` template to exclude the unused import. - Simplified generated files by ensuring only relevant dependencies are included.
… clarity - Grouped package references into logical categories: source generation, OTEL, and testing libraries. - Reorganized library types to improve readability and maintainability in `Directory.Packages.props`. - Removed duplicate and misplaced entries to streamline configuration.
- Updated `AwsLambda.Host.UnitTests` to support targeting `net8.0`, `net9.0`, and `net10.0`. - Added a new test project `AwsLambda.Host.Envelopes.UnitTests` with initial test structure. - Registered new test project in the solution and added necessary dependencies. - Included a basic test for `ApiGatewayRequestEnvelope` to verify foundation setup.
- Added comprehensive tests to validate `ExtractPayload` functionality under various scenarios: - Valid JSON, camelCase naming policy, null/empty body, invalid/malformed JSON. - Verified behavior of inherited properties and `JsonIgnore` attribute on `BodyContent`. - Ensured all deserialized values are preserved and exceptions are handled correctly.
- Added comprehensive tests to validate `PackPayload` under various scenarios: - Valid payload, camelCase naming policy, null/empty body, and complex objects. - Verified `BodyContent` serialization behavior with `JsonIgnore` attribute. - Ensured proper inheritance from `APIGatewayProxyResponse` and dynamic updates to `Body`.
- Added comprehensive tests to validate `ExtractPayload` functionality: - Single/multiple records, camelCase naming policy, null/empty body, invalid/malformed JSON. - Verified behavior of `BodyContent`, including `JsonIgnore` attribute and deserialization outcomes. - Ensured proper inheritance of `SqsEnvelope` from `SQSEvent` and `SqsMessageEnvelope` from `SQSMessage`. - Registered `AwsLambda.Host.Envelopes.Sqs` project reference in unit test project for coverage.
- Introduced detailed documentation for `SqsEnvelope<T>` usage, including deserialization examples. - Provided quick start guide and AOT configuration instructions for JSON serialization. - Added badges for build status, code coverage, quality gate, and license. - Linked relevant resources and example projects for further reference.
…esponseEnvelope` - Introduced `ApiGatewayV2RequestEnvelope<T>` to simplify deserialization of request payloads. - Added `ApiGatewayV2ResponseEnvelope<T>` to streamline serialization of response payloads. - Enabled strongly-typed `BodyContent` for improved payload handling in API Gateway integrations.
…iGatewayV2ResponseEnvelope` - Added comprehensive tests for `ApiGatewayV2RequestEnvelope` to validate `ExtractPayload` functionality: - Scenarios include valid JSON, camelCase naming policy, null/empty body, invalid/malformed JSON. - Verified proper inheritance, `JsonIgnore` attribute, and deserialization correctness. - Developed tests for `ApiGatewayV2ResponseEnvelope` to confirm `PackPayload` behavior: - Scenarios include valid payloads, camelCase naming policy, null/empty body, complex objects. - Ensured `BodyContent` serialization adheres to expected structure with proper updates and inheritance.
- Detailed documentation for `AwsLambda.Host.Envelopes.ApiGateway`. - Included usage, quick start examples, and AOT support for envelopes. - Added badges for build status, code coverage, quality, and license. - Linked relevant resources and example projects for reference.
- Added a table describing envelope classes, base classes, and their use cases. - Enhanced documentation to improve clarity and use case discovery.
- Removed build, code coverage, quality gate, and license badges from `ApiGateway` and `Sqs` README files. - Updated both `README` files to simplify the header section.
… envelopes - Simplified links in `README` files for `ApiGateway` and `Sqs` envelopes. - Added `PackageId`, `Description`, and `PackageReadmeFile` metadata to project files. - Updated `Directory.Build.props` to set version as `1.0.0-beta.1`.
- Added documentation for envelope abstractions: `IRequestEnvelope` and `IResponseEnvelope`. - Detailed their contracts for payload extraction and response packing in AWS Lambda contexts. - Enhanced `README` to improve clarity on key features and abstractions.
…nd `LambdaApplication` - Adjusted line breaks and indentation for better readability in XML documentation. - Enhanced consistency in formatting for `<remarks>` and `<description>` tags.
- Updated `validate-pr-title.yaml` to include `envelopes` as an allowed scope for PR title validation.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
This PR introduces a comprehensive modular envelope system for the Lambda.Host framework, enabling strongly-typed handling of AWS Lambda events (API Gateway, SQS) with automatic payload extraction and response packing.
Key Changes:
Envelope Abstractions (
AwsLambda.Host.Abstractions):IRequestEnvelopeinterface for extracting and deserializing Lambda event payloadsIResponseEnvelopeinterface for serializing and packing handler resultsEnvelopeOptionsclass for configuring envelope serializationEnvelope Implementations:
AwsLambda.Host.Envelopes.ApiGateway- Strongly-typed API Gateway request/response handlingAwsLambda.Host.Envelopes.Sqs- SQS event envelope with batch response supportEnhanced Host Features:
UseExtractAndPackEnvelopemiddleware for automatic envelope processingAddLambdaSerializerWithContext<T>()extension method for simplified serializer registrationLambdaApplicationwith XML documentation improvementsNew Example Project:
AwsLambda.Host.Example.Eventsdemonstrating both API Gateway and SQS event handling with strongly-typed payloadsDependencies:
Amazon.Lambda.APIGatewayEventsv2.7.2Amazon.Lambda.SQSEventsv2.2.0AutoFixturev4.18.1 for testingxunit.v3to v3.2.0Configuration:
1.0.0-beta.1Breaking Changes
LambdaHostOptionsto dependency injectionWhat Changed:
LambdaHostOptionspassed toConfigureLambdaHostOptions()AddLambdaSerializerWithContext<T>()The default serializer (
DefaultLambdaJsonSerializer) is still registered automatically if you don't override it. You only need to callAddLambdaSerializerWithContext<T>()if you're using a custom source-generated context.Migration Example:
Test Plan
Notes for Reviewers
IRequestEnvelopeandIResponseEnvelopeUseExtractAndPackEnvelope) is automatically added to the request pipeline