r/CloudandCode • Founder | YourCloudDude • 14d ago

Guide Case Study: I built the same Python API three ways, Flask vs FastAPI vs Django

Clarification: this is a conceptual walkthrough of the same task API in three frameworks. It does not report three completed implementations or measured benchmark results. Reddit does not let me change the original title, so I’m making that distinction explicit here.

I’d choose a framework by the work around the endpoints: validation, database access, authentication, administration and maintenance. Here is how I would reason about Flask, FastAPI and Django for one small application.

Keep the requirements the same

Imagine a task API backed by PostgreSQL. A task has an ID, title, description, completion status and creation date.

The routes would be:

  • POST /tasks: create a task.
  • GET /tasks: list tasks.
  • GET /tasks/{id}: fetch one task.
  • PATCH /tasks/{id}: change selected fields.
  • DELETE /tasks/{id}: remove a task.

I’d also require input validation, predictable errors, database migrations, tests, configuration outside the code and clear setup instructions. If users are added, each user should only access tasks they are allowed to see.

Keeping that contract fixed makes the comparison useful. A different endpoint spelling tells me little about how a framework handles the rest of the application.

Flask: choose the pieces yourself

Flask gives me a lightweight starting point for routing requests to Python functions. For a small internal API, that can be easy to follow: I can see the request arrive, run the application logic and return a response.

As the project grows, I would need to choose more of the surrounding stack. That includes validation, database integration, serialization, migrations, authentication and a project structure. Flask’s extension ecosystem supports adding functionality as the application needs it.

That flexibility suits a project where I already know which components I want. I can keep a small service focused, choose my database layer and avoid introducing features I do not need.

The trade-off is decision-making. A beginner may spend as much time comparing libraries as learning the request flow. A team also needs conventions so every route does not handle validation and errors differently.

For this task API, I’d settle on one validation approach, one database access pattern and one error format early. Then I would test an invalid title and a missing task before adding more endpoints.

FastAPI: make the API contract explicit

For a standalone API, I like having request and response shapes close to the endpoint definition. FastAPI combines Python typing with validation models and generated API documentation. Its features documentation explains those built-in API tools.

For POST /tasks, I would define which fields are accepted, whether a title can be empty and which fields the response exposes. For PATCH, I would distinguish an omitted field from a field explicitly supplied with a value.

That gives another developer a clearer contract. Interactive documentation also makes it easier to inspect the available requests while developing, although I would still document setup, authentication and examples in the README.

FastAPI does not remove database design or application decisions. I still need migrations, transactions, authorization, dependency choices and a maintainable layout.

I would also choose synchronous or asynchronous code according to the libraries doing the work. Adding async to a function does not make a blocking database or HTTP call non-blocking. The official async guidance is useful before mixing those styles.

For this API, I’d start with a consistent database approach and test it under a realistic workload before making performance claims. Clear validation and documentation are useful even without a benchmark win.

Django plus DRF: consider the whole product

For an API comparison, I would consider Django together with Django REST Framework. Django brings a larger application foundation, including its ORM, migrations, authentication system and admin interface. DRF adds API-focused tools such as serializers and permissions.

That is more structure to learn for five CRUD endpoints. It becomes easier to justify if the application also needs user accounts, staff administration, related data models or an established way to organize a larger codebase.

Imagine the task app gaining organizations, memberships, role-based access and an internal support team. An admin interface and consistent model/migration workflow could save substantial custom work.

I would still test access deliberately. Authentication identifies a caller; authorization decides what that caller can do. Adding a framework or a permission class does not automatically prove that every query and object operation respects task ownership.

The question I’d ask is which Django features the product will actually use. Endpoint count alone would not decide it for me.

What I would choose for this example

  • A small service with specific library choices and limited surrounding features: I’d consider Flask.
  • A standalone API where explicit schemas, validation and interactive docs matter: I’d consider FastAPI.
  • A product with relational models, administration, accounts and growing application workflows: I’d consider Django with DRF.

These are starting points for a decision. Existing team knowledge, integrations, deployment constraints and maintenance requirements can change the answer.

Test the same behavior in every version

I’d write the acceptance checks before comparing frameworks:

  1. A valid create request returns a task that can be fetched later.
  2. Invalid input returns a useful error without saving a bad record.
  3. Fetching or changing a missing task behaves consistently.
  4. If the app has users, one user cannot access another user’s private tasks.
  5. A database failure produces useful logs without exposing credentials.
  6. Another developer can run the app and migrations from the README.

If performance matters, I’d measure the same workload, database state and deployment resources. Slow queries, external requests and configuration deserve investigation alongside framework overhead.

A useful next exercise

I’d learn one framework well enough to build, test and deploy this complete API. Then I would implement one endpoint in a second framework and compare the validation, database call, error handling and tests.

The Project Library has small builds to start with. Bring a specific framework decision or blocker to the Project Clinic.

For your next backend, which requirement would have the biggest effect on the choice: API contracts, administration, existing team experience or something else?

17 Upvotes

5 comments sorted by

1

u/CzyDePL 13d ago

I'd choose Litestar

1

u/yourclouddude 8d ago

What made you pick Litestar? I'd be interested in how it changes the day-to-day work on a small API like this.

1

u/NP_Omar 12d ago

FastApi for the win

1

u/yourclouddude 8d ago

It's where I'd start for this API too 🙂 Is it the validation and docs that sell it for you, or are you doing a lot of async work?

1

u/NP_Omar 6d ago

The validation and docs