GraphQL With Django

GraphQL With Django

·

10 min read

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 ✔

  1. REST overview, perceive weaknesses
  2. GraphQL overview
  3. GraphQL-Django setup
  4. 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

REST.png 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

graphql-query.PNG we will get a response like this

response.PNG we can restructure our query right in the frontend and get a different response. let's see an example below.

2.PNG And we get the following response...

22.PNG

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.