generated from amazon-archives/__template_MIT-0
    
        
        - 
                Notifications
    You must be signed in to change notification settings 
- Fork 455
feat(event_handlers): Add support for Lambda Function URLs #1408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
          
     Merged
      
      
            heitorlessa
  merged 10 commits into
  aws-powertools:develop
from
rubenfonseca:feat/lambda-function-urls
  
      
      
   
  Aug 4, 2022 
      
    
  
     Merged
                    Changes from all commits
      Commits
    
    
            Show all changes
          
          
            10 commits
          
        
        Select commit
          Hold shift + click to select a range
      
      a8b3f48
              
                feat(event_sources): add support for Lambda Function URL events
              
              
                rubenfonseca aca525c
              
                feat(event_handlers): add support for Lambda Function URL
              
              
                rubenfonseca cb3bc5b
              
                chore(docs): add documentation for Lambda Functoin URLs
              
              
                rubenfonseca 1039c04
              
                chore(docs): remove file commited by mistake
              
              
                rubenfonseca febe483
              
                chore(docs): updated links
              
              
                rubenfonseca 184d84f
              
                chore(docs): typo
              
              
                rubenfonseca 0711e6d
              
                chore: typos
              
              
                rubenfonseca a47f6eb
              
                chore(event_handlers): apply suggestions from code review
              
              
                rubenfonseca 8ccf4b6
              
                chore(tests): add missing new line
              
              
                rubenfonseca eaebeee
              
                chore(tests): typo
              
              
                rubenfonseca File filter
Filter by extension
Conversations
          Failed to load comments.   
        
        
          
      Loading
        
  Jump to
        
          Jump to file
        
      
      
          Failed to load files.   
        
        
          
      Loading
        
  Diff view
Diff view
There are no files selected for viewing
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
        
          
  
    
      
          
            53 changes: 53 additions & 0 deletions
          
          53 
        
  aws_lambda_powertools/event_handler/lambda_function_url.py
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
| from typing import Callable, Dict, List, Optional | ||
|  | ||
| from aws_lambda_powertools.event_handler import CORSConfig | ||
| from aws_lambda_powertools.event_handler.api_gateway import ApiGatewayResolver, ProxyEventType | ||
| from aws_lambda_powertools.utilities.data_classes import LambdaFunctionUrlEvent | ||
|  | ||
|  | ||
| class LambdaFunctionUrlResolver(ApiGatewayResolver): | ||
| """AWS Lambda Function URL resolver | ||
|  | ||
| Notes: | ||
| ----- | ||
| Lambda Function URL follows the API Gateway HTTP APIs Payload Format Version 2.0. | ||
|  | ||
| Documentation: | ||
| - https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html | ||
| - https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-payloads | ||
|  | ||
| Examples | ||
| -------- | ||
| Simple example integrating with Tracer | ||
|  | ||
| ```python | ||
| from aws_lambda_powertools import Tracer | ||
| from aws_lambda_powertools.event_handler import LambdaFunctionUrlResolver | ||
|  | ||
| tracer = Tracer() | ||
| app = LambdaFunctionUrlResolver() | ||
|  | ||
| @app.get("/get-call") | ||
| def simple_get(): | ||
| return {"message": "Foo"} | ||
|  | ||
| @app.post("/post-call") | ||
| def simple_post(): | ||
| post_data: dict = app.current_event.json_body | ||
| return {"message": post_data} | ||
|  | ||
| @tracer.capture_lambda_handler | ||
| def lambda_handler(event, context): | ||
| return app.resolve(event, context) | ||
| """ | ||
|  | ||
| current_event: LambdaFunctionUrlEvent | ||
|  | ||
| def __init__( | ||
| self, | ||
| cors: Optional[CORSConfig] = None, | ||
| debug: Optional[bool] = None, | ||
| serializer: Optional[Callable[[Dict], str]] = None, | ||
| strip_prefixes: Optional[List[str]] = None, | ||
| ): | ||
| super().__init__(ProxyEventType.LambdaFunctionUrlEvent, cors, debug, serializer, strip_prefixes) | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              
        
          
  
    
      
          
            18 changes: 18 additions & 0 deletions
          
          18 
        
  aws_lambda_powertools/utilities/data_classes/lambda_function_url_event.py
  
  
      
      
   
        
      
      
    
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| from aws_lambda_powertools.utilities.data_classes.api_gateway_proxy_event import APIGatewayProxyEventV2 | ||
|  | ||
|  | ||
| class LambdaFunctionUrlEvent(APIGatewayProxyEventV2): | ||
| """AWS Lambda Function URL event | ||
|  | ||
| Notes: | ||
| ----- | ||
| Lambda Function URL follows the API Gateway HTTP APIs Payload Format Version 2.0. | ||
|  | ||
| Keys related to API Gateway features not available in Function URL use a sentinel value (e.g.`routeKey`, `stage`). | ||
|  | ||
| Documentation: | ||
| - https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html | ||
| - https://docs.aws.amazon.com/lambda/latest/dg/urls-invocation.html#urls-payloads | ||
| """ | ||
|  | ||
| pass | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
              | Original file line number | Diff line number | Diff line change | 
|---|---|---|
|  | @@ -3,11 +3,11 @@ title: REST API | |
| description: Core utility | ||
| --- | ||
|  | ||
| Event handler for Amazon API Gateway REST and HTTP APIs, and Application Loader Balancer (ALB). | ||
| Event handler for Amazon API Gateway REST and HTTP APIs, Application Loader Balancer (ALB), and Lambda Function URLs. | ||
|  | ||
| ## Key Features | ||
|  | ||
| * Lightweight routing to reduce boilerplate for API Gateway REST/HTTP API and ALB | ||
| * 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 [Event Source Data Classes utilities](../../utilities/data_classes.md){target="_blank"} for self-documented event schema | ||
|  | ||
|  | @@ -18,23 +18,31 @@ Event handler for Amazon API Gateway REST and HTTP APIs, and Application Loader | |
|  | ||
| ### Required resources | ||
|  | ||
| You must have an existing [API Gateway Proxy integration](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html){target="_blank"} or [ALB](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html){target="_blank"} configured to invoke your Lambda function. | ||
| If you're using any API Gateway integration, you must have an existing [API Gateway Proxy integration](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html){target="_blank"} or [ALB](https://docs.aws.amazon.com/elasticloadbalancing/latest/application/lambda-functions.html){target="_blank"} configured to invoke your Lambda function. | ||
|  | ||
| This is the sample infrastructure for API Gateway 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. | ||
|  | ||
| ???+ info "There is no additional permissions or dependencies required to use this utility." | ||
|  | ||
| ```yaml title="AWS Serverless Application Model (SAM) example" | ||
| --8<-- "examples/event_handler_rest/sam/template.yaml" | ||
| ``` | ||
| === "API Gateway SAM Template" | ||
|  | ||
| ```yaml title="AWS Serverless Application Model (SAM) example" | ||
| --8<-- "examples/event_handler_rest/sam/template.yaml" | ||
| ``` | ||
|  | ||
| === "Lambda Function URL SAM Template" | ||
|  | ||
| ```yaml title="AWS Serverless Application Model (SAM) example" | ||
| --8<-- "examples/event_handler_lambda_function_url/sam/template.yaml" | ||
| ``` | ||
|  | ||
| ### Event Resolvers | ||
|  | ||
| Before you decorate your functions to handle a given path and HTTP method(s), you need to initialize a resolver. | ||
|  | ||
| A resolver will handle request resolution, including [one or more routers](#split-routes-with-router), and give you access to the current event via typed properties. | ||
|  | ||
| For resolvers, we provide: `APIGatewayRestResolver`, `APIGatewayHttpResolver`, and `ALBResolver`. | ||
| For resolvers, we provide: `APIGatewayRestResolver`, `APIGatewayHttpResolver`, `ALBResolver`, and `LambdaFunctionUrlResolver` . | ||
|  | ||
| ???+ info | ||
| We will use `APIGatewayRestResolver` as the default across examples. | ||
|  | @@ -87,6 +95,22 @@ When using Amazon Application Load Balancer (ALB) to front your Lambda functions | |
| --8<-- "examples/event_handler_rest/src/getting_started_alb_api_resolver.py" | ||
| ``` | ||
|  | ||
| #### Lambda Function URL | ||
|  | ||
| When using [AWS Lambda Function URL](https://docs.aws.amazon.com/lambda/latest/dg/urls-configuration.html), you can use `LambdaFunctionUrlResolver`. | ||
|  | ||
| === "getting_started_lambda_function_url_resolver.py" | ||
|  | ||
| ```python hl_lines="5 11" title="Using Lambda Function URL resolver" | ||
| --8<-- "examples/event_handler_lambda_function_url/src/getting_started_lambda_function_url_resolver.py" | ||
| ``` | ||
|  | ||
| === "getting_started_lambda_function_url_resolver.json" | ||
|  | ||
| ```json hl_lines="4-5" title="Example payload delivered to the handler" | ||
| --8<-- "examples/event_handler_lambda_function_url/src/getting_started_lambda_function_url_resolver.json" | ||
| ``` | ||
|  | ||
| ### Dynamic routes | ||
|  | ||
| You can use `/todos/<todo_id>` to configure dynamic URL paths, where `<todo_id>` will be resolved at runtime. | ||
|  | @@ -270,7 +294,7 @@ This will ensure that CORS headers are always returned as part of the response w | |
|  | ||
| #### Pre-flight | ||
|  | ||
| Pre-flight (OPTIONS) calls are typically handled at the API Gateway level as per [our sample infrastructure](#required-resources), no Lambda integration necessary. However, ALB expects you to handle pre-flight requests. | ||
| Pre-flight (OPTIONS) calls are typically handled at the API Gateway or Lambda Function URL level as per [our sample infrastructure](#required-resources), no Lambda integration is necessary. However, ALB expects you to handle pre-flight requests. | ||
|  | ||
| For convenience, we automatically handle that for you as long as you [setup CORS in the constructor level](#cors). | ||
|  | ||
|  | @@ -339,6 +363,8 @@ Like `compress` feature, the client must send the `Accept` header with the corre | |
| ???+ warning | ||
| This feature requires API Gateway to configure binary media types, see [our sample infrastructure](#required-resources) for reference. | ||
|  | ||
| ???+ note | ||
| Lambda Function URLs handle binary media types automatically. | ||
| === "binary_responses.py" | ||
|  | ||
| ```python hl_lines="14 20" | ||
|  | @@ -380,7 +406,7 @@ This will enable full tracebacks errors in the response, print request and respo | |
|  | ||
| ### Custom serializer | ||
|  | ||
| You can instruct API Gateway handler to use a custom serializer to best suit your needs, for example take into account Enums when serializing. | ||
| You can instruct event handler to use a custom serializer to best suit your needs, for example take into account Enums when serializing. | ||
|  | ||
| ```python hl_lines="35 40" title="Using a custom JSON serializer for responses" | ||
| --8<-- "examples/event_handler_rest/src/custom_serializer.py" | ||
|  | @@ -501,7 +527,7 @@ A micro function means that your final code artifact will be different to each f | |
|  | ||
| **Downsides** | ||
|  | ||
| * **Upfront investment**. You need custom build tooling to bundle assets, including [C 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. | ||
| * **Upfront investment**. You need custom build tooling to bundle assets, including [C 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. | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. great catch!! | ||
| * 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. | ||
|  | ||
      
      Oops, something went wrong.
        
    
  
  Add this suggestion to a batch that can be applied as a single commit.
  This suggestion is invalid because no changes were made to the code.
  Suggestions cannot be applied while the pull request is closed.
  Suggestions cannot be applied while viewing a subset of changes.
  Only one suggestion per line can be applied in a batch.
  Add this suggestion to a batch that can be applied as a single commit.
  Applying suggestions on deleted lines is not supported.
  You must change the existing code in this line in order to create a valid suggestion.
  Outdated suggestions cannot be applied.
  This suggestion has been applied or marked resolved.
  Suggestions cannot be applied from pending reviews.
  Suggestions cannot be applied on multi-line comments.
  Suggestions cannot be applied while the pull request is queued to merge.
  Suggestion cannot be applied right now. Please check back later.
  
    
  
    
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to future self: we should improve the return type to a more accurate one with
@overload.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note to future self: wait for python 3.10 to actually have proper pattern matching