REST vs. GraphQL: Is it Time to Switch in Django?
For the last decade, REST (Representational State Transfer) has been the undisputed king of APIs. In the Django world, Django Rest Framework (DRF) is the gold standard.
But recently, GraphQL has challenged the throne. Developed by Facebook, it changes how frontends talk to backends. Instead of the server defining what data is sent, the client asks for exactly what it needs.
The Problem with REST
Imagine a "User Profile" screen that needs:
1. User's Name (from /api/users/1/)
2. Last 3 Posts (from /api/users/1/posts/)
3. List of Followers (from /api/users/1/followers/)
In REST, this often leads to Over-fetching (getting data you don't need) or Under-fetching (needing to make multiple HTTP requests to stitch data together).
The GraphQL Solution
With GraphQL, there is only one endpoint (usually /graphql). The frontend sends a query describing the shape of the data it wants:
query {
user(id: 1) {
username
posts(limit: 3) {
title
}
followers {
username
}
}
}
The server returns exactly that JSON structure. No more, no less.
Implementing GraphQL in Django
To do this in Python, we use Graphene-Django.
1. Installation
pip install graphene-django
Add graphene_django to your INSTALLED_APPS in settings.py.
2. Define a Schema
Unlike DRF Serializers, Graphene uses "Types".
# schema.py
import graphene
from graphene_django import DjangoObjectType
from .models import User, Post
class UserType(DjangoObjectType):
class Meta:
model = User
fields = ("id", "username", "posts")
class PostType(DjangoObjectType):
class Meta:
model = Post
fields = ("id", "title", "content")
class Query(graphene.ObjectType):
all_users = graphene.List(UserType)
user_by_id = graphene.Field(UserType, id=graphene.Int())
def resolve_all_users(root, info):
return User.objects.all()
def resolve_user_by_id(root, info, id):
return User.objects.get(pk=id)
schema = graphene.Schema(query=Query)
3. The URL
In urls.py, you only need one line:
from graphene_django.views import GraphQLView
from .schema import schema
urlpatterns = [
path("graphql", GraphQLView.as_view(graphiql=True, schema=schema)),
]
(Setting graphiql=True gives you a beautiful in-browser IDE to test your queries).
REST vs. GraphQL: The Verdict
Stick with REST (DRF) if:
- You need simple caching (HTTP caching works perfectly with REST URLs).
- You are building a public API for unknown third-party developers.
- You want robust file uploading (GraphQL file uploads are tricky).
Switch to GraphQL if:
- You have a complex mobile app where reducing network requests is critical (saving battery and data).
- Your data is highly relational and nested.
- Your frontend team wants to iterate fast without asking backend devs for new endpoints constantly.