Create GraphQL API in Django
Intro
Just a brief explanation : GraphQL is a query language which you can use in your API and enjoy the powerful flexibility (I assure you that the front-end crew are also going to enjoy this in long term)
I had a big problem about the documentation and complex problems such as many to many , … relations or use of enums in database so the solutions I present here are all personal experience and some searching around but I know it works .😉
Installation
So we use Graphene-Django to implement GraphQL in Django.The installation is straight froward and you can use the documentation for it:
Also Django GraphQL JWT for Authentication which again you can install it by the docs:
🧱 Structure of a GraphQL schema
It’s better to break the schema down to separate files to avoid a big schema file and also have a clean code.
So the main parts are :
- Type: This states our data type which we link our data model to it and its automatically handled
2. Input: It indicates the arguments which we receive through mutations and use them to make mutations
3. Query: As the name suggests, it’s used to get data (acting like Get in REST)
By using get_tags() query we receive all the tags in the table and by using get_tag(id:wanted_id) we get the row of the tag table containing the id you pass to it
4. Resolver: these functions define the act happening as you hit a query and the logic of the query happens in the body of these functions starting with resolve_
Note that the naming is important
5. Mutation: mutations do the rest of the work (Create : post in REST , Update : put in REST , Delete)
You can see the use of inputs and types in here also the ok variable indicates success of the mutation in the API’s consumer end.
Relations and Enums
OK you should be familiar with GraphQL by now🥳 .So lets get deeper and investigate the relations in the database:
🔑 Foreign Key (One to One , One to many)
There is no difference in types, queries and resolvers. so lets see a sample of input and mutation :
We create a file in our app named services.py to handle our data fetch by id:
For simplicity we consider here that every article just has an author and nothing else:
many to many
now that we know every article can have several tags, we use many to many relation to implement assignment of multiple tags to an article:
note that iteration through input tags and assigning them to the database instance should be happening after the simple and foreign relation rows assignment and after the database_instance.save()
Enums
for enums we use Django’s ORM TextChoices and then use the graphene.Enum.from_enum method to assign it to the type:
note : by this approach GraphQL will not accept any value other than enums we defined for sex input but notice putting choices constraint on the user model’s sex field will raise errors so we don’t put any constraint on the sex field.
🔒 Authentication
last but not least we investigate authentication and permissions:
as mentioned in the installation part we are using django-graphql-jwt and the documentation is so rich so I skip the details but reference some key points from the docs:
To use it all you have to do is adding it to the GRAPENE and AUTHENTICATION_BACKENDS in setting of your project as mentioned in the docs and adding 3 mutations to your main schema file :
The permission integration is pretty simple and it’s achieved by just using decorators and you’ll get along by reading the docs.
The code of a simple blog API is available in:
https://github.com/mahan-ym/Graphql-Django-Tutorial
I hope this will be useful to you.