-
Notifications
You must be signed in to change notification settings - Fork 406
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
Feature request: Event Handler - enhance route functions - to carry event & context #1955
Comments
Thanks for opening your first issue here! We'll come back to you as soon as we can. |
Draft PR - #1956 |
hey @Muthuveerappanv thanks a lot for having a great level of detail and for proactively sending a draft PR - I'll make one major comment in the PR but I'm happy with it as it's a no brainier. For |
Actually, I take it back. I think I read too quickly when glancing at the Instead - please correct me - you're looking to explicitly pass If that's the case, there's been discussions on adding support for Middlewares in Event Handler - #953, the RFC #1566, a related use case #1236, and a similar feature in Chalice that we collaborated to integrate Powertools. I haven't managed to put much thought into this yet, but reviewing feedbacks one more time we're looking for:
Suggested actions from here:
|
yes this will be a good option. A middleware factory for api resolvers applicable to its routes
thumbs up to this 👍🏼
event_parser and validation can be extended to support this
can we go for a kwargs in this case (body, headers, query_params) to start with then probably think about reflection in next phase ?
swaggers docs, Redoc, generators are good to have, once we have the middleware factory & a better route UX, we can come back to it ?
there are lot of issues left open-ended, so was not sure which one to piggyback on. Also the draft PR I made for local testing purpose and used it show what I was trying to explain in the issue, I can close it.
middleware factory makes more sense, we had a similar challenge with typescript (aws-powertools/powertools-lambda-typescript#413) too. Middleware factory for event_handler (api_resolver routes) was the solution that came to our mind, but we (@karthikeyanjp) didn't pursue it considering python didn't have one (parity) 😀
yeah makes sense! |
(on a call, reading fully shortly).. btw we have a middleware factory (our first feature in Python) -> https://awslabs.github.io/aws-lambda-powertools-python/2.9.0/utilities/middleware_factory/ |
Great to hear that we're capturing the key use cases - I agree it's scattered and this is the first attempt in aggregating them. I closed the RFC, and pinned the other two issues: Middleware support (#953), API auto-doc from routes (#1236). Some answers from your questions and comments - as it's longer than I'd imagined, I'll create a new comment with a suggested order on what next steps looks like off this conversation (thank you!!)
I'd like to avoid making yet another decorator in the routes, as one of the feedbacks we get from non-developers is that they sometimes get confused with the order (decorator stacking). Instead, it'd be great to offer an UX where you might (A) have an additional parameter in the route definition to validate input/output, or (B) built-in middlewares customers can plug-n-play. I like the latter as it's one less set of parameters to remember, and Event Handler would take care of passing a copy of the Rough example from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.utilities.typing import LambdaContext
from aws_lambda_powertools.event_handler.middlewares import json_schema_validator
app = APIGatewayRestResolver()
# Factory that
# 1. Acts as a thin wrapper for the Validation utility as a thin wrapper
# 2. Returns an Event Handler middleware that can validate the body, querystring, or params since it has access to the App instance
schema_validator = json_schema_validator(inbound_schema=SCHEMA_IN, outbound_schema=SCHEMA_OUT, query_strings=True, payload=True, **other_options)
@app.get("/todos", middlewares=[schema_validator])
@tracer.capture_method
def get_todos():
...
def lambda_handler(event: dict, context: LambdaContext) -> dict:
return app.resolve(event, context)
The part I'm trying to wrap my head around on kwargs is - when would this be more appropriate vs accessing As in, if we add middleware support, do we still need it? Is it primarily convenience to not have to type
Yes! Middleware is more important as it unlocks a range of use cases and areas we need to get better at before coming to this. While I see the pattern emerging for lift-n-shift and onboarding developers to Serverless quickly, I'm still on the fence about this feature if I'm honest due to the trade-offs on having a single function for this to be worthy (I could be wrong). |
Suggested next steps:
Writing a middleware
Registering a middleware
|
|
These are great @Muthuveerappanv - agree with all of them. We're good to go for an implementation now - 1 PR to implement a decorator factory in Middleware Factory utility, and 1 PR to implement Middleware support in Event Handler (before/after, etc.) Adding a |
Prioritizing it for our next iteration May 8th-May 19th. We'll check how much of a perf penalty this adds in practice. If it doesn't we'll work and launch within that timeframe :) Otherwise, we'll look into adding that support in a newer Resolver with Pydantic support + OpenAPI docs auto-generation |
cc @rafaelgsr as we discussed to prioritize the middleware first, then a POC create a contract to integrate with Chalice-Spec for OpenAPI auto-generation |
I wanted to return to this one and see if the Event Handler middleware implementation resolves this issue for @Muthuveerappanv. Are there still gaps for you? The middleware handlers will enable the injection of named parameters (if you want), or you can add to the context object using append_context which I find to be a super-useful feature. Powertools clears this context after each route invocation. |
@walmsles Thanks for contributing the |
Hi @guywilsonjr - thank you for using it. I recommend raising this request as a separate feature request. The existing implementation restricts the JSON schema validation to the request body, so it is payload validation only as-is, and the query parameters will not be included. Raising this as a separate request will make this issue more visible and open for wider comment. let me know if I can help at all. |
I completely missed resolving this as it was added last year re:Invent -- Data Validation feature. https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#data-validation We now handle both data validation (Pydantic), inject request data (body/header/query_string/etc), and auto-serialize response based on type annotations. Something else we briefly discussed - having a |
|
Use case
Event Handler Router - Imrprovements
Currently the route endpoints of
event_handler
don't take any function parameters other than url path variables as positional parametersThis makes it difficult for introducing many use-cases within the route as the body, query-params can be accessed from only the
app
variable.parser
utility is a great tool but cant be used readily with routes. For different endpoints inevent_handler
the body might be different, in which case the event_parser doesn't help much as it can be applied only at the handler level.A
router_parser
utility would greatly help at the route function level, but due to the limitation mentioned about in theevent_handler
the route functions aren't extendible.Solution/User Experience
Passing the
event
andcontext
to the routes as named arguments, will help overcome the limitationUser Experience
Change Proposed
app.resolve
invokes the route as shown here, requesting it to be changed to belowThis change will pave to
route_parser
like utilities that will help take away a lot of boiler plate implementation ofpydantic
parser. It will also enableroutes
to take full advantage of the parser utility, which is not the case today as parser decorators can only be applied at thehandler
proposal for the route_parser would roughly look like this
Alternative solutions
No response
Acknowledgment
The text was updated successfully, but these errors were encountered: