From 9504dac5443ca03da3752bc167bede6a1695c25b Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 10 Sep 2025 17:29:14 +0200 Subject: [PATCH 01/30] docs(event-handler): create main structure --- docs/features/event-handler/bedrock-agents.md | 1 - docs/features/event-handler/index.md | 8 +++ .../event-handler/{api-gateway.md => rest.md} | 20 +++--- .../rest/templates/api_gateway.yml | 68 +++++++++++++++++++ .../rest/templates/lambda_furl.yml | 30 ++++++++ mkdocs.yml | 8 +-- 6 files changed, 117 insertions(+), 18 deletions(-) rename docs/features/event-handler/{api-gateway.md => rest.md} (57%) create mode 100644 examples/snippets/event-handler/rest/templates/api_gateway.yml create mode 100644 examples/snippets/event-handler/rest/templates/lambda_furl.yml diff --git a/docs/features/event-handler/bedrock-agents.md b/docs/features/event-handler/bedrock-agents.md index fa81222ed0..8ea8a22fd0 100644 --- a/docs/features/event-handler/bedrock-agents.md +++ b/docs/features/event-handler/bedrock-agents.md @@ -1,7 +1,6 @@ --- title: Bedrock Agents description: Event Handler for Amazon Bedrock Agents -status: new --- diff --git a/docs/features/event-handler/index.md b/docs/features/event-handler/index.md index 6ee9a38397..817fed779b 100644 --- a/docs/features/event-handler/index.md +++ b/docs/features/event-handler/index.md @@ -7,6 +7,14 @@ description: Simplify routing and processing of events in AWS Lambda functions
+- __REST APIs__ + + --- + + Event handler for Amazon API Gateway REST and HTTP APIs, Application Loader Balancer (ALB), Lambda Function URLs, and VPC Lattice. + + [:octicons-arrow-right-24: Read more](./rest.md) + - __AppSync Events API__ --- diff --git a/docs/features/event-handler/api-gateway.md b/docs/features/event-handler/rest.md similarity index 57% rename from docs/features/event-handler/api-gateway.md rename to docs/features/event-handler/rest.md index adf097f13b..1f8d9da82a 100644 --- a/docs/features/event-handler/api-gateway.md +++ b/docs/features/event-handler/rest.md @@ -1,28 +1,26 @@ --- title: REST API -description: Core utility +description: Event handler for building REST APIs in AWS Lambda +status: new --- - -???+ warning "Don't use in production (yet)" - This feature is currently under development. As such it's considered not stable and we might make significant breaking changes before going [before its release](https://github.com/aws-powertools/powertools-lambda-typescript/milestone/17){target="_blank"}. You are welcome to [provide feedback](https://github.com/aws-powertools/powertools-lambda-typescript/issues/413){target="_blank"} and [contribute to the project](../../contributing/getting_started.md){target="_blank"}. +!!! warning "Feature status" + This feature is under active development and may undergo significant changes. We recommend using it in non-critical workloads and [providing feedback](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) to help us improve it. Event handler for Amazon API Gateway REST and HTTP APIs, Application Loader Balancer (ALB), Lambda Function URLs, and VPC Lattice. ## Key Features * Lightweight routing to reduce boilerplate for API Gateway REST/HTTP API, ALB and Lambda Function URLs. -* Support for CORS, binary and Gzip compression, Decimals JSON encoding and bring your own JSON serializer -* Built-in integration with [Parser](../../features/parser.md){target="_blank"} for easy payload validation and parsing +* Built-in middleware engine for request/response transformation and validation. * Works with micro function (one or a few routes) and monolithic functions (all routes) ## Getting started -???+ tip - All examples shared in this documentation are available within the [project repository](https://github.com/aws-powertools/powertools-lambda-typescript/tree/main/examples/snippets/event-handler){target="_blank"}. - ### Install +!!! info "This is not necessary if you're installing Powertools for AWS Lambda (TypeScript) via [Lambda layer](../../getting-started/lambda-layers.md)." + ```shell npm install @aws-lambda-powertools/event-handler ``` @@ -40,13 +38,13 @@ This is the sample infrastructure for API Gateway and Lambda Function URLs we ar === "API Gateway SAM Template" ```yaml title="AWS Serverless Application Model (SAM) example" -[//]: # ( --8<-- "examples/snippets/event-handler/rest/templates/template.yaml") + --8<-- "examples/snippets/event-handler/rest/templates/api_gateway.yml" ``` === "Lambda Function URL SAM Template" ```yaml title="AWS Serverless Application Model (SAM) example" -[//]: # ( --8<-- "examples/event_handler_lambda_function_url/sam/template.yaml") + --8<-- "examples/snippets/event-handler/rest/templates/lambda_furl.yml" ``` diff --git a/examples/snippets/event-handler/rest/templates/api_gateway.yml b/examples/snippets/event-handler/rest/templates/api_gateway.yml new file mode 100644 index 0000000000..6fdd416be4 --- /dev/null +++ b/examples/snippets/event-handler/rest/templates/api_gateway.yml @@ -0,0 +1,68 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: Hello world event handler API Gateway + +Globals: + Api: + TracingEnabled: true + Cors: # see CORS section + AllowOrigin: "'https://example.com'" + AllowHeaders: "'Content-Type,Authorization,X-Amz-Date'" + MaxAge: "'300'" + BinaryMediaTypes: # see Binary responses section + - "*~1*" # converts to */* for any binary type + # NOTE: use this stricter version if you're also using CORS; */* doesn't work with CORS + # see: https://github.com/aws-powertools/powertools-lambda-python/issues/3373#issuecomment-1821144779 + # - "image~1*" # converts to image/* + # - "*~1csv" # converts to */csv, eg text/csv, application/csv + + Function: + Timeout: 5 + MemorySize: 256 + Runtime: nodejs22.x + Tracing: Active + Environment: + Variables: + POWERTOOLS_LOG_LEVEL: INFO + POWERTOOLS_SERVICE_NAME: hello + +Resources: + ApiFunction: + Type: AWS::Serverless::Function + Properties: + Handler: index.handler + CodeUri: hello_world + Description: API handler function + Events: + AnyApiEvent: + Type: Api + Properties: + # NOTE: this is a catch-all rule to simplify the documentation. + # explicit routes and methods are recommended for prod instead (see below) + Path: /{proxy+} # Send requests on any path to the lambda function + Method: ANY # Send requests using any http method to the lambda function + + + # GetAllTodos: + # Type: Api + # Properties: + # Path: /todos + # Method: GET + # GetTodoById: + # Type: Api + # Properties: + # Path: /todos/{todo_id} + # Method: GET + # CreateTodo: + # Type: Api + # Properties: + # Path: /todos + # Method: POST + + ## Swagger UI specific routes + + # SwaggerUI: + # Type: Api + # Properties: + # Path: /swagger + # Method: GET \ No newline at end of file diff --git a/examples/snippets/event-handler/rest/templates/lambda_furl.yml b/examples/snippets/event-handler/rest/templates/lambda_furl.yml new file mode 100644 index 0000000000..1770b5a278 --- /dev/null +++ b/examples/snippets/event-handler/rest/templates/lambda_furl.yml @@ -0,0 +1,30 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: Hello world event handler API Gateway + +Globals: + Function: + Timeout: 5 + MemorySize: 256 + Runtime: nodejs22.x + Tracing: Active + Environment: + Variables: + POWERTOOLS_LOG_LEVEL: INFO + POWERTOOLS_SERVICE_NAME: hello + FunctionUrlConfig: + Cors: # see CORS section + # Notice that values here are Lists of Strings, vs comma-separated values on API Gateway + AllowOrigins: ["https://example.com"] + AllowHeaders: ["Content-Type", "Authorization", "X-Amz-Date"] + MaxAge: 300 + +Resources: + ApiFunction: + Type: AWS::Serverless::Function + Properties: + Handler: index.handler + CodeUri: hello_world + Description: API handler function + FunctionUrlConfig: + AuthType: NONE # AWS_IAM for added security beyond sample documentation \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 30193d8af4..3784246e87 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -47,6 +47,7 @@ nav: - features/metrics.md - Event Handler: - features/event-handler/index.md + - features/event-handler/rest.md - features/event-handler/appsync-events.md - features/event-handler/appsync-graphql.md - features/event-handler/bedrock-agents.md @@ -162,12 +163,6 @@ plugins: - snippets/node_modules/* - snippets/package.json - snippets/CHANGELOG.md - - typedoc: - source: '.' - output_dir: 'api' - tsconfig: 'tsconfig.json' - options: 'typedoc.json' - name: 'API Reference' - llmstxt: markdown_description: Powertools for AWS Lambda (TypeScript) is a developer toolkit to implement Serverless best practices and increase developer velocity. It provides a suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier. @@ -183,6 +178,7 @@ plugins: - features/tracer.md - features/logger.md - features/metrics.md + - features/event-handler/rest.md - features/event-handler/appsync-events.md - features/event-handler/appsync-graphql.md - features/event-handler/bedrock-agents.md From 045a58306a3bd61a289b82f52940ea1ebebfa027 Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Wed, 10 Sep 2025 21:48:06 +0200 Subject: [PATCH 02/30] docs: skeleton --- docs/features/event-handler/rest.md | 245 +++++++++++++++++- docs/media/micro-function.png | Bin 0 -> 86833 bytes docs/media/monolithic-function.png | Bin 0 -> 81725 bytes .../rest/gettingStarted_dynamic_routes.ts | 26 ++ .../rest/gettingStarted_methods.ts | 28 ++ .../rest/gettingStarted_multi_methods.ts | 34 +++ .../rest/gettingStarted_serialization.ts | 9 + .../gettingStarted_dynamic_routes.json | 5 + .../rest/samples/gettingStarted_methods.json | 6 + .../samples/gettingStarted_serialization.json | 10 + .../rest/templates/api_gateway.yml | 35 +-- 11 files changed, 363 insertions(+), 35 deletions(-) create mode 100644 docs/media/micro-function.png create mode 100644 docs/media/monolithic-function.png create mode 100644 examples/snippets/event-handler/rest/gettingStarted_dynamic_routes.ts create mode 100644 examples/snippets/event-handler/rest/gettingStarted_methods.ts create mode 100644 examples/snippets/event-handler/rest/gettingStarted_multi_methods.ts create mode 100644 examples/snippets/event-handler/rest/gettingStarted_serialization.ts create mode 100644 examples/snippets/event-handler/rest/samples/gettingStarted_dynamic_routes.json create mode 100644 examples/snippets/event-handler/rest/samples/gettingStarted_methods.json create mode 100644 examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 1f8d9da82a..ba4ff37c18 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -31,21 +31,246 @@ If you're using any API Gateway integration, you must have an existing [API Gate In case of using [VPC Lattice](https://docs.aws.amazon.com/lambda/latest/dg/services-vpc-lattice.html){target="_blank"}, you must have a service network configured to invoke your Lambda function. -This is the sample infrastructure for API Gateway and Lambda Function URLs we are using for the examples in this documentation. +This is the sample infrastructure for API Gateway and Lambda Function URLs we are using for the examples in this documentation. There is no additional permissions or dependencies required to use this utility. -???+ info "There is no additional permissions or dependencies required to use this utility." +??? "See Infrastructure as Code (IaC) examples" + === "API Gateway SAM Template" -=== "API Gateway SAM Template" + ```yaml title="AWS Serverless Application Model (SAM) example" + --8<-- "examples/snippets/event-handler/rest/templates/api_gateway.yml" + ``` - ```yaml title="AWS Serverless Application Model (SAM) example" - --8<-- "examples/snippets/event-handler/rest/templates/api_gateway.yml" +### Route events + +Before you start defining your routes, it's important to understand how the event handler works with different types of events. The event handler can process events from API Gateway REST APIs, and will soon support ALB, Lambda Function URLs, and VPC Lattice as well. + +When a request is received, the event handler will automatically convert the event into a `Request` object and give you access to the current request context, including headers, query parameters, and request body, as well as path parameters via typed arguments. + +#### Response auto-serialization + +!!! tip "Want full control over the response, headers, and status code? Read about the `Response` object here." + +For your convenience, when you return a JavaScript object from your route handler, we automatically perform these actions: + +* Auto-serialize the response to JSON and trim whitespace +* Include the response under the appropriate equivalent of a `body` +* Set the `Content-Type` header to `application/json` +* Set the HTTP status code to 200 (OK) + +=== "index.ts" + + ```ts hl_lines="6" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_serialization.ts" ``` -=== "Lambda Function URL SAM Template" + 1. This object will be serialized, trimmed, and included under the `body` key + +=== "JSON response" - ```yaml title="AWS Serverless Application Model (SAM) example" - --8<-- "examples/snippets/event-handler/rest/templates/lambda_furl.yml" + ```json hl_lines="8" + --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json" ``` - - \ No newline at end of file +### Dynamic routes + +You can use `/todos/:todoId` to configure dynamic URL paths, where `:todoId` will be resolved at runtime. + +All dynamic route parameters will be available as typed object properties in the first argument of your route handler. + +=== "index.ts" + + ```ts hl_lines="16" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_dynamic_routes.ts:3" + ``` + +=== "Request" + + ```json + --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_dynamic_routes.json" + ``` + +You can also nest dynamic paths, for example `/todos/:todoId/comments/:commentId`, where both `:todoId` and `:commentId` will be resolved at runtime. + +### HTTP Methods + +You can use dedicated methods to specify the HTTP method that should be handled in each resolver. That is, `app.`, where the HTTP method could be `get`, `post`, `put`, `patch`, and `delete`. + +=== "index.ts" + + ```ts hl_lines="14 16" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_methods.ts:3" + ``` + +=== "Request" + + ```json + --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_methods.json" + ``` + +If you need to accept multiple HTTP methods in a single function, or support a HTTP method for which no dedicated method exists (i.e. [`TRACE`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods/TRACE){target="_blank"}), you can use the `route` method and pass a list of HTTP methods. + +=== "index.ts" + + ```ts hl_lines="21-24" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_multi_methods.ts:3" + ``` + +!!! tip + We generally recommend to have separate functions for each HTTP method, as the functionality tends to differ depending on which method is used. + +### Data validation + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Accessing request details + +You can access request details such as headers, query parameters, and body using the `Request` object provided to your route handlers. + +### Handling not found routes + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Error handling + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Raising HTTP errors + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Enabling SwaggerUI + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Custom domains + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +## Advanced + +### CORS + +You can configure CORS at the router level via the `cors` middleware. + +!!! note "Coming soon" + +### Middleware + +// TODO: @svozza + +### Fine grained responses + +You can use the Web API's `Response` object to have full control over the response. For example, you might want to add additional headers, cookies, or set a custom content type. + +// TODO: @svozza please add a code example + response sample + +### Response streaming + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Compress + +You can compress with gzip and base64 encode your responses via the `compress` parameter. You have the option to pass the `compress` parameter when working with a specific route or setting the correct `Accept-Encoding` header in the `Response` object. + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Binary responses + +!!! warning "Using API Gateway?" + Amazon API Gateway does not support `*/*` binary media type when [CORS](#cors) is also configured. This feature requires API Gateway to configure binary media types, see our [sample infrastructure](#required-resources) for reference. + +For convenience, we automatically base64 encode binary responses. You can also use it in combination with the `compress` parameter if your client supports gzip. + +Like the `compress` feature, the client must send the `Accept` header with the correct media type. + +!!! tip Lambda Function URLs handle binary media types automatically. + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Debug mode + +You can enable debug mode via the `POWERTOOLS_DEV` environment variable. + +This will enable full stack traces errors in the response, log request and responses, and set CORS in development mode. + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### OpenAPI + +When you enable [Data Validation](#data-validation), we use a combination of Zod and JSON Schemas to add constraints to your API's parameters. + +In OpenAPI documentation tools like [SwaggerUI](#enabling-swaggerui), these annotations become readable descriptions, offering a self-explanatory API interface. This reduces boilerplate code while improving functionality and enabling auto-documentation. + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Split routers + +As you grow the number of routes a given Lambda function should handle, it is natural to either break into smaller Lambda functions, or split routes into separate files to ease maintenance - that's where the split `Router` feature is useful. + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this feature. + +### Considerations + +This utility is optimized for AWS Lambda computing model and prioritizes fast startup, minimal feature set, and quick onboarding for triggers supported by Lambda. + +Event Handler naturally leads to a single Lambda function handling multiple routes for a given service, which can be eventually broken into multiple functions. + +Both single (monolithic) and multiple functions (micro) offer different set of trade-offs worth knowing. + +!!! tip "TL;DR;" + Start with a monolithic function, add additional functions with new handlers, and possibly break into micro functions if necessary. + +#### Monolithic function + +![monolithic function](../../media//monolithic-function.png) + +A monolithic function means that your final code artifact will be deployed to a single function. This is generally the best approach to start. + +_**Benefits**_ + +* **Code reuse.** It's easier to reason about your service, modularize it and reuse code as it grows. Eventually, it can be turned into a standalone library. +* **No custom tooling.** Monolithic functions are treated just like normal Python packages; no upfront investment in tooling. +* **Faster deployment and debugging.** Whether you use all-at-once, linear, or canary deployments, a monolithic function is a single deployable unit. IDEs like PyCharm and VSCode have tooling to quickly profile, visualize, and step through debug any Python package. + +_**Downsides**_ + +* **Cold starts.** Frequent deployments and/or high load can diminish the benefit of monolithic functions depending on your latency requirements, due to [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"}. Always load test to pragmatically balance between your customer experience and development cognitive load. +* **Granular security permissions.** The micro function approach enables you to use fine-grained permissions & access controls, separate external dependencies & code signing at the function level. Conversely, you could have multiple functions while duplicating the final code artifact in a monolithic approach. Regardless, least privilege can be applied to either approaches. +* **Higher risk per deployment.** A misconfiguration or invalid import can cause disruption if not caught earlier in automated testing. Multiple functions can mitigate misconfigurations but they would still share the same code artifact. You can further minimize risks with multiple environments in your CI/CD pipeline. + +#### Micro function + +![micro function](../../media//micro-function.png) + +A micro function means that your final code artifact will be different to each function deployed. This is generally the approach to start if you're looking for fine-grain control and/or high load on certain parts of your service. + +_**Benefits**_ + +**Granular scaling.** A micro function can benefit from the [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"} to scale differently depending on each part of your application. Concurrency controls and provisioned concurrency can also be used at a granular level for capacity management. +**Discoverability.** Micro functions are easier to visualize when using distributed tracing. Their high-level architectures can be self-explanatory, and complexity is highly visible — assuming each function is named to the business purpose it serves. +**Package size.** An independent function can be significant smaller (KB vs MB) depending on external dependencies it require to perform its purpose. Conversely, a monolithic approach can benefit from [Lambda Layers](https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html){target="_blank"} to optimize builds for external dependencies. + +_**Downsides**_ + +**Upfront investment.** You need custom build tooling to bundle assets, including [native bindings for runtime compatibility](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html){target="_blank"}. Operations become more elaborate — you need to standardize tracing labels/annotations, structured logging, and metrics to pinpoint root causes. +**Engineering discipline** is necessary for both approaches. Micro-function approach however requires further attention in consistency as the number of functions grow, just like any distributed system. +**Harder to share code.** Shared code must be carefully evaluated to avoid unnecessary deployments when that changes. Equally, if shared code isn't a library, your development, building, deployment tooling need to accommodate the distinct layout. +**Slower safe deployments.** Safely deploying multiple functions require coordination — AWS CodeDeploy deploys and verifies each function sequentially. This increases lead time substantially (minutes to hours) depending on the deployment strategy you choose. You can mitigate it by selectively enabling it in prod-like environments only, and where the risk profile is applicable. +Automated testing, operational and security reviews are essential to stability in either approaches. + +## Testing your code + +!!! note "Coming soon" + Please open an issue if you would like us to prioritize this section. diff --git a/docs/media/micro-function.png b/docs/media/micro-function.png new file mode 100644 index 0000000000000000000000000000000000000000..74887bc77269e2fd6111f28201ef650f472cdeeb GIT binary patch literal 86833 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 z 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±w?X?p7^INTE->C-bgKQsOQJ)Y3X$F4__uj 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: unknown): Promise<{ id: string } & T>; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { + correlationPaths, + search, +} from '@aws-lambda-powertools/logger/correlationId'; +import type { Context } from 'aws-lambda/handler'; + +const logger = new Logger({ + correlationIdSearchFn: search, +}); +const app = new Router({ logger }); + +app.get('/todos/:todoId', async ({ todoId }) => { + const todo = await getTodoById(todoId); + return { todo }; +}); + +export const handler = async (event: unknown, context: Context) => { + // You can continue using other utilities just as before + logger.addContext(context); + logger.setCorrelationId(event, correlationPaths.API_GATEWAY_REST); + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/gettingStarted_methods.ts b/examples/snippets/event-handler/rest/gettingStarted_methods.ts new file mode 100644 index 0000000000..f63ffe306a --- /dev/null +++ b/examples/snippets/event-handler/rest/gettingStarted_methods.ts @@ -0,0 +1,28 @@ +declare function putTodo(todo: unknown): Promise<{ id: string } & T>; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { + correlationPaths, + search, +} from '@aws-lambda-powertools/logger/correlationId'; +import type { Context } from 'aws-lambda/handler'; + +const logger = new Logger({ + correlationIdSearchFn: search, +}); +const app = new Router({ logger }); + +app.post('/todos', async (_, { request }) => { + const body = await request.json(); + const todo = await putTodo(body); + + return todo; +}); + +export const handler = async (event: unknown, context: Context) => { + // You can continue using other utilities just as before + logger.addContext(context); + logger.setCorrelationId(event, correlationPaths.API_GATEWAY_REST); + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/gettingStarted_multi_methods.ts b/examples/snippets/event-handler/rest/gettingStarted_multi_methods.ts new file mode 100644 index 0000000000..4888d31097 --- /dev/null +++ b/examples/snippets/event-handler/rest/gettingStarted_multi_methods.ts @@ -0,0 +1,34 @@ +declare function putTodo(todo: unknown): Promise<{ id: string } & T>; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import { Logger } from '@aws-lambda-powertools/logger'; +import { + correlationPaths, + search, +} from '@aws-lambda-powertools/logger/correlationId'; +import type { Context } from 'aws-lambda/handler'; + +const logger = new Logger({ + correlationIdSearchFn: search, +}); +const app = new Router({ logger }); + +app.route( + async (_, { request }) => { + const body = await request.json(); + const todo = await putTodo(body); + + return todo; + }, + { + path: '/todos', + method: ['POST', 'PUT'], + } +); + +export const handler = async (event: unknown, context: Context) => { + // You can continue using other utilities just as before + logger.addContext(context); + logger.setCorrelationId(event, correlationPaths.API_GATEWAY_REST); + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/gettingStarted_serialization.ts b/examples/snippets/event-handler/rest/gettingStarted_serialization.ts new file mode 100644 index 0000000000..4eac624c62 --- /dev/null +++ b/examples/snippets/event-handler/rest/gettingStarted_serialization.ts @@ -0,0 +1,9 @@ +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; + +const app = new Router(); + +app.get('/ping', async () => { + return { message: 'pong' }; // (1)! +}); + +export const handler = app.resolve; diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_dynamic_routes.json b/examples/snippets/event-handler/rest/samples/gettingStarted_dynamic_routes.json new file mode 100644 index 0000000000..dd5727cc1e --- /dev/null +++ b/examples/snippets/event-handler/rest/samples/gettingStarted_dynamic_routes.json @@ -0,0 +1,5 @@ +{ + "resource": "/todos/{id}", + "path": "/todos/1", + "httpMethod": "GET" +} \ No newline at end of file diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_methods.json b/examples/snippets/event-handler/rest/samples/gettingStarted_methods.json new file mode 100644 index 0000000000..7be85e3400 --- /dev/null +++ b/examples/snippets/event-handler/rest/samples/gettingStarted_methods.json @@ -0,0 +1,6 @@ +{ + "resource": "/todos", + "path": "/todos", + "httpMethod": "POST", + "body": "{\"title\": \"foo\", \"userId\": 1, \"completed\": false}" +} \ No newline at end of file diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json b/examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json new file mode 100644 index 0000000000..a3f6051828 --- /dev/null +++ b/examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json @@ -0,0 +1,10 @@ +{ + "statusCode": 200, + "multiValueHeaders": { + "Content-Type": [ + "application/json" + ] + }, + "body": "{'message':'pong'}", + "isBase64Encoded": false +} \ No newline at end of file diff --git a/examples/snippets/event-handler/rest/templates/api_gateway.yml b/examples/snippets/event-handler/rest/templates/api_gateway.yml index 6fdd416be4..056f84d413 100644 --- a/examples/snippets/event-handler/rest/templates/api_gateway.yml +++ b/examples/snippets/event-handler/rest/templates/api_gateway.yml @@ -41,28 +41,13 @@ Resources: # explicit routes and methods are recommended for prod instead (see below) Path: /{proxy+} # Send requests on any path to the lambda function Method: ANY # Send requests using any http method to the lambda function - - - # GetAllTodos: - # Type: Api - # Properties: - # Path: /todos - # Method: GET - # GetTodoById: - # Type: Api - # Properties: - # Path: /todos/{todo_id} - # Method: GET - # CreateTodo: - # Type: Api - # Properties: - # Path: /todos - # Method: POST - - ## Swagger UI specific routes - - # SwaggerUI: - # Type: Api - # Properties: - # Path: /swagger - # Method: GET \ No newline at end of file + GetAllTodos: + Type: Api + Properties: + Path: /todos + Method: GET + GetTodoById: + Type: Api + Properties: + Path: /todos/{todo_id} + Method: GET \ No newline at end of file From acc0594b65893e515a807043036b3fa877c97af8 Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 00:09:55 +0100 Subject: [PATCH 03/30] minor grammar and code fixes --- docs/features/event-handler/rest.md | 24 +++++++++---------- .../rest/gettingStarted_serialization.ts | 12 +++++++++- .../samples/gettingStarted_serialization.json | 6 ++--- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index ba4ff37c18..2ef2809c44 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -42,9 +42,9 @@ This is the sample infrastructure for API Gateway and Lambda Function URLs we ar ### Route events -Before you start defining your routes, it's important to understand how the event handler works with different types of events. The event handler can process events from API Gateway REST APIs, and will soon support ALB, Lambda Function URLs, and VPC Lattice as well. +Before you start defining your routes, it's important to understand how the event handler works with different types of events. The event handler can process events from API Gateway REST APIs, and will soon support HTTP APIs, ALB, Lambda Function URLs, and VPC Lattice as well. -When a request is received, the event handler will automatically convert the event into a `Request` object and give you access to the current request context, including headers, query parameters, and request body, as well as path parameters via typed arguments. +When a request is received, the event handler will automatically convert the event into a [`Request`](https://developer.mozilla.org/en-US/docs/Web/API/Request) object and give you access to the current request context, including headers, query parameters, and request body, as well as path parameters via typed arguments. #### Response auto-serialization @@ -93,7 +93,7 @@ You can also nest dynamic paths, for example `/todos/:todoId/comments/:commentId ### HTTP Methods -You can use dedicated methods to specify the HTTP method that should be handled in each resolver. That is, `app.`, where the HTTP method could be `get`, `post`, `put`, `patch`, and `delete`. +You can use dedicated methods to specify the HTTP method that should be handled in each resolver. That is, `app.`, where the HTTP method could be `delete`, `get`, `head`, `patch`, `post`, `put`, `options`. === "index.ts" @@ -241,14 +241,14 @@ A monolithic function means that your final code artifact will be deployed to a _**Benefits**_ * **Code reuse.** It's easier to reason about your service, modularize it and reuse code as it grows. Eventually, it can be turned into a standalone library. -* **No custom tooling.** Monolithic functions are treated just like normal Python packages; no upfront investment in tooling. -* **Faster deployment and debugging.** Whether you use all-at-once, linear, or canary deployments, a monolithic function is a single deployable unit. IDEs like PyCharm and VSCode have tooling to quickly profile, visualize, and step through debug any Python package. +* **No custom tooling.** Monolithic functions are treated just like normal Typescript packages; no upfront investment in tooling. +* **Faster deployment and debugging.** Whether you use all-at-once, linear, or canary deployments, a monolithic function is a single deployable unit. IDEs like WebStorm and VSCode have tooling to quickly profile, visualize, and step through debug any Typescript package. _**Downsides**_ -* **Cold starts.** Frequent deployments and/or high load can diminish the benefit of monolithic functions depending on your latency requirements, due to [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"}. Always load test to pragmatically balance between your customer experience and development cognitive load. -* **Granular security permissions.** The micro function approach enables you to use fine-grained permissions & access controls, separate external dependencies & code signing at the function level. Conversely, you could have multiple functions while duplicating the final code artifact in a monolithic approach. Regardless, least privilege can be applied to either approaches. -* **Higher risk per deployment.** A misconfiguration or invalid import can cause disruption if not caught earlier in automated testing. Multiple functions can mitigate misconfigurations but they would still share the same code artifact. You can further minimize risks with multiple environments in your CI/CD pipeline. +* **Cold starts.** Frequent deployments and/or high load can diminish the benefit of monolithic functions depending on your latency requirements, due to the [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"}. Always load test to find a pragmatic balance between customer experience and developer cognitive load. +* **Granular security permissions.** The micro function approach enables you to use fine-grained permissions and access controls, separate external dependencies and code signing at the function level. Conversely, you could have multiple functions while duplicating the final code artifact in a monolithic approach. Regardless, least privilege can be applied to either approaches. +* **Higher risk per deployment.** A misconfiguration or invalid import can cause disruption if not caught early in automated testing. Multiple functions can mitigate misconfigurations but they will uld still share the same code artifact. You can further minimize risks with multiple environments in your CI/CD pipeline. #### Micro function @@ -259,14 +259,14 @@ A micro function means that your final code artifact will be different to each f _**Benefits**_ **Granular scaling.** A micro function can benefit from the [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"} to scale differently depending on each part of your application. Concurrency controls and provisioned concurrency can also be used at a granular level for capacity management. -**Discoverability.** Micro functions are easier to visualize when using distributed tracing. Their high-level architectures can be self-explanatory, and complexity is highly visible — assuming each function is named to the business purpose it serves. -**Package size.** An independent function can be significant smaller (KB vs MB) depending on external dependencies it require to perform its purpose. Conversely, a monolithic approach can benefit from [Lambda Layers](https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html){target="_blank"} to optimize builds for external dependencies. +**Discoverability.** Micro functions are easier to visualize when using distributed tracing. Their high-level architectures can be self-explanatory, and complexity is highly visible — assuming each function is named after the business purpose it serves. +**Package size.** An independent function can be significantly smaller (KB vs MB) depending on the external dependencies it requires to perform its purpose. Conversely, a monolithic approach can benefit from [Lambda Layers](https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html){target="_blank"} to optimize builds for external dependencies. _**Downsides**_ **Upfront investment.** You need custom build tooling to bundle assets, including [native bindings for runtime compatibility](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html){target="_blank"}. Operations become more elaborate — you need to standardize tracing labels/annotations, structured logging, and metrics to pinpoint root causes. -**Engineering discipline** is necessary for both approaches. Micro-function approach however requires further attention in consistency as the number of functions grow, just like any distributed system. -**Harder to share code.** Shared code must be carefully evaluated to avoid unnecessary deployments when that changes. Equally, if shared code isn't a library, your development, building, deployment tooling need to accommodate the distinct layout. +**Engineering discipline** is necessary for both approaches. However, the micro-function approach requires further attention to consistency as the number of functions grow, just like any distributed system. +**Harder to share code.** Shared code must be carefully evaluated to avoid unnecessary deployments when this code changes. Equally, if shared code isn't a library, your development, building, deployment tooling need to accommodate the distinct layout. **Slower safe deployments.** Safely deploying multiple functions require coordination — AWS CodeDeploy deploys and verifies each function sequentially. This increases lead time substantially (minutes to hours) depending on the deployment strategy you choose. You can mitigate it by selectively enabling it in prod-like environments only, and where the risk profile is applicable. Automated testing, operational and security reviews are essential to stability in either approaches. diff --git a/examples/snippets/event-handler/rest/gettingStarted_serialization.ts b/examples/snippets/event-handler/rest/gettingStarted_serialization.ts index 4eac624c62..00120a553c 100644 --- a/examples/snippets/event-handler/rest/gettingStarted_serialization.ts +++ b/examples/snippets/event-handler/rest/gettingStarted_serialization.ts @@ -1,4 +1,9 @@ import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import type { + APIGatewayProxyEvent, + APIGatewayProxyResult, + Context, +} from 'aws-lambda'; const app = new Router(); @@ -6,4 +11,9 @@ app.get('/ping', async () => { return { message: 'pong' }; // (1)! }); -export const handler = app.resolve; +export const handler = async ( + event: APIGatewayProxyEvent, + context: Context +): Promise => { + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json b/examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json index a3f6051828..12f3f9bdf1 100644 --- a/examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json +++ b/examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json @@ -1,9 +1,7 @@ { "statusCode": 200, - "multiValueHeaders": { - "Content-Type": [ - "application/json" - ] + "headers": { + "Content-Type": "application/json" }, "body": "{'message':'pong'}", "isBase64Encoded": false From 3642ebca9d270b66f4d9f80db03b7c49b3f70c4d Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 03:22:45 +0100 Subject: [PATCH 04/30] add middleware docs pt1 --- docs/features/event-handler/rest.md | 159 +++++++++++++++++- .../rest/gettingStarted_early_return.ts | 41 +++++ .../gettingStarted_fine_grained_responses.ts | 41 +++++ .../rest/gettingStarted_global_middleware.ts | 35 ++++ .../rest/gettingStarted_middleware_order.ts | 42 +++++ .../rest/gettingStarted_route_middleware.ts | 37 ++++ .../rest/gettingStarted_serialization.ts | 11 +- .../samples/gettingStarted_early_return.json | 8 + ...gettingStarted_fine_grained_responses.json | 9 + .../gettingStarted_middleware_order.json | 10 ++ 10 files changed, 381 insertions(+), 12 deletions(-) create mode 100644 examples/snippets/event-handler/rest/gettingStarted_early_return.ts create mode 100644 examples/snippets/event-handler/rest/gettingStarted_fine_grained_responses.ts create mode 100644 examples/snippets/event-handler/rest/gettingStarted_global_middleware.ts create mode 100644 examples/snippets/event-handler/rest/gettingStarted_middleware_order.ts create mode 100644 examples/snippets/event-handler/rest/gettingStarted_route_middleware.ts create mode 100644 examples/snippets/event-handler/rest/samples/gettingStarted_early_return.json create mode 100644 examples/snippets/event-handler/rest/samples/gettingStarted_fine_grained_responses.json create mode 100644 examples/snippets/event-handler/rest/samples/gettingStarted_middleware_order.json diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 2ef2809c44..8a99574cb4 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -162,13 +162,166 @@ You can configure CORS at the router level via the `cors` middleware. ### Middleware -// TODO: @svozza +```mermaid +sequenceDiagram + participant Request + participant Router + participant M1 as Middleware 1 + participant M2 as Middleware 2 + participant Handler as Route Handler + + Request->>Router: Incoming Request + Router->>M1: Execute (params, reqCtx, next) + Note over M1: Pre-processing + M1->>M2: Call next() + Note over M2: Pre-processing + M2->>Handler: Call next() + Note over Handler: Execute handler + Handler-->>M2: Return + Note over M2: Post-processing + M2-->>M1: Return + Note over M1: Post-processing + M1-->>Router: Return + Router-->>Request: Response + +``` + +Middleware are functions that execute during the request-response cycle, sitting between the +incoming request and your route handler. They provide a way to implement cross-cutting +concerns like authentication, logging, validation, and response transformation without +cluttering your route handlers. + +Each middleware function receives the following arguments: + +* **params** Route parameters extracted from the URL path +* **reqCtx** Request context containing the event, Lambda context, request, and response objects +* **next** A function to pass control to the next middleware in the chain + +Middleware can be applied globally, only on specific routes, or a combination of both. + +#### Global middleware + +You can use `app.use` to register middleware that should always run regardless of the route. + +=== "index.ts" + + ```ts hl_lines="8-17" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_global_middleware.ts:3" + ``` + +#### Route specific middleware + +You can apply middleware to specific routes by passing them as arguments before the route +handler. + +=== "index.ts" + + ```ts hl_lines="9-18 25" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_route_middleware.ts:3" + ``` + +#### Order of execution + +```mermaid +sequenceDiagram + participant Request + participant Router + participant GM as Global Middleware + participant RM as Route Middleware + participant Handler as Route Handler + + Request->>Router: Incoming Request + Router->>GM: Execute (params, reqCtx, next) + Note over GM: Pre-processing + GM->>RM: Call next() + Note over RM: Pre-processing + RM->>Handler: Call next() + Note over Handler: Execute handler + Handler-->>RM: Return + Note over RM: Post-processing + RM-->>GM: Return + Note over GM: Post-processing + GM-->>Router: Return + Router-->>Request: Response + +``` + +Middleware follow an onion pattern where global middleware executes first in pre-processing, +then route-specific middleware. After the handler executes, the order reverses for +post-processing. When middleware modify the same response properties, the middleware that +executes last in post-processing wins. + +=== "index.ts" + + ```ts hl_lines="8-11 13-16 23" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_middleware_order.ts:3" + ``` + +=== "JSON Response" + + ```json hl_lines="5" + --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_middleware_order.json" + ``` + +#### Returning early + +```mermaid +sequenceDiagram + participant Request + participant Router + participant M1 as Middleware 1 + participant M2 as Middleware 2 + participant M3 as Middleware 3 + participant Handler as Route Handler + + Request->>Router: Incoming Request + Router->>M1: Execute (params, reqCtx, next) + Note over M1: Pre-processing + M1->>M2: Call next() + Note over M2: Pre-processing + M2->>M2: Return Response (early return) + Note over M2: Post-processing + M2-->>M1: Return Response + Note over M1: Post-processing + M1-->>Router: Return Response + Router-->>Request: Response + Note over M3,Handler: Never executed + +``` + +There are cases where you may want to terminate the execution of the middleware chain early. To +do so, middleware can short-circuit processing by returning a `Response` or JSON object +instead of calling `next()`. Neither the handler nor any subsequent middleware will run +but the post-processing of already executed middleware will. + +=== "index.ts" + + ```ts hl_lines="12-17" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_early_return.ts:3" + ``` + +=== "JSON Response" + + ```json hl_lines="2" + --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_early_return.json" + ``` ### Fine grained responses -You can use the Web API's `Response` object to have full control over the response. For example, you might want to add additional headers, cookies, or set a custom content type. +You can use the Web API's `Response` object to have full control over the response. For +example, you might want to add additional headers, cookies, or set a custom content type. -// TODO: @svozza please add a code example + response sample +=== "index.ts" + + ```ts hl_lines="9-16 21-26" + --8<-- "examples/snippets/event-handler/rest/gettingStarted_fine_grained_responses.ts:3" + ``` + +=== "JSON Response" + + ```json hl_lines="4-6" + --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_fine_grained_responses.json" + ``` ### Response streaming diff --git a/examples/snippets/event-handler/rest/gettingStarted_early_return.ts b/examples/snippets/event-handler/rest/gettingStarted_early_return.ts new file mode 100644 index 0000000000..a08e90e3cf --- /dev/null +++ b/examples/snippets/event-handler/rest/gettingStarted_early_return.ts @@ -0,0 +1,41 @@ +declare function getAllTodos(): Promise<{ id: string; title: string }[]>; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import type { Middleware } from '@aws-lambda-powertools/event-handler/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import type { Context } from 'aws-lambda'; + +const logger = new Logger(); +const app = new Router({ logger }); + +// Authentication middleware - returns early if no auth header +const authMiddleware: Middleware = async (params, reqCtx, next) => { + const authHeader = reqCtx.request.headers.get('authorization'); + + if (!authHeader) { + return new Response(JSON.stringify({ error: 'Unauthorized' }), { + status: 401, + headers: { 'Content-Type': 'application/json' }, + }); + } + + await next(); +}; + +// Logging middleware - never executes when auth fails +const loggingMiddleware: Middleware = async (params, reqCtx, next) => { + logger.info('Request processed'); + await next(); +}; + +app.use(authMiddleware); +app.use(loggingMiddleware); + +app.get('/todos', async () => { + const todos = await getAllTodos(); + return { todos }; +}); + +export const handler = async (event: unknown, context: Context) => { + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/gettingStarted_fine_grained_responses.ts b/examples/snippets/event-handler/rest/gettingStarted_fine_grained_responses.ts new file mode 100644 index 0000000000..2d989f2bdb --- /dev/null +++ b/examples/snippets/event-handler/rest/gettingStarted_fine_grained_responses.ts @@ -0,0 +1,41 @@ +declare function getAllTodos(): Promise<{ id: string; title: string }[]>; +declare function createTodo( + title: string +): Promise<{ id: string; title: string }>; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import { Logger } from '@aws-lambda-powertools/logger'; +import type { Context } from 'aws-lambda'; + +const logger = new Logger(); +const app = new Router({ logger }); + +app.get('/todos', async () => { + const todos = await getAllTodos(); + + return new Response(JSON.stringify({ todos }), { + status: 200, + headers: { + 'Content-Type': 'application/json', + 'Cache-Control': 'max-age=300', + 'X-Custom-Header': 'custom-value', + }, + }); +}); + +app.post('/todos', async (params, reqCtx) => { + const body = await reqCtx.request.json(); + const todo = await createTodo(body.title); + + return new Response(JSON.stringify(todo), { + status: 201, + headers: { + Location: `/todos/${todo.id}`, + 'Content-Type': 'application/json', + }, + }); +}); + +export const handler = async (event: unknown, context: Context) => { + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/gettingStarted_global_middleware.ts b/examples/snippets/event-handler/rest/gettingStarted_global_middleware.ts new file mode 100644 index 0000000000..081aa88bec --- /dev/null +++ b/examples/snippets/event-handler/rest/gettingStarted_global_middleware.ts @@ -0,0 +1,35 @@ +declare function getAllTodos(): Promise<{ id: string; title: string }[]>; +declare function putTodo(todo: unknown): Promise<{ id: string } & T>; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import { Logger } from '@aws-lambda-powertools/logger'; +import type { Context } from 'aws-lambda'; + +const logger = new Logger(); +const app = new Router({ logger }); + +// Logging middleware - runs for all routes +app.use(async (params, reqCtx, next) => { + const start = Date.now(); + await next(); + const duration = Date.now() - start; + logger.info('Request completed', { + path: reqCtx.request.url, + duration, + }); +}); + +app.get('/todos', async () => { + const todos = await getAllTodos(); + return { todos }; +}); + +app.post('/todos', async (params, { request }) => { + const body = await request.json(); + const todo = await putTodo(body); + return todo; +}); + +export const handler = async (event: unknown, context: Context) => { + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/gettingStarted_middleware_order.ts b/examples/snippets/event-handler/rest/gettingStarted_middleware_order.ts new file mode 100644 index 0000000000..dad875582b --- /dev/null +++ b/examples/snippets/event-handler/rest/gettingStarted_middleware_order.ts @@ -0,0 +1,42 @@ +declare function getAllTodos(): Promise<{ id: string; title: string }[]>; +declare function putTodo(todo: unknown): Promise<{ id: string } & T>; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import type { Middleware } from '@aws-lambda-powertools/event-handler/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import type { Context } from 'aws-lambda'; + +const logger = new Logger(); +const app = new Router({ logger }); + +// Global middleware - executes first in pre-processing, last in post-processing +app.use(async (params, reqCtx, next) => { + reqCtx.res.headers.set('x-pre-processed-by', 'global-middleware'); + await next(); + reqCtx.res.headers.set('x-post-processed-by', 'global-middleware'); +}); + +// Route-specific middleware - executes second in pre-processing, first in post-processing +const routeMiddleware: Middleware = async (params, reqCtx, next) => { + reqCtx.res.headers.set('x-pre-processed-by', 'route-middleware'); + await next(); + reqCtx.res.headers.set('x-post-processed-by', 'route-middleware'); +}; + +app.get('/todos', async () => { + const todos = await getAllTodos(); + return { todos }; +}); + +// This route will have: +// x-pre-processed-by: route-middleware (route middleware overwrites global) +// x-post-processed-by: global-middleware (global middleware executes last) +app.post('/todos', [routeMiddleware], async (params, reqCtx) => { + const body = await reqCtx.request.json(); + const todo = await putTodo(body); + return todo; +}); + +export const handler = async (event: unknown, context: Context) => { + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/gettingStarted_route_middleware.ts b/examples/snippets/event-handler/rest/gettingStarted_route_middleware.ts new file mode 100644 index 0000000000..6a4a2798c1 --- /dev/null +++ b/examples/snippets/event-handler/rest/gettingStarted_route_middleware.ts @@ -0,0 +1,37 @@ +declare function getAllTodos(): Promise<{ id: string; title: string }[]>; +declare function putTodo(todo: unknown): Promise<{ id: string } & T>; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import type { Middleware } from '@aws-lambda-powertools/event-handler/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import type { Context } from 'aws-lambda'; + +const logger = new Logger(); +const app = new Router({ logger }); + +// Add timestamp to todo items +const addTimestamp: Middleware = async (params, reqCtx, next) => { + const body = await reqCtx.request.json(); + body.createdAt = new Date().toISOString(); + reqCtx.request = new Request(reqCtx.request.url, { + ...reqCtx.request, + body: JSON.stringify(body), + }); + await next(); +}; + +app.get('/todos', async () => { + const todos = await getAllTodos(); + return { todos }; +}); + +// Route with timestamp middleware +app.post('/todos', [addTimestamp], async (params, reqCtx) => { + const body = await reqCtx.request.json(); + const todo = await putTodo(body); + return todo; +}); + +export const handler = async (event: unknown, context: Context) => { + return app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/gettingStarted_serialization.ts b/examples/snippets/event-handler/rest/gettingStarted_serialization.ts index 00120a553c..17922b34ea 100644 --- a/examples/snippets/event-handler/rest/gettingStarted_serialization.ts +++ b/examples/snippets/event-handler/rest/gettingStarted_serialization.ts @@ -1,9 +1,5 @@ import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; -import type { - APIGatewayProxyEvent, - APIGatewayProxyResult, - Context, -} from 'aws-lambda'; +import type { APIGatewayProxyResult, Context } from 'aws-lambda'; const app = new Router(); @@ -11,9 +7,6 @@ app.get('/ping', async () => { return { message: 'pong' }; // (1)! }); -export const handler = async ( - event: APIGatewayProxyEvent, - context: Context -): Promise => { +export const handler = async (event: unknown, context: Context) => { return app.resolve(event, context); }; diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_early_return.json b/examples/snippets/event-handler/rest/samples/gettingStarted_early_return.json new file mode 100644 index 0000000000..75f76e9c68 --- /dev/null +++ b/examples/snippets/event-handler/rest/samples/gettingStarted_early_return.json @@ -0,0 +1,8 @@ +{ + "statusCode": 401, + "body": "{\"error\":\"Unauthorized\"}", + "headers": { + "Content-Type": "application/json" + }, + "isBase64Encoded": false +} \ No newline at end of file diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_fine_grained_responses.json b/examples/snippets/event-handler/rest/samples/gettingStarted_fine_grained_responses.json new file mode 100644 index 0000000000..3b4f079a6a --- /dev/null +++ b/examples/snippets/event-handler/rest/samples/gettingStarted_fine_grained_responses.json @@ -0,0 +1,9 @@ +{ + "statusCode": 201, + "body": "{\"id\":\"123\",\"title\":\"Learn TypeScript\"}", + "headers": { + "Content-Type": "application/json", + "Location": "/todos/123" + }, + "isBase64Encoded": false +} \ No newline at end of file diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_middleware_order.json b/examples/snippets/event-handler/rest/samples/gettingStarted_middleware_order.json new file mode 100644 index 0000000000..0135c632cd --- /dev/null +++ b/examples/snippets/event-handler/rest/samples/gettingStarted_middleware_order.json @@ -0,0 +1,10 @@ +{ + "statusCode": 200, + "body": "{\"id\":\"123\",\"title\":\"New todo\"}", + "headers": { + "content-type": "application/json", + "x-pre-processed-by": "route-middleware", + "x-post-processed-by": "global-middleware" + }, + "isBase64Encoded": false +} \ No newline at end of file From 021192560d7d40afb9ba4ecbaf25eeff1e7dd2a2 Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 08:47:33 +0100 Subject: [PATCH 05/30] rename snippets and json samples to have advanced_prefix --- docs/features/event-handler/rest.md | 18 ++++++++++-------- ...s.ts => advanced_fine_grained_responses.ts} | 0 ...y_return.ts => advanced_mw_early_return.ts} | 0 ...are.ts => advanced_mw_global_middleware.ts} | 0 ...rder.ts => advanced_mw_middleware_order.ts} | 0 ...ware.ts => advanced_mw_route_middleware.ts} | 0 ...on => advanced_fine_grained_responses.json} | 0 ...turn.json => advanced_mw_early_return.json} | 0 ....json => advanced_mw_middleware_order.json} | 0 9 files changed, 10 insertions(+), 8 deletions(-) rename examples/snippets/event-handler/rest/{gettingStarted_fine_grained_responses.ts => advanced_fine_grained_responses.ts} (100%) rename examples/snippets/event-handler/rest/{gettingStarted_early_return.ts => advanced_mw_early_return.ts} (100%) rename examples/snippets/event-handler/rest/{gettingStarted_global_middleware.ts => advanced_mw_global_middleware.ts} (100%) rename examples/snippets/event-handler/rest/{gettingStarted_middleware_order.ts => advanced_mw_middleware_order.ts} (100%) rename examples/snippets/event-handler/rest/{gettingStarted_route_middleware.ts => advanced_mw_route_middleware.ts} (100%) rename examples/snippets/event-handler/rest/samples/{gettingStarted_fine_grained_responses.json => advanced_fine_grained_responses.json} (100%) rename examples/snippets/event-handler/rest/samples/{gettingStarted_early_return.json => advanced_mw_early_return.json} (100%) rename examples/snippets/event-handler/rest/samples/{gettingStarted_middleware_order.json => advanced_mw_middleware_order.json} (100%) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 8a99574cb4..feff5609af 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -206,7 +206,7 @@ You can use `app.use` to register middleware that should always run regardless o === "index.ts" ```ts hl_lines="8-17" - --8<-- "examples/snippets/event-handler/rest/gettingStarted_global_middleware.ts:3" + --8<-- "examples/snippets/event-handler/rest/advanced_mw_global_middleware.ts:3" ``` #### Route specific middleware @@ -217,7 +217,7 @@ handler. === "index.ts" ```ts hl_lines="9-18 25" - --8<-- "examples/snippets/event-handler/rest/gettingStarted_route_middleware.ts:3" + --8<-- "examples/snippets/event-handler/rest/advanced_mw_route_middleware.ts:3" ``` #### Order of execution @@ -254,13 +254,13 @@ executes last in post-processing wins. === "index.ts" ```ts hl_lines="8-11 13-16 23" - --8<-- "examples/snippets/event-handler/rest/gettingStarted_middleware_order.ts:3" + --8<-- "examples/snippets/event-handler/rest/advanced_mw_middleware_order.ts:3" ``` === "JSON Response" ```json hl_lines="5" - --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_middleware_order.json" + --8<-- "examples/snippets/event-handler/rest/samples/advanced_mw_middleware_order.json" ``` #### Returning early @@ -297,15 +297,17 @@ but the post-processing of already executed middleware will. === "index.ts" ```ts hl_lines="12-17" - --8<-- "examples/snippets/event-handler/rest/gettingStarted_early_return.ts:3" + --8<-- "examples/snippets/event-handler/rest/advanced_mw_early_return.ts:3" ``` === "JSON Response" ```json hl_lines="2" - --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_early_return.json" + --8<-- "examples/snippets/event-handler/rest/samples/advanced_mw_early_return.json" ``` +#### Exception Handling + ### Fine grained responses You can use the Web API's `Response` object to have full control over the response. For @@ -314,13 +316,13 @@ example, you might want to add additional headers, cookies, or set a custom cont === "index.ts" ```ts hl_lines="9-16 21-26" - --8<-- "examples/snippets/event-handler/rest/gettingStarted_fine_grained_responses.ts:3" + --8<-- "examples/snippets/event-handler/rest/advanced_fine_grained_responses.ts:3" ``` === "JSON Response" ```json hl_lines="4-6" - --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_fine_grained_responses.json" + --8<-- "examples/snippets/event-handler/rest/samples/advanced_fine_grained_responses.json" ``` ### Response streaming diff --git a/examples/snippets/event-handler/rest/gettingStarted_fine_grained_responses.ts b/examples/snippets/event-handler/rest/advanced_fine_grained_responses.ts similarity index 100% rename from examples/snippets/event-handler/rest/gettingStarted_fine_grained_responses.ts rename to examples/snippets/event-handler/rest/advanced_fine_grained_responses.ts diff --git a/examples/snippets/event-handler/rest/gettingStarted_early_return.ts b/examples/snippets/event-handler/rest/advanced_mw_early_return.ts similarity index 100% rename from examples/snippets/event-handler/rest/gettingStarted_early_return.ts rename to examples/snippets/event-handler/rest/advanced_mw_early_return.ts diff --git a/examples/snippets/event-handler/rest/gettingStarted_global_middleware.ts b/examples/snippets/event-handler/rest/advanced_mw_global_middleware.ts similarity index 100% rename from examples/snippets/event-handler/rest/gettingStarted_global_middleware.ts rename to examples/snippets/event-handler/rest/advanced_mw_global_middleware.ts diff --git a/examples/snippets/event-handler/rest/gettingStarted_middleware_order.ts b/examples/snippets/event-handler/rest/advanced_mw_middleware_order.ts similarity index 100% rename from examples/snippets/event-handler/rest/gettingStarted_middleware_order.ts rename to examples/snippets/event-handler/rest/advanced_mw_middleware_order.ts diff --git a/examples/snippets/event-handler/rest/gettingStarted_route_middleware.ts b/examples/snippets/event-handler/rest/advanced_mw_route_middleware.ts similarity index 100% rename from examples/snippets/event-handler/rest/gettingStarted_route_middleware.ts rename to examples/snippets/event-handler/rest/advanced_mw_route_middleware.ts diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_fine_grained_responses.json b/examples/snippets/event-handler/rest/samples/advanced_fine_grained_responses.json similarity index 100% rename from examples/snippets/event-handler/rest/samples/gettingStarted_fine_grained_responses.json rename to examples/snippets/event-handler/rest/samples/advanced_fine_grained_responses.json diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_early_return.json b/examples/snippets/event-handler/rest/samples/advanced_mw_early_return.json similarity index 100% rename from examples/snippets/event-handler/rest/samples/gettingStarted_early_return.json rename to examples/snippets/event-handler/rest/samples/advanced_mw_early_return.json diff --git a/examples/snippets/event-handler/rest/samples/gettingStarted_middleware_order.json b/examples/snippets/event-handler/rest/samples/advanced_mw_middleware_order.json similarity index 100% rename from examples/snippets/event-handler/rest/samples/gettingStarted_middleware_order.json rename to examples/snippets/event-handler/rest/samples/advanced_mw_middleware_order.json From 0356fe3a8b9d2e0f63623f7ec63cbd9fb059e55f Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 10:00:02 +0100 Subject: [PATCH 06/30] add middleware exception handling section --- docs/features/event-handler/rest.md | 91 ++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index feff5609af..6f71e85af2 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -137,7 +137,7 @@ You can access request details such as headers, query parameters, and body using !!! note "Coming soon" Please open an issue if you would like us to prioritize this feature. -### Raising HTTP errors +### Throwing HTTP errors !!! note "Coming soon" Please open an issue if you would like us to prioritize this feature. @@ -308,6 +308,95 @@ but the post-processing of already executed middleware will. #### Exception Handling +```mermaid +sequenceDiagram + participant Request + participant Router + participant EH as Error Handler + participant M1 as Middleware 1 + participant M2 as Middleware 2 + participant Handler as Route Handler + + Request->>Router: Incoming Request + Router->>M1: Execute (params, reqCtx, next) + Note over M1: Pre-processing + M1->>M2: Call next() + Note over M2: Throws Exception + M2-->>M1: Exception propagated + M1-->>Router: Exception propagated + Router->>EH: Handle error + EH-->>Router: HTTP 500 Response + Router-->>Request: HTTP 500 Error + Note over Handler: Never executed + +``` + +
*Unhandled exceptions*
+ +By default, any unhandled exception in the middleware chain will be propagated as a HTTP +500 back to the client. As you would expect, unlike early return, this stops the middleware +chain entirely and no post-processing steps for any previously executed middleware will occur. + +```mermaid +sequenceDiagram + participant Request + participant Router + participant M1 as Middleware 1 + participant M2 as Middleware 2 + participant Handler as Route Handler + + Request->>Router: Incoming Request + Router->>M1: Execute (params, reqCtx, next) + Note over M1: Pre-processing + M1->>M2: Call next() + Note over M2: Exception thrown & caught + Note over M2: Handle exception gracefully + M2->>Handler: Call next() + Note over Handler: Execute handler + Handler-->>M2: Return + Note over M2: Post-processing + M2-->>M1: Return + Note over M1: Post-processing + M1-->>Router: Return + Router-->>Request: Response + +``` + +
*Handled exceptions*
+ +You can handle exceptions in middleware as you woul anywhere else, simply surround your code in +a `try`/`catch` block and processing will occur as usual. + +```mermaid +sequenceDiagram + participant Request + participant Router + participant EH as Error Handler + participant M1 as Middleware 1 + participant M2 as Middleware 2 + participant Handler as Route Handler + + Request->>Router: Incoming Request + Router->>M1: Execute (params, reqCtx, next) + Note over M1: Pre-processing + M1->>M2: Call next() + Note over M2: Intentionally throws exception + M2-->>M1: Exception propagated + M1-->>Router: Exception propagated + Router->>EH: Handle error + EH-->>Router: HTTP Error Response + Router-->>Request: HTTP Error Response + Note over Handler: Never executed + +``` + +
*Intentional exceptions*
+ +Similarly, you can choose to stop processing entirely by throwing an exception in your +middleware. Event handler provides many [built-in HTTP errors](#throwing-http-errors) that +you can use or you can throw a custom error of your own. As noted above, this means +that no post-processing of your request will occur. + ### Fine grained responses You can use the Web API's `Response` object to have full control over the response. For From e64bb96df17df584d87df6fa247589f4a21bcf1b Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 10:53:15 +0100 Subject: [PATCH 07/30] add custom middleware section --- docs/features/event-handler/rest.md | 30 ++++++++++++ .../rest/advanced_mw_custom_middleware.ts | 48 +++++++++++++++++++ .../rest/advanced_mw_destructuring_problem.ts | 31 ++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 examples/snippets/event-handler/rest/advanced_mw_custom_middleware.ts create mode 100644 examples/snippets/event-handler/rest/advanced_mw_destructuring_problem.ts diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 6f71e85af2..65d598d95f 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -397,6 +397,36 @@ middleware. Event handler provides many [built-in HTTP errors](#throwing-http-er you can use or you can throw a custom error of your own. As noted above, this means that no post-processing of your request will occur. +#### Custom middleware + +A common pattern to create reusable middleware is to implement a factory functions that +accepts configuration options and returns a middleware function. + +=== "index.ts" + + ```ts hl_lines="8-30 35 38" + --8<-- "examples/snippets/event-handler/rest/advanced_mw_custom_middleware.ts:3" + ``` + +In this example we have a middleware that acts only in the post-processing stage as all +the logic occurs after the `next` function has been called. This is so as to ensure that +the handler has run and we have access to request body. + +#### Avoiding destructuring pitfalls + +!!! warning "Critical: Never destructure the response object" + When writing middleware, always access the response through `reqCtx.res` rather than destructuring `{ res }` from the request context. Destructuring captures a reference to the original response object, which becomes stale when middleware replaces the response. + +=== "index.ts" + + ```ts hl_lines="8 15" + --8<-- "examples/snippets/event-handler/rest/advanced_mw_destructuring_problem.ts:3" + ``` + +During the middleware execution chain, the response object (`reqCtx.res`) can be replaced by +other middleware or the route handler. When you destructure the request context, you capture +a reference to the response object as it existed at that moment, not the current response. + ### Fine grained responses You can use the Web API's `Response` object to have full control over the response. For diff --git a/examples/snippets/event-handler/rest/advanced_mw_custom_middleware.ts b/examples/snippets/event-handler/rest/advanced_mw_custom_middleware.ts new file mode 100644 index 0000000000..cf9238c48a --- /dev/null +++ b/examples/snippets/event-handler/rest/advanced_mw_custom_middleware.ts @@ -0,0 +1,48 @@ +declare const compresssBody: (body: string) => Promise; + +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import type { Middleware } from '@aws-lambda-powertools/event-handler/types'; +import type { Context } from 'aws-lambda'; + +interface CompressOptions { + threshold?: number; + level?: number; +} + +// Factory function that returns middleware +const compress = (options: CompressOptions = {}): Middleware => { + return async (params, reqCtx, next) => { + await next(); + + // Check if response should be compressed + const body = await reqCtx.res.text(); + const threshold = options.threshold || 1024; + + if (body.length > threshold) { + const compressedBody = await compresssBody(body); + const compressedRes = new Response(compressedBody, reqCtx.res); + compressedRes.headers.set('Content-Encoding', 'gzip'); + reqCtx.res = compressedRes; + } + }; +}; + +const app = new Router(); + +// Use custom middleware globally +app.use(compress({ threshold: 500 })); + +app.get('/data', async () => { + return { + message: 'Large response data', + data: new Array(100).fill('content'), + }; +}); + +app.get('/small', async () => { + return { message: 'Small response' }; +}); + +export const handler = async (event: unknown, context: Context) => { + return await app.resolve(event, context); +}; diff --git a/examples/snippets/event-handler/rest/advanced_mw_destructuring_problem.ts b/examples/snippets/event-handler/rest/advanced_mw_destructuring_problem.ts new file mode 100644 index 0000000000..cc268fac6b --- /dev/null +++ b/examples/snippets/event-handler/rest/advanced_mw_destructuring_problem.ts @@ -0,0 +1,31 @@ +import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; +import type { Middleware } from '@aws-lambda-powertools/event-handler/types'; +import type { Context } from 'aws-lambda'; + +const app = new Router(); + +// ❌ WRONG: Using destructuring captures a reference to the original response +const badMiddleware: Middleware = async (params, { res }, next) => { + res.headers.set('X-Before', 'Before'); + await next(); + // This header will NOT be added because 'res' is a stale reference + res.headers.set('X-After', 'After'); +}; + +// ✅ CORRECT: Always access response through reqCtx +const goodMiddleware: Middleware = async (params, reqCtx, next) => { + reqCtx.res.headers.set('X-Before', 'Before'); + await next(); + // This header WILL be added because we get the current response + reqCtx.res.headers.set('X-After', 'After'); +}; + +app.use(goodMiddleware); + +app.get('/test', async () => { + return { message: 'Hello World!' }; +}); + +export const handler = async (event: unknown, context: Context) => { + return await app.resolve(event, context); +}; From b3bf46dd6037f03ae9d0fdfe476d1375212d75c7 Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 11:13:08 +0100 Subject: [PATCH 08/30] add middleware composition section --- docs/features/event-handler/rest.md | 19 +++++++ .../rest/advanced_mw_compose_middleware.ts | 57 +++++++++++++++++++ 2 files changed, 76 insertions(+) create mode 100644 examples/snippets/event-handler/rest/advanced_mw_compose_middleware.ts diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 65d598d95f..f3fdcc61e5 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -427,6 +427,25 @@ During the middleware execution chain, the response object (`reqCtx.res`) can be other middleware or the route handler. When you destructure the request context, you capture a reference to the response object as it existed at that moment, not the current response. +#### Composing middleware + +You can create reusable middleware stacks by using the `composeMiddleware` function to combine +multiple middleware into a single middleware function. This is useful for creating standardized +middleware combinations that can be shared across different routes or applications. + +=== "index.ts" + + ```ts hl_lines="25-26 32 35" + --8<-- "examples/snippets/event-handler/rest/advanced_mw_compose_middleware.ts:3" + ``` + +The `composeMiddleware` function maintains the same execution order as if you had applied the +middleware individually, following the onion pattern where middleware execute in order during +pre-processing and in reverse order during post-processing. + +!!! note "Composition order" + Unlike traditional function composition which typically works right-to-left, `composeMiddleware` follows the convention used by most web frameworks and executes middleware left-to-right (first to last in the array). This means `composeMiddleware([a, b, c])` executes middleware `a` first, then `b`, then `c`. + ### Fine grained responses You can use the Web API's `Response` object to have full control over the response. For diff --git a/examples/snippets/event-handler/rest/advanced_mw_compose_middleware.ts b/examples/snippets/event-handler/rest/advanced_mw_compose_middleware.ts new file mode 100644 index 0000000000..0263371543 --- /dev/null +++ b/examples/snippets/event-handler/rest/advanced_mw_compose_middleware.ts @@ -0,0 +1,57 @@ +declare const getAllTodos: () => Promise; +declare const putTodo: (body: any) => Promise; + +import { + composeMiddleware, + Router, +} from '@aws-lambda-powertools/event-handler/experimental-rest'; +import type { Middleware } from '@aws-lambda-powertools/event-handler/types'; +import { Logger } from '@aws-lambda-powertools/logger'; +import type { Context } from 'aws-lambda'; + +const logger = new Logger(); + +// Individual middleware functions +const logging: Middleware = async (params, reqCtx, next) => { + logger.info(`Request: ${reqCtx.request.method} ${reqCtx.request.url}`); + await next(); + logger.info(`Response: ${reqCtx.res.status}`); +}; + +const cors: Middleware = async (params, reqCtx, next) => { + await next(); + reqCtx.res.headers.set('Access-Control-Allow-Origin', '*'); + reqCtx.res.headers.set( + 'Access-Control-Allow-Methods', + 'GET, POST, PUT, DELETE' + ); +}; + +const rateLimit: Middleware = async (params, reqCtx, next) => { + // Rate limiting logic would go here + reqCtx.res.headers.set('X-RateLimit-Limit', '100'); + await next(); +}; + +// Compose middleware stack for all requests +const apiMiddleware = composeMiddleware([logging, cors, rateLimit]); + +const app = new Router(); + +// Use composed middleware globally +app.use(apiMiddleware); + +app.get('/todos', async () => { + const todos = await getAllTodos(); + return { todos }; +}); + +app.post('/todos', async (params, { request }) => { + const body = await request.json(); + const todo = await putTodo(body); + return todo; +}); + +export const handler = async (event: unknown, context: Context) => { + return await app.resolve(event, context); +}; From 38f5c4b3996560cae044aae73bad8e03542b8b78 Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 11:20:05 +0100 Subject: [PATCH 09/30] add goodcitizen section --- docs/features/event-handler/rest.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index f3fdcc61e5..6296353cbe 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -446,6 +446,18 @@ pre-processing and in reverse order during post-processing. !!! note "Composition order" Unlike traditional function composition which typically works right-to-left, `composeMiddleware` follows the convention used by most web frameworks and executes middleware left-to-right (first to last in the array). This means `composeMiddleware([a, b, c])` executes middleware `a` first, then `b`, then `c`. +#### Being a good citizen + +Middleware can add subtle improvements to request/response processing, but also add significant complexity if you're not careful. + +Keep the following in mind when authoring middleware for Event Handler: + +* **Call the next middleware.** If you are not returning early by returns a `Response` object + or JSON object, always ensure you call the `next` function. +* **Keep a lean scope.** Focus on a single task per middleware to ease composability and maintenance. +* **Catch your own exceptions.** Catch and handle known exceptions to your logic, unless you want to raise HTTP Errors, or propagate specific exceptions to the client. +* **Avoid destructuring the response object.** As mentioned in the [destructuring pitfalls](#avoiding-destructuring-pitfalls) section, always access the response through `reqCtx.res` rather than destructuring to avoid stale references. + ### Fine grained responses You can use the Web API's `Response` object to have full control over the response. For From 074dcddba26047081b8bc970ade426f93759529b Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:31:54 +0100 Subject: [PATCH 10/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 6296353cbe..c1bf34f20c 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -107,7 +107,7 @@ You can use dedicated methods to specify the HTTP method that should be handled --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_methods.json" ``` -If you need to accept multiple HTTP methods in a single function, or support a HTTP method for which no dedicated method exists (i.e. [`TRACE`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods/TRACE){target="_blank"}), you can use the `route` method and pass a list of HTTP methods. +If you need to accept multiple HTTP methods in a single function, or support an HTTP method for which no dedicated method exists (i.e. [`TRACE`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods/TRACE){target="_blank"}), you can use the `route` method and pass a list of HTTP methods. === "index.ts" From 7e2b6bae3c0b3f8a5f423ce1a5a35fe003d07af1 Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:33:22 +0100 Subject: [PATCH 11/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index c1bf34f20c..8759810d5c 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -496,7 +496,8 @@ For convenience, we automatically base64 encode binary responses. You can also u Like the `compress` feature, the client must send the `Accept` header with the correct media type. -!!! tip Lambda Function URLs handle binary media types automatically. +!!! tip + Lambda Function URLs handle binary media types automatically. !!! note "Coming soon" Please open an issue if you would like us to prioritize this feature. From 09b5c1e634993b6c44be7029d3182d956bc0cf50 Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:39:42 +0100 Subject: [PATCH 12/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 8759810d5c..c89b1b7dd6 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -296,7 +296,7 @@ but the post-processing of already executed middleware will. === "index.ts" - ```ts hl_lines="12-17" + ```ts hl_lines="13-18" --8<-- "examples/snippets/event-handler/rest/advanced_mw_early_return.ts:3" ``` From de60b628b5bc922c10d1da0782aec1b015377322 Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:40:18 +0100 Subject: [PATCH 13/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index c89b1b7dd6..6e30e6d89e 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -259,7 +259,7 @@ executes last in post-processing wins. === "JSON Response" - ```json hl_lines="5" + ```json hl_lines="6-7" --8<-- "examples/snippets/event-handler/rest/samples/advanced_mw_middleware_order.json" ``` From 228e2bccf4700010affb26747ffa2429c05a6c1f Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:43:42 +0100 Subject: [PATCH 14/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 6e30e6d89e..a2ea352e0d 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -253,7 +253,7 @@ executes last in post-processing wins. === "index.ts" - ```ts hl_lines="8-11 13-16 23" + ```ts hl_lines="9-14 16-21 31" --8<-- "examples/snippets/event-handler/rest/advanced_mw_middleware_order.ts:3" ``` From 7c1b0820eecb5a7915fcd5b0d672e11d6e432ab8 Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:44:15 +0100 Subject: [PATCH 15/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index a2ea352e0d..626db115a3 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -79,7 +79,7 @@ All dynamic route parameters will be available as typed object properties in the === "index.ts" - ```ts hl_lines="16" + ```ts hl_lines="14" --8<-- "examples/snippets/event-handler/rest/gettingStarted_dynamic_routes.ts:3" ``` From c1852d6f8edcd21e0419b75c0eefcf49a767769f Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:44:55 +0100 Subject: [PATCH 16/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 626db115a3..6b3d1b111c 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -465,7 +465,7 @@ example, you might want to add additional headers, cookies, or set a custom cont === "index.ts" - ```ts hl_lines="9-16 21-26" + ```ts hl_lines="14-21 28-34" --8<-- "examples/snippets/event-handler/rest/advanced_fine_grained_responses.ts:3" ``` From cce2d7e1cae1327039399671efc357ea995afa05 Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:45:49 +0100 Subject: [PATCH 17/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 6b3d1b111c..d9977940c6 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -67,7 +67,7 @@ For your convenience, when you return a JavaScript object from your route handle === "JSON response" - ```json hl_lines="8" + ```json hl_lines="6" --8<-- "examples/snippets/event-handler/rest/samples/gettingStarted_serialization.json" ``` From 8ac9dea76430d2db06808b53a1d50047a0c05e6a Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:46:08 +0100 Subject: [PATCH 18/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index d9977940c6..902aeb02b7 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -466,7 +466,7 @@ example, you might want to add additional headers, cookies, or set a custom cont === "index.ts" ```ts hl_lines="14-21 28-34" - --8<-- "examples/snippets/event-handler/rest/advanced_fine_grained_responses.ts:3" + --8<-- "examples/snippets/event-handler/rest/advanced_fine_grained_responses.ts:6" ``` === "JSON Response" From d7fcffd9ff81934423bccd44428938c92af1f173 Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:56:19 +0100 Subject: [PATCH 19/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 902aeb02b7..7f62890f29 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -364,7 +364,7 @@ sequenceDiagram
*Handled exceptions*
-You can handle exceptions in middleware as you woul anywhere else, simply surround your code in +You can handle exceptions in middleware as you would anywhere else, simply surround your code in a `try`/`catch` block and processing will occur as usual. ```mermaid From f75872dda09a11a3f20d4cc76729d8e84f5fb7e8 Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:56:46 +0100 Subject: [PATCH 20/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 7f62890f29..2917c02e73 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -452,7 +452,7 @@ Middleware can add subtle improvements to request/response processing, but also Keep the following in mind when authoring middleware for Event Handler: -* **Call the next middleware.** If you are not returning early by returns a `Response` object +* **Call the next middleware.** If you are not returning early by returning a `Response` object or JSON object, always ensure you call the `next` function. * **Keep a lean scope.** Focus on a single task per middleware to ease composability and maintenance. * **Catch your own exceptions.** Catch and handle known exceptions to your logic, unless you want to raise HTTP Errors, or propagate specific exceptions to the client. From 2f19dd3527ab50aa069cfe8a9ee5c27784a5addf Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:56:58 +0100 Subject: [PATCH 21/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 2917c02e73..3e36132a1e 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -435,7 +435,7 @@ middleware combinations that can be shared across different routes or applicatio === "index.ts" - ```ts hl_lines="25-26 32 35" + ```ts hl_lines="33-34 39" --8<-- "examples/snippets/event-handler/rest/advanced_mw_compose_middleware.ts:3" ``` From e0c1abbdb52821daa593371587f2a8059e43572a Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:57:27 +0100 Subject: [PATCH 22/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 3e36132a1e..743714be39 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -419,7 +419,7 @@ the handler has run and we have access to request body. === "index.ts" - ```ts hl_lines="8 15" + ```ts hl_lines="6 14-15" --8<-- "examples/snippets/event-handler/rest/advanced_mw_destructuring_problem.ts:3" ``` From d57eccfcd5ac7f99badc3f836df3420226f1d9e8 Mon Sep 17 00:00:00 2001 From: Stefano Vozza Date: Thu, 11 Sep 2025 11:57:43 +0100 Subject: [PATCH 23/30] Update docs/features/event-handler/rest.md Co-authored-by: Swopnil Dangol --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 743714be39..cf23fa5f28 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -404,7 +404,7 @@ accepts configuration options and returns a middleware function. === "index.ts" - ```ts hl_lines="8-30 35 38" + ```ts hl_lines="5-26 31" --8<-- "examples/snippets/event-handler/rest/advanced_mw_custom_middleware.ts:3" ``` From 6490babe33a3e506ec087a109859c8d8d76016df Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 12:09:27 +0100 Subject: [PATCH 24/30] address PR comments --- docs/features/event-handler/rest.md | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index cf23fa5f28..525216f2de 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -5,7 +5,7 @@ status: new --- !!! warning "Feature status" - This feature is under active development and may undergo significant changes. We recommend using it in non-critical workloads and [providing feedback](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) to help us improve it. + This feature is under active development and may undergo significant changes. We recommend using it in non-critical workloads and [providing feedback](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose){target="_blank"} to help us improve it. Event handler for Amazon API Gateway REST and HTTP APIs, Application Loader Balancer (ALB), Lambda Function URLs, and VPC Lattice. @@ -48,7 +48,7 @@ When a request is received, the event handler will automatically convert the eve #### Response auto-serialization -!!! tip "Want full control over the response, headers, and status code? Read about the `Response` object here." +!!! tip "Want full control over the response, headers, and status code? Read about it in the [Fine grained responses](#fine-grained-responses) section." For your convenience, when you return a JavaScript object from your route handler, we automatically perform these actions: @@ -121,7 +121,7 @@ If you need to accept multiple HTTP methods in a single function, or support an ### Data validation !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) if you would like us to prioritize this feature. ### Accessing request details @@ -130,27 +130,27 @@ You can access request details such as headers, query parameters, and body using ### Handling not found routes !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose){target="_blank"} if you would like us to prioritize this feature. ### Error handling !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose){target="_blank"} if you would like us to prioritize this feature. ### Throwing HTTP errors !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose){target="_blank"} if you would like us to prioritize this feature. ### Enabling SwaggerUI !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose){target="_blank"} if you would like us to prioritize this feature. ### Custom domains !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose){target="_blank"} if you would like us to prioritize this feature. ## Advanced @@ -478,14 +478,14 @@ example, you might want to add additional headers, cookies, or set a custom cont ### Response streaming !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) if you would like us to prioritize this feature. ### Compress You can compress with gzip and base64 encode your responses via the `compress` parameter. You have the option to pass the `compress` parameter when working with a specific route or setting the correct `Accept-Encoding` header in the `Response` object. !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) if you would like us to prioritize this feature. ### Binary responses @@ -500,7 +500,7 @@ Like the `compress` feature, the client must send the `Accept` header with the c Lambda Function URLs handle binary media types automatically. !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) if you would like us to prioritize this feature. ### Debug mode @@ -509,7 +509,7 @@ You can enable debug mode via the `POWERTOOLS_DEV` environment variable. This will enable full stack traces errors in the response, log request and responses, and set CORS in development mode. !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) if you would like us to prioritize this feature. ### OpenAPI @@ -518,14 +518,14 @@ When you enable [Data Validation](#data-validation), we use a combination of Zod In OpenAPI documentation tools like [SwaggerUI](#enabling-swaggerui), these annotations become readable descriptions, offering a self-explanatory API interface. This reduces boilerplate code while improving functionality and enabling auto-documentation. !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) if you would like us to prioritize this feature. ### Split routers As you grow the number of routes a given Lambda function should handle, it is natural to either break into smaller Lambda functions, or split routes into separate files to ease maintenance - that's where the split `Router` feature is useful. !!! note "Coming soon" - Please open an issue if you would like us to prioritize this feature. + Please [open an issue](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new/choose) if you would like us to prioritize this feature. ### Considerations @@ -554,7 +554,7 @@ _**Downsides**_ * **Cold starts.** Frequent deployments and/or high load can diminish the benefit of monolithic functions depending on your latency requirements, due to the [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"}. Always load test to find a pragmatic balance between customer experience and developer cognitive load. * **Granular security permissions.** The micro function approach enables you to use fine-grained permissions and access controls, separate external dependencies and code signing at the function level. Conversely, you could have multiple functions while duplicating the final code artifact in a monolithic approach. Regardless, least privilege can be applied to either approaches. -* **Higher risk per deployment.** A misconfiguration or invalid import can cause disruption if not caught early in automated testing. Multiple functions can mitigate misconfigurations but they will uld still share the same code artifact. You can further minimize risks with multiple environments in your CI/CD pipeline. +* **Higher risk per deployment.** A misconfiguration or invalid import can cause disruption if not caught early in automated testing. Multiple functions can mitigate misconfigurations but they will still share the same code artifact. You can further minimize risks with multiple environments in your CI/CD pipeline. #### Micro function @@ -564,16 +564,16 @@ A micro function means that your final code artifact will be different to each f _**Benefits**_ -**Granular scaling.** A micro function can benefit from the [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"} to scale differently depending on each part of your application. Concurrency controls and provisioned concurrency can also be used at a granular level for capacity management. -**Discoverability.** Micro functions are easier to visualize when using distributed tracing. Their high-level architectures can be self-explanatory, and complexity is highly visible — assuming each function is named after the business purpose it serves. -**Package size.** An independent function can be significantly smaller (KB vs MB) depending on the external dependencies it requires to perform its purpose. Conversely, a monolithic approach can benefit from [Lambda Layers](https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html){target="_blank"} to optimize builds for external dependencies. +* **Granular scaling.** A micro function can benefit from the [Lambda scaling model](https://docs.aws.amazon.com/lambda/latest/dg/invocation-scaling.html){target="_blank"} to scale differently depending on each part of your application. Concurrency controls and provisioned concurrency can also be used at a granular level for capacity management. +* **Discoverability.** Micro functions are easier to visualize when using distributed tracing. Their high-level architectures can be self-explanatory, and complexity is highly visible — assuming each function is named after the business purpose it serves. +* **Package size.** An independent function can be significantly smaller (KB vs MB) depending on the external dependencies it requires to perform its purpose. Conversely, a monolithic approach can benefit from [Lambda Layers](https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html){target="_blank"} to optimize builds for external dependencies. _**Downsides**_ -**Upfront investment.** You need custom build tooling to bundle assets, including [native bindings for runtime compatibility](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html){target="_blank"}. Operations become more elaborate — you need to standardize tracing labels/annotations, structured logging, and metrics to pinpoint root causes. -**Engineering discipline** is necessary for both approaches. However, the micro-function approach requires further attention to consistency as the number of functions grow, just like any distributed system. -**Harder to share code.** Shared code must be carefully evaluated to avoid unnecessary deployments when this code changes. Equally, if shared code isn't a library, your development, building, deployment tooling need to accommodate the distinct layout. -**Slower safe deployments.** Safely deploying multiple functions require coordination — AWS CodeDeploy deploys and verifies each function sequentially. This increases lead time substantially (minutes to hours) depending on the deployment strategy you choose. You can mitigate it by selectively enabling it in prod-like environments only, and where the risk profile is applicable. +* **Upfront investment.** You need custom build tooling to bundle assets, including [native bindings for runtime compatibility](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html){target="_blank"}. Operations become more elaborate — you need to standardize tracing labels/annotations, structured logging, and metrics to pinpoint root causes. +* **Engineering discipline** is necessary for both approaches. However, the micro-function approach requires further attention to consistency as the number of functions grow, just like any distributed system. +* **Harder to share code.** Shared code must be carefully evaluated to avoid unnecessary deployments when this code changes. Equally, if shared code isn't a library, your development, building, deployment tooling need to accommodate the distinct layout. +* **Slower safe deployments.** Safely deploying multiple functions require coordination — AWS CodeDeploy deploys and verifies each function sequentially. This increases lead time substantially (minutes to hours) depending on the deployment strategy you choose. You can mitigate it by selectively enabling it in prod-like environments only, and where the risk profile is applicable. Automated testing, operational and security reviews are essential to stability in either approaches. ## Testing your code From da98d1f6ec863ec5f1f06b2dfdf3deb72100686c Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 12:39:08 +0100 Subject: [PATCH 25/30] remove global and route specific middleware sections and re-order some text in error handling section --- docs/features/event-handler/rest.md | 117 +++++++++------------------- 1 file changed, 38 insertions(+), 79 deletions(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 525216f2de..8f25707cf9 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -162,30 +162,6 @@ You can configure CORS at the router level via the `cors` middleware. ### Middleware -```mermaid -sequenceDiagram - participant Request - participant Router - participant M1 as Middleware 1 - participant M2 as Middleware 2 - participant Handler as Route Handler - - Request->>Router: Incoming Request - Router->>M1: Execute (params, reqCtx, next) - Note over M1: Pre-processing - M1->>M2: Call next() - Note over M2: Pre-processing - M2->>Handler: Call next() - Note over Handler: Execute handler - Handler-->>M2: Return - Note over M2: Post-processing - M2-->>M1: Return - Note over M1: Post-processing - M1-->>Router: Return - Router-->>Request: Response - -``` - Middleware are functions that execute during the request-response cycle, sitting between the incoming request and your route handler. They provide a way to implement cross-cutting concerns like authentication, logging, validation, and response transformation without @@ -197,30 +173,12 @@ Each middleware function receives the following arguments: * **reqCtx** Request context containing the event, Lambda context, request, and response objects * **next** A function to pass control to the next middleware in the chain -Middleware can be applied globally, only on specific routes, or a combination of both. - -#### Global middleware - -You can use `app.use` to register middleware that should always run regardless of the route. - -=== "index.ts" - - ```ts hl_lines="8-17" - --8<-- "examples/snippets/event-handler/rest/advanced_mw_global_middleware.ts:3" - ``` +Middleware can be applied globally on all routes, only on specific routes, or a combination of both. -#### Route specific middleware - -You can apply middleware to specific routes by passing them as arguments before the route -handler. - -=== "index.ts" - - ```ts hl_lines="9-18 25" - --8<-- "examples/snippets/event-handler/rest/advanced_mw_route_middleware.ts:3" - ``` - -#### Order of execution +Middleware follow an onion pattern where global middleware executes first in pre-processing, +then route-specific middleware. After the handler executes, the order reverses for +post-processing. When middleware modify the same response properties, the middleware that +executes last in post-processing wins. ```mermaid sequenceDiagram @@ -246,10 +204,11 @@ sequenceDiagram ``` -Middleware follow an onion pattern where global middleware executes first in pre-processing, -then route-specific middleware. After the handler executes, the order reverses for -post-processing. When middleware modify the same response properties, the middleware that -executes last in post-processing wins. +#### Registering middleware + +You can use `app.use` to register middleware that should always run regardless of the route +and you can apply middleware to specific routes by passing them as arguments before the route +handler. === "index.ts" @@ -265,6 +224,11 @@ executes last in post-processing wins. #### Returning early +There are cases where you may want to terminate the execution of the middleware chain early. To +do so, middleware can short-circuit processing by returning a `Response` or JSON object +instead of calling `next()`. Neither the handler nor any subsequent middleware will run +but the post-processing of already executed middleware will. + ```mermaid sequenceDiagram participant Request @@ -289,11 +253,6 @@ sequenceDiagram ``` -There are cases where you may want to terminate the execution of the middleware chain early. To -do so, middleware can short-circuit processing by returning a `Response` or JSON object -instead of calling `next()`. Neither the handler nor any subsequent middleware will run -but the post-processing of already executed middleware will. - === "index.ts" ```ts hl_lines="13-18" @@ -306,7 +265,11 @@ but the post-processing of already executed middleware will. --8<-- "examples/snippets/event-handler/rest/samples/advanced_mw_early_return.json" ``` -#### Exception Handling +#### Error Handling + +By default, any unhandled error in the middleware chain will be propagated as a HTTP +500 back to the client. As you would expect, unlike early return, this stops the middleware +chain entirely and no post-processing steps for any previously executed middleware will occur. ```mermaid sequenceDiagram @@ -321,9 +284,9 @@ sequenceDiagram Router->>M1: Execute (params, reqCtx, next) Note over M1: Pre-processing M1->>M2: Call next() - Note over M2: Throws Exception - M2-->>M1: Exception propagated - M1-->>Router: Exception propagated + Note over M2: Throws Error + M2-->>M1: Error propagated + M1-->>Router: Error propagated Router->>EH: Handle error EH-->>Router: HTTP 500 Response Router-->>Request: HTTP 500 Error @@ -331,11 +294,10 @@ sequenceDiagram ``` -
*Unhandled exceptions*
+
*Unhandled errors*
-By default, any unhandled exception in the middleware chain will be propagated as a HTTP -500 back to the client. As you would expect, unlike early return, this stops the middleware -chain entirely and no post-processing steps for any previously executed middleware will occur. +You can handle errors in middleware as you would anywhere else, simply surround your code in +a `try`/`catch` block and processing will occur as usual. ```mermaid sequenceDiagram @@ -349,8 +311,8 @@ sequenceDiagram Router->>M1: Execute (params, reqCtx, next) Note over M1: Pre-processing M1->>M2: Call next() - Note over M2: Exception thrown & caught - Note over M2: Handle exception gracefully + Note over M2: Error thrown & caught + Note over M2: Handle error gracefully M2->>Handler: Call next() Note over Handler: Execute handler Handler-->>M2: Return @@ -362,10 +324,12 @@ sequenceDiagram ``` -
*Handled exceptions*
+
*Handled errors*
-You can handle exceptions in middleware as you would anywhere else, simply surround your code in -a `try`/`catch` block and processing will occur as usual. +Similarly, you can choose to stop processing entirely by throwing an error in your +middleware. Event handler provides many [built-in HTTP errors](#throwing-http-errors) that +you can use or you can throw a custom error of your own. As noted above, this means +that no post-processing of your request will occur. ```mermaid sequenceDiagram @@ -380,9 +344,9 @@ sequenceDiagram Router->>M1: Execute (params, reqCtx, next) Note over M1: Pre-processing M1->>M2: Call next() - Note over M2: Intentionally throws exception - M2-->>M1: Exception propagated - M1-->>Router: Exception propagated + Note over M2: Intentionally throws error + M2-->>M1: Error propagated + M1-->>Router: Error propagated Router->>EH: Handle error EH-->>Router: HTTP Error Response Router-->>Request: HTTP Error Response @@ -390,12 +354,7 @@ sequenceDiagram ``` -
*Intentional exceptions*
- -Similarly, you can choose to stop processing entirely by throwing an exception in your -middleware. Event handler provides many [built-in HTTP errors](#throwing-http-errors) that -you can use or you can throw a custom error of your own. As noted above, this means -that no post-processing of your request will occur. +
*Intentional errors*
#### Custom middleware @@ -455,7 +414,7 @@ Keep the following in mind when authoring middleware for Event Handler: * **Call the next middleware.** If you are not returning early by returning a `Response` object or JSON object, always ensure you call the `next` function. * **Keep a lean scope.** Focus on a single task per middleware to ease composability and maintenance. -* **Catch your own exceptions.** Catch and handle known exceptions to your logic, unless you want to raise HTTP Errors, or propagate specific exceptions to the client. +* **Catch your own errors.** Catch and handle known errors to your logic, unless you want to raise HTTP Errors, or propagate specific errors to the client. * **Avoid destructuring the response object.** As mentioned in the [destructuring pitfalls](#avoiding-destructuring-pitfalls) section, always access the response through `reqCtx.res` rather than destructuring to avoid stale references. ### Fine grained responses From 2bc065405596f7a077c989552f044f02eba12ca5 Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 12:43:08 +0100 Subject: [PATCH 26/30] remove unused global/route middleware snippets --- .../rest/advanced_mw_global_middleware.ts | 35 ------------------ .../rest/advanced_mw_route_middleware.ts | 37 ------------------- 2 files changed, 72 deletions(-) delete mode 100644 examples/snippets/event-handler/rest/advanced_mw_global_middleware.ts delete mode 100644 examples/snippets/event-handler/rest/advanced_mw_route_middleware.ts diff --git a/examples/snippets/event-handler/rest/advanced_mw_global_middleware.ts b/examples/snippets/event-handler/rest/advanced_mw_global_middleware.ts deleted file mode 100644 index 081aa88bec..0000000000 --- a/examples/snippets/event-handler/rest/advanced_mw_global_middleware.ts +++ /dev/null @@ -1,35 +0,0 @@ -declare function getAllTodos(): Promise<{ id: string; title: string }[]>; -declare function putTodo(todo: unknown): Promise<{ id: string } & T>; - -import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; -import { Logger } from '@aws-lambda-powertools/logger'; -import type { Context } from 'aws-lambda'; - -const logger = new Logger(); -const app = new Router({ logger }); - -// Logging middleware - runs for all routes -app.use(async (params, reqCtx, next) => { - const start = Date.now(); - await next(); - const duration = Date.now() - start; - logger.info('Request completed', { - path: reqCtx.request.url, - duration, - }); -}); - -app.get('/todos', async () => { - const todos = await getAllTodos(); - return { todos }; -}); - -app.post('/todos', async (params, { request }) => { - const body = await request.json(); - const todo = await putTodo(body); - return todo; -}); - -export const handler = async (event: unknown, context: Context) => { - return app.resolve(event, context); -}; diff --git a/examples/snippets/event-handler/rest/advanced_mw_route_middleware.ts b/examples/snippets/event-handler/rest/advanced_mw_route_middleware.ts deleted file mode 100644 index 6a4a2798c1..0000000000 --- a/examples/snippets/event-handler/rest/advanced_mw_route_middleware.ts +++ /dev/null @@ -1,37 +0,0 @@ -declare function getAllTodos(): Promise<{ id: string; title: string }[]>; -declare function putTodo(todo: unknown): Promise<{ id: string } & T>; - -import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; -import type { Middleware } from '@aws-lambda-powertools/event-handler/types'; -import { Logger } from '@aws-lambda-powertools/logger'; -import type { Context } from 'aws-lambda'; - -const logger = new Logger(); -const app = new Router({ logger }); - -// Add timestamp to todo items -const addTimestamp: Middleware = async (params, reqCtx, next) => { - const body = await reqCtx.request.json(); - body.createdAt = new Date().toISOString(); - reqCtx.request = new Request(reqCtx.request.url, { - ...reqCtx.request, - body: JSON.stringify(body), - }); - await next(); -}; - -app.get('/todos', async () => { - const todos = await getAllTodos(); - return { todos }; -}); - -// Route with timestamp middleware -app.post('/todos', [addTimestamp], async (params, reqCtx) => { - const body = await reqCtx.request.json(); - const todo = await putTodo(body); - return todo; -}); - -export const handler = async (event: unknown, context: Context) => { - return app.resolve(event, context); -}; From f7dabc736cfa1b060a9a5583606693df7082125b Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 12:55:09 +0100 Subject: [PATCH 27/30] remove unused import --- .../snippets/event-handler/rest/gettingStarted_serialization.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/snippets/event-handler/rest/gettingStarted_serialization.ts b/examples/snippets/event-handler/rest/gettingStarted_serialization.ts index 17922b34ea..5b93f14004 100644 --- a/examples/snippets/event-handler/rest/gettingStarted_serialization.ts +++ b/examples/snippets/event-handler/rest/gettingStarted_serialization.ts @@ -1,5 +1,5 @@ import { Router } from '@aws-lambda-powertools/event-handler/experimental-rest'; -import type { APIGatewayProxyResult, Context } from 'aws-lambda'; +import type { Context } from 'aws-lambda'; const app = new Router(); From 3da83bb5ea79c152898c950ee9b425026e8c7896 Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 13:33:06 +0100 Subject: [PATCH 28/30] rewording and fix PR comment --- docs/features/event-handler/rest.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 8f25707cf9..706b07e4f7 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -173,11 +173,11 @@ Each middleware function receives the following arguments: * **reqCtx** Request context containing the event, Lambda context, request, and response objects * **next** A function to pass control to the next middleware in the chain -Middleware can be applied globally on all routes, only on specific routes, or a combination of both. +Middleware can be applied on specific routes, globally on all routes, or a combination of both. -Middleware follow an onion pattern where global middleware executes first in pre-processing, -then route-specific middleware. After the handler executes, the order reverses for -post-processing. When middleware modify the same response properties, the middleware that +Middleware execution follows an onion pattern where global middleware runs first in +pre-processing, then route-specific middleware. After the handler executes, the order reverses +for post-processing. When middleware modify the same response properties, the middleware that executes last in post-processing wins. ```mermaid @@ -424,7 +424,7 @@ example, you might want to add additional headers, cookies, or set a custom cont === "index.ts" - ```ts hl_lines="14-21 28-34" + ```ts hl_lines="14-21 28-32" --8<-- "examples/snippets/event-handler/rest/advanced_fine_grained_responses.ts:6" ``` From 913dbf03f43c22adb87a38e926f942ae32ea7d3e Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 13:57:15 +0100 Subject: [PATCH 29/30] add typedoc config back to mkdocs --- mkdocs.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/mkdocs.yml b/mkdocs.yml index 3784246e87..c1af2e07d9 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -163,7 +163,12 @@ plugins: - snippets/node_modules/* - snippets/package.json - snippets/CHANGELOG.md - + - typedoc: + source: '.' + output_dir: 'api' + tsconfig: 'tsconfig.json' + options: 'typedoc.json' + name: 'API Reference' - llmstxt: markdown_description: Powertools for AWS Lambda (TypeScript) is a developer toolkit to implement Serverless best practices and increase developer velocity. It provides a suite of utilities for AWS Lambda Functions that makes tracing with AWS X-Ray, structured logging and creating custom metrics asynchronously easier. full_output: llms-full.txt From c03f0518d729076934a3f6e4dbeed8acb3152ae7 Mon Sep 17 00:00:00 2001 From: svozza Date: Thu, 11 Sep 2025 14:48:05 +0100 Subject: [PATCH 30/30] fix line number highlighting --- docs/features/event-handler/rest.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/features/event-handler/rest.md b/docs/features/event-handler/rest.md index 706b07e4f7..8de6d6d108 100644 --- a/docs/features/event-handler/rest.md +++ b/docs/features/event-handler/rest.md @@ -424,7 +424,7 @@ example, you might want to add additional headers, cookies, or set a custom cont === "index.ts" - ```ts hl_lines="14-21 28-32" + ```ts hl_lines="11-19 25-32" --8<-- "examples/snippets/event-handler/rest/advanced_fine_grained_responses.ts:6" ```