How Django and React work together?
But why?
Out of the box you have build-in backends for Django Template Language (and Jinja2 as an alternative). Django’s own template system is really powerful, and for many years it was more than enough in terms of building websites.
But in order to meet modern trends like:
- Single Page Apps
- use the same codebase for Web and Mobile
- manage complex State
you need to consider implementing some frontend framework. One of them would be React.
Main advantages of React:
- backend agnostic
- declarative
- component-based
- scalable
- …
React doesn’t pretend to be MVC, it doesn’t try to do the stuff that Django already does well, it does one thing managing templates.
Ways to get React connected to Django
1. As Django app
In this scenario you load HTML templates as usual, and let React manage the DOM. React will be sitting in the apps (in one giant ‘Frontend’, or inside existing ones).
You don’t loose the ‘batteries included’ stuff from Django:
- admin interface
- authentication system
- contenttypes framework
- flatpages app
- GeoDjango
- django.contrib.humanize
- messages framework
- django.contrib.postgres
- redirects app
- sessions framework
- sites framework
- sitemap framework
- syndication feed framework
2. Just separate folder
Still Django will have to render entry point of the app, but at this time it’s up to you at which point React will take over. But after that happens Django’s only job will be serving an API.
3. Standalone SPA
Django’s role is limited to expose API, which will be consumed by React SPA. This kind of separation frontend from backend gives more flexibility, but also creates new challenges like:
- search engine optimization
- authentication
- logic duplication (errors, forms, testing)
How to build API in Django?
REST
The core idea of REpresentational State Transfer is that each resource is identified by an URL, and you retrieve that resource by making HTTP requests. There is no ‘official’ standard for RESTful Web APIs, but usually it follows those methods:
Operation | SQL | HTTP | RESTful |
---|---|---|---|
Create | INSERT | PUT / POST | POST |
Read (Retrieve) | SELECT | GET | GET |
Update (Modify) | UPDATE | PUT / POST / PATCH | PUT |
Delete (Destroy) | DELETE | DELETE | DELETE |
Client:
Application will have to perform those actions:
- construct and send HTTP request
- receive and parse server response
- store data locally
- display data in the UI
GraphQL
GraphQL is a query language for your API, and a server-side runtime for executing queries, it has been released only as a specification. GraphQL solves many of the shortcomings and problems that developers face when interacting with REST APIs like:
- overfetching: Downloading superfluous data
- underfetching and the n+1 problem
- managing endpoints
- poor data usage analytics
- no contract(schema) between client and server
But to be fair GraphQL brings some new challenges mainly related to relying on a single endpoint:
- logging
- caching both server and browser side
- nested queries
Server:
We can differentiate three kinds of architectures that include a GraphQL server:
- GraphQL server with a connected database
- GraphQL server that is a thin layer in front of a number of third party or legacy systems and integrates them through a single GraphQL API
- a hybrid approach of a connected database and third party or legacy systems that can all be accessed through the same GraphQL API
Client:
By using client libraries (Relay, Apollo), you provide the abstraction to deal with the repetitive implementation of infrastructure. Then application will only need to:
- describe data requirements
- display data in UI
Development tools
REST tools
When comes to REST DjangoRESTframework will be go to tool-kit for building APIs in your project. It offers additional features like:
- web browsable API
- authentication and authorization policies
- serialization (both ORM and non-ORM data sources)
GraphQL tools
For Django
Server implementation:
- Graphene
– code-first approach (schema is generated)
– inspired by DRF Serializers (maps Django models to types)
– inconsistent (some features require Relay) - Strawberry
– code-first approach (schema is generated)
– inspired by Python dataclasses
– at the time of writing this their site is under-construction - Ariadne
– schema-first
– inspired by Apollo Server
– maintained by one company - tartiflette
– schema-first
– inspired by GraphQL.js
– maintained by one company
Other stuff:
- Django GraphQL JWT
JSON Web Token authentication. - django-webpack-loader
Provides links to the latest generated bundle in an automated fashion.
For React
Client implementation:
- Apollo Client
A complete state management library, part of the Apollo platform (Server, Client React, Client iOS, Graph Manager). - Relay
Very opinionated client for React.
(newsflash: React, GraphQL, and Relay all were developed by Facebook)
What to choose?
It depends on the situation. Here are some use cases I can see could happen:
For existing Django site
Backend: I would let Django to handle some landing and login pges, as well as admin interface. When comes to API: if it was earlier DRF I would try to rewrite all the Serializers to Resolvers with Graphene.
Frontend: React with graphQL client (Apollo or Relay).
For separated backend and frontend
Backend: Django exposing API through schema-first GraphQL implementation (e.g. Ariadne).
Frontend: React with GraphQL client (Apollo or Relay).
For completely new project
Backend & Frontend: Apollo platform + React.
At this moment Apollo is the most complete solution for build, query, and manage data layer. It enables applications to interact with data from any combination of connected data stores, and also external APIs.