question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[QUESTION] Are there plans to make class-based-views a first-class feature?

See original GitHub issue

Description

Hi @tiangolo! First off kudos on FastAPI, beautiful stuff. My team (about a dozen backenders, pinging one here @gvbgduh) are in the midst of porting out Py2 services to Py3 and thought it’d be a good time to move away from Flask and Flask-RESTful and into something that makes better use of the Py3 features (predominantly async). Thus far FastAPI/Starlette is the top contender but the one feature we’re missing the most is class-based-views (CBVs) as opposed to the defacto function-based-views (FBVs). Thus we were wondering if there’s any plans to introduce CBVs as a first-class feature in FastAPI.

While we know Starlette plays well with CBVs we looove the automagical features FastAPI offers like validation, OpenAPI generation, etc, things we had to do in very round-about ways prior.

Way we see it CBVs have the following primary perks:

  • Centralised routing since you tend to declare the different routes in one place, typically after instantiating the application.
  • Code reusability since you can easily do OOP and inherit (eg through mixins) or compose common functionality around.
  • Would make it much easier to port existing CBVs to FastAPI since we’d be coming from Flask-RESTful.

Thus far we’ve found we can ‘hack’ CBVs into FastAPI as such:

from typing import Dict

import fastapi
from starlette.endpoints import HTTPEndpoint

from app.services.api.models import Something


app = fastapi.FastAPI(debug=True)


class ResourceRoot(HTTPEndpoint):
    def get(self):
        # do stuff


class ResourceSomething(HTTPEndpoint):

    def get(self, some_id: str) -> Dict:
        # do stuff

    def post(self, something: Something) -> None:
        # do stuff


resource_root = ResourceRoot(scope={"type": "http"})
resource_something = ResourceSomething(scope={"type": "http"})
app.add_api_route(
    path="/",
    endpoint=resource_root.get,
    methods=["GET"],
)
app.add_api_route(
    path="/something",
    endpoint=resource_something.post,
    methods=["POST"]
)
app.add_api_route(
    path="/something/{some_id}",
    endpoint=resource_something.get,
    methods=["GET"]
)

and as far as we can tell we’re maintaining the FastAPI fanciness but it might be a little confusing for our devs. Is there a better way to do this?

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:69
  • Comments:38 (9 by maintainers)

github_iconTop GitHub Comments

39reactions
tarsilcommented, Nov 19, 2021

@tiangolo thank you for your FastAPI and I’ve been using it for more than an year now but I cannot disagree with the fact that using Starlette from the same creator of Django Rest Framework and seeing tools like Flask with class based view, I still struggle to understand why FastAPI does not natively support it, at all, this pushes a lot of people off and let me just try to give you a few simple examples why.

  1. Class based views apply the OOP principle, even if some people don’t like it, it’s the most used paradigm.
  2. You don’t need to repeat logic across the rest of the views. DRY principle is good and if we need to repeat our code over and over again, it becomes ugly, hard to maintain and maybe creates a lot of tech debt.
  3. Arguing that “what can you do in CBV that you can’t in function based views” I would say to read point 1 and 2.
  4. FastAPI was pointed as a tool that could bring the best of django and the best of flask in one. Here I have mixed feelings because even Flask allows both CBS and function based views as well as django.

It would be amazing to have something CBS native for FastAPI as well. This would allow us to baiscally do the moves from monoliths and flask into full FastAPI and I’m 100% sure that I’m not the only one thinking like this 😃. Again, fantastic framework.

Starlette already supports HTTPEndpoint (https://www.starlette.io/endpoints/) so I think this could be something that could be added to FastAPI.

I can’t convince my company to fully adopt it (neither the companies I worked before) because this simple feature is a killer if cannot be there.

30reactions
dmontagucommented, Jan 21, 2020

For anyone following this thread, I recently released fastapi-utils which provides a version of a class-based view.

It doesn’t support automatically inferring decorators if you name your method get, post, etc., but given the amount of info that currently goes into the decorators, I’m not sure how useful that would be anyway.

What it does do is allow you to reuse dependencies across multiple routes without repeating them in each signature by just declaring them as class attributes.

If you are interested, you can read the documentation here: https://fastapi-utils.davidmontague.xyz/user-guide/class-based-views/

Read more comments on GitHub >

github_iconTop Results From Across the Web

Why class-based views are not all that great - Medium
Class-based views were first introduced in 2010 and back then my younger self did his best to push back on the current approach....
Read more >
Introduction to class-based views - Django documentation
Class-based views provide an alternative way to implement views as Python objects instead of functions. They do not replace function-based views, but have...
Read more >
Are class based views widely used by the Django community?
1 Answer 1 ... One fact is that class based view was added in Django 1.3, so if you're planning to support old...
Read more >
Simplicity of Function Based Views and Re-usability of Class ...
CBV = class based views. In ... #django FBV = function based views. ... The idea is to make it very clear where...
Read more >
Django Rest Framework – Class Based Views - Real Python
The CreateModelMixin meanwhile provides the create() function for creating a new object in response to a POST request. Finally, the GenericAPIView mixin ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found