Skip to content

feat(event_handler): add Dependency injection with Depends()#8128

Open
leandrodamascena wants to merge 7 commits intodevelopfrom
feat/8099-dependency-injection
Open

feat(event_handler): add Dependency injection with Depends()#8128
leandrodamascena wants to merge 7 commits intodevelopfrom
feat/8099-dependency-injection

Conversation

@leandrodamascena
Copy link
Copy Markdown
Contributor

Issue number: closes #8099

Summary

This PR add Depends() for type-safe dependency injection in route handlers using the Annotated pattern. Dependencies are declared inline in the function signature - no decorators, no global state. This also supports nested dependencies, per-invocation caching, Request injection, and dependency_overrides for easy testing.

User experience

Before this, sharing services like a DynamoDB table across handlers required append_context - untyped, no IDE support, manual setup in every handler.

Now you declare what a handler needs directly in its signature:

import os
from typing import Any

import boto3
from typing_extensions import Annotated

from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
from aws_lambda_powertools.event_handler.openapi.params import Depends
from aws_lambda_powertools.utilities.typing import LambdaContext

app = APIGatewayHttpResolver()


def get_dynamodb_resource():
    return boto3.resource("dynamodb")


def get_orders_table(dynamodb: Annotated[Any, Depends(get_dynamodb_resource)]):
    return dynamodb.Table(os.environ["ORDERS_TABLE"])


def get_users_table(dynamodb: Annotated[Any, Depends(get_dynamodb_resource)]):
    return dynamodb.Table(os.environ["USERS_TABLE"])


@app.get("/orders/<user_id>")
def get_user_orders(
    user_id: str,
    orders_table: Annotated[Any, Depends(get_orders_table)],
    users_table: Annotated[Any, Depends(get_users_table)],
):
    user = users_table.get_item(Key={"pk": user_id})["Item"]
    orders = orders_table.query(KeyConditionExpression="pk = :uid", ExpressionAttributeValues={":uid": user_id})
    return {"user": user["name"], "orders": orders["Items"]}


def lambda_handler(event: dict, context: LambdaContext) -> dict:
    return app.resolve(event, context)

The resolver handles the rest: resolving, caching, and injecting. Dependencies can depend on other dependencies, and the whole tree is resolved automatically.

For testing, swap any dependency without monkeypatching:

app.dependency_overrides[get_dynamodb_table] = lambda: mock_table

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@leandrodamascena leandrodamascena requested a review from a team as a code owner April 7, 2026 15:17
@boring-cyborg boring-cyborg bot added documentation Improvements or additions to documentation event_handlers tests labels Apr 7, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added the size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. label Apr 7, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Apr 7, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Apr 7, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Apr 7, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Apr 8, 2026
@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Apr 8, 2026
@codecov
Copy link
Copy Markdown

codecov bot commented Apr 8, 2026

Codecov Report

❌ Patch coverage is 98.16514% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.68%. Comparing base (12aeb50) to head (5f579bc).

Files with missing lines Patch % Lines
aws_lambda_powertools/event_handler/depends.py 98.73% 0 Missing and 1 partial ⚠️
..._lambda_powertools/event_handler/openapi/params.py 90.90% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #8128      +/-   ##
===========================================
+ Coverage    96.64%   96.68%   +0.04%     
===========================================
  Files          284      285       +1     
  Lines        14079    14187     +108     
  Branches      1153     1175      +22     
===========================================
+ Hits         13606    13717     +111     
+ Misses         344      341       -3     
  Partials       129      129              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@powertools-for-aws-oss-automation powertools-for-aws-oss-automation bot added size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. and removed size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. labels Apr 8, 2026
@sonarqubecloud
Copy link
Copy Markdown

sonarqubecloud bot commented Apr 8, 2026

@leandrodamascena leandrodamascena requested a review from svozza April 8, 2026 02:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation event_handlers size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feature: Dependency Injection with Depends() for Event Handler

1 participant