Featured graphql python

Building a GraphQL API with Python: A Practical Tutorial

Hello, dear readers! 👋

Do you remember our task management API from the article Building a RESTful API with Python? Well, today we are going to rebuild it — but this time speaking a completely different language: GraphQL.

And yes, we will be using Python, our programming language friend, together with Django and a library called Graphene.

In the recent article GraphQL vs REST: When to Choose Each, we covered all the theory: why Facebook created GraphQL, the over-fetching problem, the famous single endpoint. Now it is time to get our hands dirty and see all of that working on our own machine.

By the end of this tutorial, you will have a working GraphQL API with Python where the client asks for exactly the data it wants — and you will be able to compare it, file by file, with the REST version we built before. Same project, two philosophies. Sounds fun? Let’s go! 🚀

Index

  1. What We Are Building
  2. Setting Up the Environment
  3. Creating the Task Model
  4. The Heart of GraphQL: The Schema
  5. One Endpoint to Rule Them All
  6. Playing with GraphiQL
  7. Testing Our API (Like Professionals)
  8. REST vs GraphQL: Same Project, Side by Side
  9. Conclusion
  10. References

1. What We Are Building

Our old friend: a Task Management API. Each task has a title, a description, and a status that can be PENDING, IN_PROGRESS, or DONE.

But here is the twist. In the REST version, we needed serializers, views, and routers spread across multiple files, plus one URL per resource. In the GraphQL version, we will have:

  • One single endpoint: /graphql/
  • One schema file where everything lives
  • Queries to read tasks (with the client choosing the fields!)
  • Mutations to create, update, and delete tasks
  • A free interactive playground called GraphiQL

2. Setting Up the Environment

As always, let’s keep things organized with a virtual environment. Open your terminal and type:

Now, let’s install our ingredients:

Graphene-Django is the bridge between Django and GraphQL. It knows how to transform our Django models into GraphQL types almost magically — you will see.

Create the project and the app:

Then register both in taskmanager_graphql/settings.py:

3. Creating the Task Model

Open tasks/models.py. If you followed the REST tutorial, this will look very familiar — and that is exactly the point. Same model, so we can compare both worlds fairly:

Run the migrations:

Our database is ready. Now comes the interesting part.

4. The Heart of GraphQL: The Schema

Here is where GraphQL really differs from REST. Remember that in the REST tutorial we created serializers.py, then views.py, then registered routes? In GraphQL, all of that lives in one file: the schema.

Create tasks/schema.py. I will build it piece by piece, and for each piece I will tell you its REST “cousin”, so nothing feels alien.

4.1 The Type (cousin of the Serializer)

That’s it. DjangoObjectType looks at our model and generates the GraphQL type automatically. In the REST version, our serializer did a similar job — but here we get a strongly typed contract for free.

4.2 Queries (cousins of the list/retrieve views)

Each field has a resolver — a function that knows how to fetch that data. Notice the small kindness to our users: status.upper() means they can write “pending” or “PENDING”, and both work. Small details make friendly APIs.

4.3 Mutations (cousins of create/update/destroy)

Notice the pattern ok + message in our mutations. Instead of throwing scary errors, our API answers politely: “Invalid status. Valid options: PENDING, IN_PROGRESS, DONE”. Your future front-end colleagues will thank you for this. Trust me.

4.4 The Schema (gluing everything together)

At the end of the file:

Four concepts: Type → Query → Mutation → Schema. That is the whole GraphQL mental model.


5. One Endpoint to Rule Them All

In the REST tutorial, we registered several routes. Today, open taskmanager_graphql/urls.py and behold:

One route. That’s all. Everything — reads, writes, deletes — goes through /graphql/. Remember the theory article? This is that “single endpoint” idea, now living in your urls.py.

The graphiql=True parameter gives us a free interactive playground. Let’s meet it.

⚠️ Heads-up: csrf_exempt and graphiql=True are here to keep the tutorial simple. In production, add authentication, handle CSRF properly, and turn GraphiQL off (or restrict it).


6. Playing with GraphiQL

Start the server:

Now open http://127.0.0.1:8000/graphql/ in your browser and say hello to GraphiQL — an interactive editor with auto-completion and documentation, generated automatically from our schema.

GraphiQL playground on first load at 127.0.0.1:8000/graphql/

 

6.1 Creating our first task

Paste this in the left panel and press the play button:

createTask mutation and its result in GraphiQL

The response confirms: our task was born with status PENDING. Create two or three more — we will need them.

6.2 The magic moment: asking only for what we need

Now, the query that justifies this whole tutorial:

Look carefully at the response. Where is the description? Where is createdAt? They are not there — because we did not ask for them.

allTasks query in GraphiQL returning only title and status

This is the over-fetching problem from our theory article, solved in front of your eyes. In the REST version, GET /api/tasks/ always returned every field of every task. Here, the client is in control. Try adding id to the query and watch the response change instantly.

6.3 Updating and filtering

Change a task status:

And now try to break it (breaking things is how we learn 😄):

updateTaskStatus returning ok false with the invalid status message

Our API answers with ok: false and a helpful message listing the valid options. This is the ok + message pattern earning its keep.

Finally, filter tasks by status:


7. Testing Our API (Like Professionals)

A tutorial that ends without tests is only half a tutorial. Create tasks/tests.py:

My favorite is the last one: test_client_chooses_fields. It literally proves, in code, the promise that brought us here. Run everything:

python manage.py test
Terminal showing the Django test run passing

All green. Beautiful. ✅

(The code above has 4 tests. In the GitHub repository you will find the complete test suite with 7 tests, including updates, deletes, and filtering — so if you run the repository, you will see 7.)


8. REST vs GraphQL: Same Project, Side by Side

Since we built the exact same project twice, we earned the right to a fair comparison:

Diagram comparing REST files (serializers, views, urls) with a single GraphQL schema.py
AspectREST version (DRF)GraphQL version (Graphene)
Endpoints/api/tasks/, /api/tasks/<id>//graphql/ only
Code organizationserializers.py + views.py + urls.pyOne schema.py
Response shapeFixed (all fields, always)Client chooses the fields
Interactive docsSwagger (needed setup)GraphiQL (came for free)
Testing toolPostman / SwaggerGraphiQL in the browser
Learning curveFamiliar territoryNew concepts (types, resolvers, mutations)

My honest opinion after building both? For a small CRUD like this one, REST is simpler and perfectly fine — exactly as we concluded in the theory article. But now you have felt the difference in your fingers, and when a project with multiple clients and interconnected data appears in your life, you will know precisely which tool to reach for.


9. Conclusion

Today we rebuilt our task management API in GraphQL and, along the way, we saw the theory from the previous article come alive: the single endpoint, the client choosing fields, the auto-generated documentation, and friendly error handling with the ok + message pattern.

The complete project, with all 7 tests, is on my GitHub: https://github.com/mariomthree/task-management-graphql-api

Feel free to clone it, break it, improve it — and leave a star if it helped you! ⭐

Your thoughts matter! Did you prefer building this in REST or in GraphQL? Share your experience in the comments — and if something did not work on your machine, tell me and we will debug it together.

Thank you for reading, and see you in the next article! 👋


10. References

Django Software Foundation. (2026). Django documentation. https://docs.djangoproject.com/

Graphene Community. (2026). Graphene-Django documentation. https://docs.graphene-python.org/projects/django/

GraphQL Foundation. (2024). GraphQL documentation. https://graphql.org/

Mabande, M. M. (2025, September 9). Building a RESTful API with Python: Creating a simple task management. MarioM3. https://mariomthree.com/building-a-restful-api-with-python-creating-a-simple-task-management/

Mabande, M. M. (2026, July 20). GraphQL vs REST: When to choose each one. MarioM3. https://mariomthree.com/graphql-vs-rest/

Leave a Reply

Your email address will not be published. Required fields are marked *