This is a cry-out for help maybe, or at least a conversation starter. I want to understand if I am the only one facing these issues or if this is a general issue not many people are talking about.
Context:
Often everywhere on the internet, when people talk about web frameworks, they praise Django. They say its very well done, no bugs, very solid. Now, more than a decade passed since I started developing apps and I’ve seen a lot during these years, but the state of the framework for me is in a bit weird state (will explain more in depth in a moment).
I’ve used PHP (Zend, Laravel, Codeigniter and Symfony) at the start then I’ve used the .Net frameworks and .NET MVC then some nodejs (express, koa, hapi) and some Golang (Fiber), all had differences, OOP, Functional, MVC, Code first, Configuration first, Plugins, Preprocessors but mostly I’ve been able to create anything I wanted, very smoothly.
In the past 2-3 years I’ve worked only with Python (specifically Django at work), some FastAPI project in my free time.
Now I want to create a showcase project, where I integrate some best practices, something I can showoff after so many years of experience.
And I want to choose Django, because its the framework I have a lot of experiences in my CV in the last years, and its the “de-facto” framework used in many places, and writing this app in Django maybe uppen my dev skills a bit, since I want to do a rather complex showcase app.
So my expectations were that I will mostly have “on the plate” everything I need to create anything I want, since many people say its the choice if you want a complex app, scalable and so on.
This is where the struggle starts:
I want to create a mobile app and the backend to be written in Django it will use GraphQL for obvious reasons and the app will have an internal chat that will use Websockets, I don’t want to use DRF because I’ve seen there are some performance penalties and other things with how DRF serialisers work, this will be a project, that will need to be able to scale seamlessly, so I will avoid any bloatware or something that slows me down.
- GraphQL:
There is no native way to use GraphQL with Django. (What?!). Ok, there is this package graphene, and actually: django-graphene - GitHub - graphql-python/graphene-django: Build powerful, efficient, and flexible GraphQL APIs with seamless Django integration.
There is a known issue with the N+1 problem in GraphQL and the solution is to use dataloaders, but their documentation on dataloaders only has examples with async: Graphene-Python
Aparently they’ve upgraded graphene and the Promises part don’t work that well.
The issue:
They actually don’t have async views working between django-graphene/django:
There is a topic with dataloaders not working (literally they do not work and no one actually makes any effort to make them work): Dataloaders not working · Issue #1425 · graphql-python/graphene-django · GitHub
One of the key things in using GraphQL and it does not work. And the documentation does not tell you anything.
If you spin up an asgi server then you might get it to work (I couldn’t), there are other people complaining on their github, with no response (I am not sure if its actively maintained anymore).
You know right now the state of Django is, support for async is not that great and your app might be even slower using Async because of the “sync_to_async” bridge.
And people in their github say that many plugins being sync might not work with Async views and its a very big mess.
I found a workaround to use someones package and basically instead of async, use sync functions and Promises and this also avoids you needing to have a asgi server with all the bad things and told them to update at least the documentation with it, but nothing happened: Enhance docs for DataLoader & django 4.0+ async examples · Issue #1390 · graphql-python/graphene-django · GitHub.
Basically you can use a package written by someone from the community:
And this helps you write graphql dataloaders in a sync manner, without needing async server and you don’t need to add sync_to_async, async_to_sync and all the other bad things on all your methods in the app just to make it work.
But django-graphene don’t want to add this to the documentation page for some reason.
Now besides the Django Async Views are not stable, sync_to_async, using sync dataloaders instead of async… having to rely on someone’s package (maybe there are bugs) for a production app, its not really what I would describe as “Mature, Scalable, Finished” and other adjectives Django receives + performance penalties between sync_to_async (async views and such).
Plus the struggle I had to endure to actually, be able to come-up with a solution that is working?
FastAPI has a mature approach, the framework is already async, you can use the Strawberry package which is very mature, why can’t this be the case with Django?
Does anyone else had this struggle? Can you tell me your experience regarding GraphQL ? Am I doing something wrong?
- Websockets (Django channels and Daphne - 2 new packages I need to install, not developed by the Django team)
No native websockets support, I need to install another package Django Channels. This will again force me to move from wsgi to asgi.
As I understood, ASGI supports sync also so I guess the rest of my app will be using sync routes (with the approach above) and the Websockets will use the async part (Can someone confirm this works in production?).
This will still force me to use async functions (which I don’t have any problem doing) - but then again, I will have all the pain with sync_to_async decorators for my websocket routes. Which I don’t like from the start because this will break the consistency of my code.
Then I’ve read there is an issue with DB connections and Django (some regression from Django 4.2) that will open too many connections to the DB, and that you will need to set the CONN_MAX_AGE = 0 and use pgbouncer ?!!
This is an issue actually with the Daphne package.
There is an open issue regarding this (last post 3 months ago):
https://code.djangoproject.com/ticket/33497
Why is this issue not a priority at Django?!
And there are people here complaining that they didn’t have this issue with Django 3, but when they upgraded to Django 4.2, they prod sites started going down, because of too many connections to the DB being made!!! Seriously !!!
So for Websockets I need CONN_MAX_AGE = 0 that will affect my db performance because of new connections for each request.
Again, this I would not call, scalable, mature and so on.
I feel like, Django is in a very weird state regarding python async (with all the sync_to_async decorators), there are a lot of bugs, and you need a lot of extra packages to get stuff working, that in the end bring new bugs and performance impact.
I did not have this issue with other web frameworks in the past, FastAPI doesn’t have any of these problems, but again, I need to develop this project in Django as a showcase because this is the framework I have listen in my CV.
Did someone else had struggles with poin 2? Is there a simpler solution that is not this hackish ?
Why is everyone saying Django is very mature, scalable and so on?
But when we talk about new tech (graphql, websockets and so on) you need extra packages, decorators, perf impact, no clear documentation on the Django site on how to use them.
What is up with all this pain? Doesn’t this framework market itself as batteries included where you have everything setup for yourself and you can just use it?
Why do I feel like if I want to use new tech, I need to hack myself to it, while other frameworks from many other languages don’t have this issue and everything just works.
And the fact that I need to rely on 3rd party packages for basic stuff (looking at you django-graphene, django channels) that many times don’t reply on issues, is also really bad. Dataloaders not working when they are one of the most important things in GraphQL… why did they migrated to a new version, if they new they won’t work? Why didn’t they waited until they had a fix?
What are your opinions on this? What am I doing wrong?