Skip to content

Feature request: add resolve_async() public method for async handler support #8137

@leandrodamascena

Description

@leandrodamascena

Use case

With the full async pipeline built internally (PRs 1-4), this final PR exposes resolve_async() to customers, enabling native async handler support in all Event Handler resolvers.

Solution/User Experience

app = APIGatewayHttpResolver()

# Sync - works exactly as before
@app.get("/health")
def health():
    return {"status": "ok"}

# Async - native support
@app.get("/dashboard/<user_id>")
async def get_dashboard(user_id: str):
    orders, profile = await asyncio.gather(
        get_orders(user_id),
        get_profile(user_id),
    )
    return {"orders": orders, "profile": profile}

def lambda_handler(event, context):
    return asyncio.run(app.resolve_async(event, context))

What changes:

  • Add public resolve_async(event, context) method on ApiGatewayResolver
    • Mirrors resolve() setup (proxy event construction, context population, CORS, etc.)
    • Delegates to _resolve_async() from PR 4
  • Add resolve_async() to all resolver subclasses: APIGatewayRestResolver, APIGatewayHttpResolver, ALBResolver
  • Documentation and examples
  • E2E tests

What stays the same:

  • resolve() is untouched - fully backward compatible
  • Sync and async handlers work in the same app
  • All existing middlewares (sync) work without changes
  • OpenAPI validation works with async handlers
  • Route matching, serialization, compression - all CPU-bound, stay sync

Key design decisions:

  1. resolve_async() is a new method, not a flag - explicit is better than implicit
  2. Sync middlewares work in async chain - threading bridge handles this transparently
  3. Auto-detection of async handlers - inspect.iscoroutinefunction() at the adapter level, no decorator needed
  4. Same middleware chain order - Request Validation → Router Middlewares → Route Middlewares → Response Validation → API Adapter

Out of scope:

  • Tracer / X-Ray with asyncio.gather - known X-Ray SDK issue, tracked separately
  • Async resolve() replacing sync resolve() - breaking change, resolve_async() is additive
  • Async-only validation/serialization - CPU-bound operations, no benefit from async

Alternative solutions

Acknowledgment

Metadata

Metadata

Projects

Status

Triage

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions