Hello, world👋 Welcome to this new article. Today we will learn about GraphQL with Django. The complete code for this article can be found at graphene-django-article
Introduction
Before GraphQL was introduced by Facebook in 2015, REST(Representational State Transfer) was the standard approach or paradigm for designing web APIs. Just like other technologies REST has its perceived strength and weaknesses which eventually led to the evolution of GraphQL.
What you will learn in this article ✔
- REST overview, perceive weaknesses
- GraphQL overview
- GraphQL-Django setup
- Fetching data with GraphQL
1. REST
REST stands for Representational State Transfer, it's a set of rules developers follow when building APIs. It basically determines how the API should look like and how it should be accessed and was the standard for designing APIs before GraphQL was introduced. Some features of the REST architecture for building APIs include simple to build, structured access to resources.
Some Perceived Weaknesses
- Inflexible to rapidly changing requirements - this is because every query is being programmed at the backend and we can only send requests to an endpoint and possibly get data according to the queries on the backend.
- Over fetching data
- Under fetching data
for example, to access any resource that is not specified by the endpoints above, we have to dive into the backend and create new URLs, views, and serializer, and basically, a whole new endpoint and that is not really flexible. When building applications, some general app data requirements include real-time collaboration, fine-grained access to data, flexible database options, fetching only required data, etc and REST does not really do a great job in providing all these app requirements which led to the introduction of GraphQL.
2. GraphQL
According to the official documentation "GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools".
Features of GraphQL
- GraphQL enables declarative data fetching
- GraphQL exposes a single endpoint
- GraphQL response with precise data from clients requests
With GraphQL, a frontend developer can declare flexible queries in the frontend through a single endpoint and get a response with the precise data needed. GraphQL basically gives the clients the power to ask for exactly what they need and nothing more.
An example of a GraphQL query is given below
query {
posts {
title
author {
name
age
}
}
}
3. GraphQL and Django Setup
Before we configure Django with GraphQL let's create a basic Django project by using the following commands
python -m venv venv
source venv/Scripts/activate
pip install django
django-admin startproject core .
python manage.py startapp books
We have created and activated a new virtual environment and started a project called core
which is the root directory of our project and also we created a new app called books
.
The next step is to make the project aware of the books
app by adding it to the INSTALLED_APPS section of the settings.py
file located in the core directory.
INSTALLED_APPS [
# all settings here remain the same
'books',
]
The next step is to create our model. And we will do that in the models.py
file located in the books
app we've just created.
# models.py
from django.db import models
class Book(models.Model):
title = models.CharField(max_length=100)
excerpt = models.TextField()
def __str__(self):
return self.title
Let's register our new model in the admin.py
file so that we can view it from the admin dashboard.
# admin.py
from django.contrib import admin
from .models import Book
admin.site.register(Book)
Migrate the models with the following command
# Terminal
python manage.py makemigrations
python manage.py migrate
Installing GraphQl
In order to use GraphQL with Django, we need to employ the services of graphene-python which is a library for building APIs in python. Its main goal is to provide simple but extendable API and makes developing API easier. Install graphene-python with the following command
pip install graphene-django
Once its done downloading, add it to the INSTALLED_APPS section
INSTALLED_APPS [
# all settings here remain the same
'books',
'graphene_django',
]
Moving on let's utilize graphene-Django. With REST we would be utilizing serializers
to format our data in a way that would be sent to the frontend whenever a request is made to the API. But with GraphQl we will be leveraging schema
.
Create a new file calledschema.py
in the books
app. The schema basically help us to describe out database models that we are going to provide to the GraphQL server and how to access the data.
# schema.py
import graphene
from graphene_django import DjangoObjectType
from .models import Book
class BookType(DjangoObjectType):
class Meta:
model = Book
fields = ('id', 'title', 'excerpt')
class Query(graphene.ObjectType):
all_books = graphene.List(BookType)
def resolve_all_books(root, info):
return Book.objects.all()
schema = graphene.Schema(query=Query)
we've imported graphene, DjangoObjectType, and our Book model. The DjangoObjectType basically handles formatting Django objects into a format that can be utilized by GraphQL. The BookType
class specifies the fields we want to have access to in our model. The Query
is returning the BookType
data as a list. And then finally, we create a schema that utilizes the query.
Now let's link URLs. Go into the root urls.py
in the core directory and add the following command.
# urls.py
from django.urls import path, include
urlpatterns = [
....
path('', include('books.urls')),
]
Now let's create a new urls.py
file in thebooks
app.
# books.urls.py
from django.urls import path
from graphene_django.views import GraphQLView
from books.schema import schema
urlpatterns = [
# Only one URL to access GraphQL
path('graphql', GraphQLView.as_view(graphiql=True, schema=schema)),
]
let's add some data that we can fetch from the API. switch into the django shell using the command python manage.py shell
and enter the following command to the shell.
# shell
>>> from books.models import Book
>>> b1 = Book(title="Atomic Habits", excerpt="tiny changes, remarkable results : an easy & proven way to build good habits & break bad ones")
>>> b1.save()
>>> b2 = Book(title="GraphQL CookBook", excerpt="getting started with GraphQL")
>>> b2.save()
After that exit from the django shell using exit()
.
Now that's all we need to do. let's test our app by starting the django development server.
python manage.py runserver
4. Fetching Data with GraphQL
Head unto localhost:8000/graphql to access the GraphQL playground and test our API. let's query our API like this
we will get a response like this
we can restructure our query right in the frontend and get a different response. let's see an example below.
And we get the following response...
Conclusion
GraphQl just generally brings in flexibility and access to fine-grained data when it comes to working with APIs. That is not to say that it replaces REST. The approach or paradigm to choose depends on the context and application needs. What we have learnt in this article, is getting started with GraphQL with Django in comparison with some of the weaknesses of REST.
Thanks 👋for reading and see you in the next one.