Skip to content
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

Tech debt: limited response type handling #5326

Open
2 tasks done
tobocop2 opened this issue Oct 7, 2024 · 2 comments
Open
2 tasks done

Tech debt: limited response type handling #5326

tobocop2 opened this issue Oct 7, 2024 · 2 comments

Comments

@tobocop2
Copy link

tobocop2 commented Oct 7, 2024

Why is this needed?

Problem Statement

The AWS Lambda Powertools for Python currently provides several options for managing HTTP responses, such as:

  • Response object: Offers flexibility but lacks strong typing and adds additional boilerplate for status codes and headers management.
  • Tuple[Dict, int] (Dict + status code): Common but can lead to juggling multiple return values without type safety.
  • Dict: Simplest option yet does not handle status codes or headers well when managed manually.

These methods pose several challenges:

  1. Lack of type safety: Inconsistency in response types increases the risk of malformed responses and potential errors.
  2. Inconsistent response handling: Switching between return types can make the codebase harder to maintain, leading to more errors or inconsistent patterns.
  3. Developer friction: Developers must manually manage status codes and serialize responses, increasing cognitive load and reducing productivity.

Proposed Solution

I propose a JsonResponse generic that inherits from the Response, allowing developers to return their responses as typed, JSON-serialized Pydantic models. This offers:

  • Type safety: Developers can return JsonResponse[MyModel] directly tied to a Pydantic model, ensuring valid responses and reducing errors.

  • Consistency: Standardizing the return type across the codebase leads to more maintainable and predictable API behavior.

  • Improved developer experience: With JsonResponse, there’s no need for manual handling of status codes or serialization—it's done automatically.

Example JsonResponse implementation:

from aws_lambda_powertools.event_handler.api_gateway import Response
from typing import Generic, TypeVar
from pydantic import BaseModel

T = TypeVar("T", bound=BaseModel)


class JsonResponse(Response, Generic[T]):
    def __init__(self, content: T, status_code: int = 200):
        super().__init__(
            status_code=status_code,
            content_type="application/json",
            body=content.model_dump_json(),
        )

Here's an example of its usage:

@app.get("/thing")
def handler() -> JsonResponse[PaginatedThingResponse]:
    response: PaginatedThingResponse = get_things()
    return JsonResponse(response, status_code=HTTPStatus.OK)

Benefits

This approach addresses several key issues:

  • Enhanced type safety: By using generics tied to Pydantic models, the system ensures that API responses match the expected structure.

  • Reduced boilerplate: No need for manual response serialization or status code management.

  • Increased consistency: All API responses follow a consistent pattern, making the codebase easier to maintain and less error-prone.

Summary

The introduction of JsonResponse addresses technical debt around response handling by enforcing consistent, type-safe responses across Lambda functions. This improvement reduces the
risk of errors, enhances the developer experience, and makes the system more maintainable.

I'd be happy to make an open source contribution if this makes sense.

Which area does this relate to?

No response

Suggestion

No response

Acknowledgment

@tobocop2 tobocop2 added tech-debt Technical Debt tasks triage Pending triage from maintainers labels Oct 7, 2024
@leandrodamascena
Copy link
Contributor

Hi @tobocop2! Thanks for opening this issue too, it seems like you have good arguments here. I need to test with some code and mypy to see how this works. Have you run tools like mypy and pyright with strict typing on your side? What did they report?

I'll put this in the backlog to look at next week and bring you more accurate insights on this.

@leandrodamascena leandrodamascena moved this from Triage to Backlog in Powertools for AWS Lambda (Python) Oct 7, 2024
@leandrodamascena leandrodamascena added event_handlers openapi-schema and removed triage Pending triage from maintainers labels Oct 7, 2024
@tobocop2
Copy link
Author

tobocop2 commented Oct 7, 2024

I have not ran either of those tools but I'd be happy to work on this if it makes sense. Thank you for the quick response!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Backlog
Development

No branches or pull requests

2 participants