aws-powertools / powertools-lambda-python

A developer toolkit to implement Serverless best practices and increase developer velocity.
https://docs.powertools.aws.dev/lambda/python/latest/
MIT No Attribution
2.79k stars 386 forks source link

More full examples of the micro function pattern #902

Closed beck3905 closed 11 months ago

beck3905 commented 2 years ago

What were you initially searching for in the docs?

I am new to powertools and have been reading the docs to determine how to integrate it into my existing projects. My project use the micro function pattern for API Gateway. All of the API Gateway code examples and discussion are more relevant to the monolith pattern. There is the discussion of monolith vs micro function, but no actual code examples for the micro function pattern.

For example, with the micro function pattern would one still use the ApiGatewayResolver when there is only one route? Or would one use the @event_source decorator approach instead?

Is this related to an existing part of the documentation? Please share a link https://awslabs.github.io/aws-lambda-powertools-python/latest/core/event_handler/api_gateway/#considerations https://awslabs.github.io/aws-lambda-powertools-python/latest/core/event_handler/api_gateway/ https://awslabs.github.io/aws-lambda-powertools-python/latest/utilities/data_classes/#api-gateway-proxy

Describe how we could make it clearer Please add more examples for the micro function pattern. Please add more details about when you would use the ApiGatewayResolver vs the event_source decorator or if you would ever use both together.

If you have a proposed update, please share it here

boring-cyborg[bot] commented 2 years ago

Thanks for opening your first issue here! We'll come back to you as soon as we can.

heitorlessa commented 2 years ago

Hey Brian, absolutely, it’s on our radar - I’d like us to provide a SAM CLI / Cookiecutter template where you could choose between micro or monolithic deployment.

Until we get there, you can totally use ApiGatewayResolver even if it’s for a single route - I personally did that in a project yesterday.

We’re releasing exception handling for any status code and custom exception for ApiGatewayResolver in the next release (either tomorrow or Monday the latest) — this comes in handy whether you have a micro or monolithic deployment.

If you have ideas or areas you find challenging with micro functions, please leave them in the comments as we could use them to make a good opinionated sample.

On Thu, 16 Dec 2021 at 18:08, boring-cyborg[bot] @.***> wrote:

Thanks for opening your first issue here! We'll come back to you as soon as we can.

— Reply to this email directly, view it on GitHub https://github.com/awslabs/aws-lambda-powertools-python/issues/902#issuecomment-996011492, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZPQBCQN5CA3GKRMSQ72FLURIMJ7ANCNFSM5KG2TVMQ . You are receiving this because you are subscribed to this thread.Message ID: @.***>

beck3905 commented 2 years ago

@heitorlessa Thanks for your response. Is there a simple way to handle translation of input and output for Api Gateway Proxy events without having to use the whole router? For a microfunction I don't really need the router capabilities.

heitorlessa commented 2 years ago

I'd still advise to use the Event Handler for API Gateway - you'd be surprised by the amount of intricacies on input/output, serialization, 404, CORS (if used), binary (if used).

For context: Historically, we created Event Source Data Classes first as most micro functions only needed the Input from API Gateway event and its variations, until more customers started to hit other corners like path parameters, or wanting to easily switch between API Gateway and ALB and AppSync (to an extent), or even non-Lambda like Fargate -- for the latter, it's a no brainier to move to something like Flask/FastAPI or simply keep API Gateway Resolver if ALB is fronting it.

Without knowing much about your use case, here's what I did yesterday with a customer for a single route and function:

import base64

from aws_lambda_powertools import Logger, Metrics, Tracer
from aws_lambda_powertools.event_handler.api_gateway import ApiGatewayResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.utilities.typing import LambdaContext

tracer = Tracer()
logger = Logger()
metrics = Metrics()
app = ApiGatewayResolver()

@app.post("/trip")
@tracer.capture_method
def ingest_trip_route():
    """Handles `/trip` POST method to ingest trip onto S3/SQS

    Returns
    -------
    response: dict
        Successful message on trip upload and receipt containing
        storage filename + enqueued message identifier

        **Example**

        ```python
        {
            "message": "trip successfully uploaded",
            "receipt":"5c6d96c4ca8748b59ff82dc0d0cfd37f+fake-message-receipt-id"
        }
"""
trip_payload: str = app.current_event.body
trip_archive: bytes = base64.b64decode(trip_payload)
...

return { 
    "message": "trip successfully uploaded",
    "receipt": f"{storage_filename}+{enqueued_message_id}"
}

@metrics.log_metrics(capture_cold_start_metric=True) @tracer.capture_lambda_handler @logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST) def lambda_handler(event, context: LambdaContext): """Lambda Handler for all routes defined in API Gateway

Parameters
----------
event: dict
    API Gateway raw event
context: LambdaContext
    Lambda Context

Returns
-------
response: dict
    API Gateway Proxy response

    **Example**

    ```python
    {
        'statusCode': 200,
        'body': {
            "message": "trip successfully uploaded",
            "receipt":"5c6d96c4ca8748b59ff82dc0d0cfd37f+fake-message-receipt-id"
        },
        'headers': {'Content-Type': 'application/json'}
        'isBase64Encoded' False
    }
    ```
"""
try:
    return app.resolve(event, context)
except Exception as e:
    logger.exception(e)
    raise


We also allow any regex for the route in case you wanna do [a catch all style](https://awslabs.github.io/aws-lambda-powertools-python/latest/core/event_handler/api_gateway/#catch-all-routes). Today's release will allow multiple HTTP Methods for a single route too.

PS: Thank you for joining us on Slack! 
stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

TonySherman commented 1 year ago

@heitorlessa - I appreciate your help and call the other day. I believe what my team is using would be considered the micro function pattern. We are using individual lambdas and adding them as API Gateway integrations via our cdk.

If that fits this use case, I think I could provide some examples for documentation.

My team ultimately decided to use micro functions to keep our lambdas single purpose and have a little more control over each lambda configuration for memory, vpc's, etc. We still found a lot of useful resources/examples in the event_handler documentation.

heitorlessa commented 1 year ago

That would be super helpful if you have the bandwidth to make a PR, Tony!!

Happy to guide if you ever get stuck

On Sun, 30 Jul 2023 at 01:36, Tony Sherman @.***> wrote:

@heitorlessa https://github.com/heitorlessa - I appreciate your help and call the other day. I believe what my team is using would be considered the micro function pattern. We are using individual lambdas and adding them as API Gateway integrations via our cdk.

If that fits this use case, I think I could provide some examples for documentation.

My team ultimately decided to use micro functions to keep our lambdas single purpose and have a little more control over each lambda configuration for memory, vpc's, etc. We still found a lot of useful resources/examples in the event_handler documentation.

— Reply to this email directly, view it on GitHub https://github.com/aws-powertools/powertools-lambda-python/issues/902#issuecomment-1656960249, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAZPQBAADGS3OR3ZCX6LW6DXSWM7FANCNFSM5KG2TVMQ . You are receiving this because you were mentioned.Message ID: @.***>

leandrodamascena commented 12 months ago

Hi @TonySherman! What do you think about submitting a PR with these examples for documentation? Micro-function vs Fat Lambda is a subject that many of our customers have doubts about. Your examples can help a lot to make our documentation clearer for those who want to use micro-function patterns.

Let me know if you need help to send this PR, we can work together.

Thanks

TonySherman commented 12 months ago

@leandrodamascena I briefly started work on this and unfortunately ran out of time.

The good news is that my employer is allotting some time to work on this issue. I'm hoping it will be in our next sprint that starts next week.

The Powertools team was so helpful in getting our micro function implementation up! Hoping we can pay it back with a contribution soon.

leandrodamascena commented 11 months ago

The good news is that my employer is allotting some time to work on this issue. I'm hoping it will be in our next sprint that starts next week.

Thanks a lot, @TonySherman! If you need help, please reach me out!

TonySherman commented 11 months ago

Just confirming that I was given some bandwidth to work on this update this week. I will reach out if I have any issues or questions.

github-actions[bot] commented 11 months ago

⚠️COMMENT VISIBILITY WARNING⚠️

This issue is now closed. Please be mindful that future comments are hard for our team to see.

If you need more assistance, please either tag a team member or open a new issue that references this one.

If you wish to keep having a conversation with other community members under this issue feel free to do so.