Django REST API and GraphQL with MySQL
Tags: GraphQL, Rest Api, MySQL, Programming, Django

In this tutorial, we will be using Django that serves as our backend application and create both REST API and GraphQL with MySQL for the database.

django rest api graphql

Introduction

Django is a Python framework that is open-source and follows the model-template-views architectural pattern. If you have used a framework the follows the model-template-views before, picking up Django will be much more easier.

To follow along with this tutorial, make sure you have these installed:

Python MySQL (I am using XAMPP which is easier to setup)

Without further ado, let’s get started.

Django REST API

First, let’s create a folder for our project and then let’s create virtual environment for our project. Open your command prompt and run this. I will be using Anaconda but it’s fine if you installed Python.

mkdir django

cd django

python -m venv venv

venv\Scripts\activate

With that, you will now have activated your virtual environment. Now, let’s installed Django and create our Django app.

pip install django // or you can use python -m pip install Django

django-admin startproject rasyue

cd rasyue

python manage.py runserver

You can replace rasyue with any name that you like. Now you should be able to go to localhost:8000 and see your default Django app.

django default landing page

But if you read the command prompt you should be seeing something like this.

command prompt

Django returned a notice to tell us about the unapplied migration. Let’s talk about migration now.

Migration in Django

First, open up your settings.py file which is under your_project_name/settings.py . Mine will be rasyue/settings.py .

You should see something like this.

Look at the database object/dictioanary. By default, Django will use sqlite that comes along with the Django package.

We are going to change that to use MySQL instead. Now fire up your xampp mysql.

Replace your database object/dictionary with below.

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.mysql',

'NAME': 'rasyuedjango',

'USER': 'root',

'PASSWORD': '',

'HOST': 'localhost', # Or an IP Address that your DB is hosted on

'PORT': '3306',

}

}

Remember to create a database for your Django app in MySQL. Mine is rasyuedjango .

And now we need to run the migration. Run the following code in your command prompt.

python manage.py migrate



python manage.py runserver

Take a look in your db and you should see a few tables have been created.

Django API App

At this point, if you are a beginner and has no idea what’s a REST API is, a REST API is the standard way to provide data to another party/app.

For example, let’s say you have a frontend app that you need to display User data, you can consume your backend REST API to fetch that data.

To create a REST API in Django, first we need to run the code below.

pip install djangorestframework

That will install the DRF(django rest framework) that will make our job easier.

REST API Data

A typical REST API should be providing some sort of data, since we do not have any data to provide, let’s create some.

Let’s just assume we want to provide data regarding books.

The steps that we need to do are as follow:

Create a super user for our django app to access the admin page Secondly, create another app in our django app to handle our REST API. Thirdly, create app model. Next, create a serializer. Then, create views and urls. After that, create some data for our books data. Finally, we need to test our REST API.

With all the steps listed, let’s get to work.

Creating Super User

To create a super user, first we need to start our app and run the following command.

python manage.py createsuperuser

The command will ask for username, email and password. Enter it and then go to localhost:8000/admin . A login box will appear, go ahead and login with the username and password that you entered previously.

django admin login

Upon successful login, you will see this page.

django admin

Now that we can log into the admin page. We need to create another app in our Django project.

Books App

First run the following command.

python manage.py startapp books

This command will create another app in your Django project.

Notice that in our project directory, another folder called Books has been created and it consists of several files like models.py, admin.py, views.py and so on .

Apps In Django

Before we go further, a couple of things you need to understand is:

Although, the command python manage.py startapp books create another app in our Django project, it is not a separate Django app. In Django, you can create several separate apps with each having unique functionality. If you have use Angular or React before, you can treat app like a component. Each of the app that you created are not linked to the core project by default, you will have to tell Django about the apps that you created which I will show later.

Registering Created App (Books)

Open up your settings.py and paste the following.

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'books',

]

It should look like this.

With that, we have successfully registered our books app.

Creating Model

In books/models.py , paste the following.

class Book(models.Model):

title = models.TextField()

description = models.TextField()

price = models.TextField()

def __str__(self):

return self.title



class Meta:

ordering = ('title',)

Open your books/admin.py and paste the following.

from django.contrib import admin

from .models import Book



# Register your models here.



admin.site.register(Book)

Now run the command.

python manage.py makemigrations

python manage.py migrate



start you server and go to admin page

python manage.py runserver

With that, when you go to the admin page. You should see something like this.

If you click on the Books , you can create a new book record, so go ahead and create as many as you like as these data will later be used in the REST API.

Creating Serializers

Create a new file and name it serializers.py in the book folder. It should be books/serializers.py . In the file, paste the followings.

from rest_framework import serializers



from .models import Book



class BookSerializer(serializers.HyperlinkedModelSerializer):

class Meta:

model = Book

fields = ('title', 'description')

Next, create another file and name it urls.py , paste the following.

from django.urls import path

from django.conf.urls import include

from rest_framework import routers

from . import views



router = routers.DefaultRouter()

router.register(r'books', views.BookView)



# Wire up our API using automatic URL routing.

# Additionally, we include login URLs for the browsable API.

urlpatterns = [

path('', include(router.urls)),

path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))

]

Open your views.py and paste the following.

from django.shortcuts import render



# Create your views here.

# views.py

from rest_framework import viewsets



from .serializers import BookSerializer

from .models import Book





class BookView(viewsets.ModelViewSet):

queryset = Book.objects.all()

serializer_class = Book

Lastly, open your project root urls.py or rasyue/urls.py and paste the following. We need to register the books/urls.py in our root url.

"""mysite URL Configuration



The `urlpatterns` list routes URLs to views. For more information please see:

https://docs.djangoproject.com/en/3.1/topics/http/urls/

Examples:

Function views

1. Add an import: from my_app import views

2. Add a URL to urlpatterns: path('', views.home, name='home')

Class-based views

1. Add an import: from other_app.views import Home

2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')

Including another URLconf

1. Import the include() function: from django.urls import include, path

2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))

"""

from django.contrib import admin

from django.urls import path

from books import views

from django.conf.urls import include



urlpatterns = [

path('admin/', admin.site.urls),

path('books-api', include('books.urls')),

]

Also, in your settings.py , include rest_framework.

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'books',

'rest_framework',

]

Now, start your app and go to localhost:8000/books-api

Play around with the REST API and understand it more. We are going to move on to create GraphQL.

Django API GraphQL

So now, lets begin to create our GraphQL by first running below command.

pip install django-graphene

Now, in the REST API above, we need to create the serializers but for graphql, we will have to create the schema.

Go ahead and create two file name schema.py , one for books/ and another one for rasyue/ .

It should look like this.

Open the books/schema.py and paste the following.

import graphene

from graphene_django.types import DjangoObjectType, ObjectType

from .models import Book class BookType(DjangoObjectType):

class Meta:

model = Book class Query(ObjectType):

book = graphene.Field(BookType, id=graphene.Int())

books = graphene.List(BookType) def resolve_book(self, info, **kwargs):

id = kwargs.get('id') if id is not None:

return Book.objects.get(pk=id) return None def resolve_books(self, info, **kwargs):

return Book.objects.all() class BookInput(graphene.InputObjectType):

id = graphene.ID()

title = graphene.String()

description = graphene.String()

price = graphene.String() class CreateBook(graphene.Mutation):

class Arguments:

input = BookInput(required=True) ok = graphene.Boolean()

book = graphene.Field(BookType) @staticmethod

def mutate(root, info, input=None):

ok = True

book_ins = Book(title=input.title)

book_ins.save()

return CreateBook(ok=ok, book=book_ins) def mutate(root, info, input=None):ok = Truebook_ins = Book(title=input.title)book_ins.save()return CreateBook(ok=ok, book=book_ins) class UpdateBook(graphene.Mutation):

class Arguments:

id = graphene.Int(required=True)

input = BookInput(required=True) ok = graphene.Boolean()

book = graphene.Field(BookType) @staticmethod

def mutate(root, info, id, input=None):

ok = False

book_ins = Book.objects.get(pk=id)

if book_ins:

ok = True

book_ins.title = input.title

book_ins.save()

return UpdateBook(ok=ok, book=book_ins)

return UpdateBook(ok=ok, book=None) def mutate(root, info, id, input=None):ok = Falsebook_ins = Book.objects.get(pk=id)if book_ins:ok = Truebook_ins.title = input.titlebook_ins.save()return UpdateBook(ok=ok, book=book_ins)return UpdateBook(ok=ok, book=None) class Mutation(graphene.ObjectType):

create_book = CreateBook.Field()

update_book = UpdateBook.Field() schema = graphene.Schema(query=Query, mutation=Mutation)

To explain the above code, in GraphQL we have two basic operations which are Query and Mutation. While Query is for fetching data, Mutation is used to update or create.

We created BookType to be used in Query operation which is fairly easy to understand.

We also created BookInput which is used to tell GraphQL the type of data that should be used in UpdateBook and CreateBook .

Now open your rasyue/schema.py and paste the following.

import graphene

import books.schema class Query(books.schema.Query, graphene.ObjectType):

pass class Mutation(books.schema.Mutation, graphene.ObjectType):

pass schema = graphene.Schema(query=Query, mutation=Mutation)

Now, open your rasyue/urls.py and paste the following.

"""mysite URL Configuration



The `urlpatterns` list routes URLs to views. For more information please see:

https://docs.djangoproject.com/en/3.1/topics/http/urls/

Examples:

Function views

1. Add an import: from my_app import views

2. Add a URL to urlpatterns: path('', views.home, name='home')

Class-based views

1. Add an import: from other_app.views import Home

2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')

Including another URLconf

1. Import the include() function: from django.urls import include, path

2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))

"""

from django.contrib import admin

from django.urls import path

from books import views

from django.conf.urls import include

from graphene_django.views import GraphQLView

from .schema import schema



urlpatterns = [

path('admin/', admin.site.urls),

path('books-api/', include('books.urls')),

path('graphql/', GraphQLView.as_view(graphiql=True)),

]

Lastly, open your rasyue/settings.py and modified it like so.

INSTALLED_APPS = [

'graphene_django',

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'books',

'rest_framework',

]



GRAPHENE = {

'SCHEMA': 'rasyue.schema.schema'

}

Your settings.py should look like this.

And that’s it. Run your django project and go to localhost:8000/graphql

The End..

And with that, this is the end for this tutorial. Hope if helps you. Thank you and stay tuned.