[QUESTION] Are there plans to make class-based-views a first-class feature?
See original GitHub issueDescription
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:
- Created 4 years ago
- Reactions:69
- Comments:38 (9 by maintainers)
Top GitHub Comments
@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.
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.
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/