Finally understand Redux by building your own Store

Redux is an interesting pattern, and at its core a very simple one – but why does it feel complex to understand? In this post, we’re going to dive into Redux by assembling our own custom Store, written in TypeScript.

Table of contents

Terminology
Actions
Reducers
Store

Store API
Store.dispatch()
Store.subscribe()
Store.value

Store Container
Our state data structure
Updating our state tree

Writing Reducer functionality
Creating a Reducer
Registering a Reducer
Invoking Reducers in the Store
Reducing initialState

Enabling subscribers
Store Subscribers
Unsubscribing from the Store

Final Code
Wrapping up

This post is based off my “vanilla TypeScript Redux store”, you can grab the source code and follow along here if you wish. Please bear in mind, this is for learning purposes to understand the mechanics inside a Store – following the Redux pattern.

Terminology
If you’re new to Redux, or have flicked through the documentation, you’ll have likely come across a few of the following terms, which I think is worth covering before we begin.
Actions
Don’t try and think about actions as a JavaScript API, actions have a purpose – and we need to understand that first. Actions inform the Store of our intent.

You’re essentially passing an instruction, such as “Hey Store! I’ve got an instruction for you, please update the state tree with this new piece of information.”

The signature of an action, using TypeScript to demonstrate, is as follows:
interface Action {
type: string;
payload?: any;
}

Payload is an optional property, as sometimes we may dispatch some kind of “load” action which accepts no payload, though most of the time we’ll use the payload property.
This means that we’ll create something like this:
const action: Action = {
type: ‘ADD_TODO’,
payload: { label: ‘Eat pizza,’, complete: false },
};

That’s pretty much the blueprint of an action. Let’s continue!
Reducers
A reducer is simply a pure function which accepts the state of our application (our internal state tree, which our Store passes to the reducer), and finally a second argument of the action which was dispatched. Which means we end up with something like this:
function reducer(state, action) {
//… that was easy
}

Okay, so what’s next to understand a reducer? The reducer gets passed our state as we know, and to do something useful (such as updating our state tree), we need to respond to the action’s type property (which we just looked at above). This is typically done via a switch:
function reducer(state, action) {
switch (action.type) {
case ‘ADD_TODO’: {
// I guess we should do something now…
}
}
}

Each case inside the switch allows us to respond to the different types of actions that compose state in our applications. For instance, let’s say we want to add a property with a value to our state tree, we’d simply return it:
function reducer(state = {}, action) {
switch (action.type) {
case ‘ADD_TODO’: {
return {
…state,
// we spread the existing todos array into a new array
// and then add our new todo on the end
todos: […state.todos, { label: ‘Eat pizza,’, complete: false }],
};
}
}

return state;
}

Note at the bottom here, we’re returning state to pass the state back if we do not match a particular action. You’ll notice that I’ve added state = {} in the first argument (which is supplying a default value for the parameter). These initial state objects are typically abstracted above the reducer, and we’ll look at this as we continue.
The final thing to note here, is our push for immutability. We’re returning a brand new object in each case, which reflects the new state tree changes, as well as the existing state tree representation – which means we have a slightly modified state object. The way we merge existing state is via the …state, where we simply spread the current state in, and add additional properties after.

To honour the concept of pure functions, given the same input we return the same output each time. Reducers handle purely dynamic state and actions, in short we set them up – and they handle the rest. They’re encapsulated functions that simply contain the pieces of logic necessary to update our state tree, based on which type of instruction we are sending (via an action).

Reducers are purely synchronous, we should avoid asynchronous intent inside a reducer.
So where does the action.payload come into play? Ideally we wouldn’t hard-core values into a reducer, unless they were simple things like a boolean toggle from false to true. To complete our full circle trip of abiding by the “pure functions” rule, we access the action.payload property supplied in the function arguments to obtain any data we’ve dispatched via an action:
function reducer(state = {}, action) {
switch (action.type) {
case ‘ADD_TODO’: {
// give me new data
const todo = action.payload;
// compose new data structure
const todos = […state.todos, todo];
// return new state representation
return {
…state,
todos,
};
}
}

return state;
}

Store
One thing I see is confusion between “state” and “store”. Store is your container, state lives in the container. Store is an object with an API that lets you interact with your state, by modifying it, asking for its value – and so forth.
I think we’re about ready to begin building our custom Store, and all of these separate topics will start to click into place as we continue.

One thing I like to tell others is “this is just a structured process for updating a property on an object”. That is Redux.

Store API
Our example Redux Store is going to have just a few public properties and methods. We’ll then use our Store as follows, supplying any reducers and initial state for our application:
const store = new Store(reducers, initialState);

Store.dispatch()
The dispatch method will allow us to present an instruction to our Store, informing it that we intend to change the state tree. This is handled via our reducer, which we’ve just covered.
Store.subscribe()
The subscribe method will allow us to pass a subscriber function into our Store, which when our state tree changes, we can pass that new state tree changes down via an argument to our .subscribe() callback.
Store.value
The value property will be setup as a getter and return the internal state tree (so we can access properties).
Store Container
As we know, the Store contains our state, and also allows us to dispatch actions and subscribe to new state tree updates. So let’s start with our Store class:
export class Store {
constructor() {}

dispatch() {}

subscribe() {}
}

This looks good for now, but we’re missing our “state” object. Let’s get it added:
export class Store {
private state: { [key: string]: any };

constructor() {
this.state = {};
}

get value() {
return this.state;
}

dispatch() {}

subscribe() {}
}

I’m using TypeScript here, as I much prefer it, to define that our state object will be composed of keys of type string, with any value. Because that’s exactly what we need for our data structures.
We’ve also added the get value() {} which internally returns the state object, when accessed as a property, i.e. console.log(store.value);.
So now we’ve got this, let’s instantiate it:
const store = new Store();

Voila.
At this point we could actually call a dispatch if we wanted:
store.dispatch({
type: ‘ADD_TODO’,
payload: { label: ‘Eat pizza’, complete: false },
});

But it’s not going to do anything, so let’s dive into focusing on our dispatch and supplying that action:
export class Store {
// …
dispatch(action) {
// Update state tree here!
}
// …
}

Okay, so inside the dispatch, we need to update our state tree. But first – what does our state tree even look like?
Our state data structure
For this article, our data structure will look like this:
{
todos: {
data: [],
loaded: false,
loading: false,
}
}

Why? We’ve learned so far that reducers update our state tree. In a real app, we’ll have many reducers, which are responsible for updating specific parts of the state tree – which we often refer to as “slices” of state. Each slice is managed by a reducer.
In this case, our todos property on our state tree – the todos slice – is going to be managed by a reducer. Which at this point, our reducer will simply manage the data, loaded and loading properties of this slice. We’re using loaded and loading because when we perform asynchronous tasks such as fetching JSON over HTTP, we want to remain in control of the various steps it takes from initiating the request – to the request being fulfilled.
So, let’s jump back into our dispatch method.
Updating our state tree
In order to follow immutable update patterns, we should assign a new representation of state to our state property as a brand new object. This new object consists of any changes we’re intending to make to the state tree, via an action.
For this example, let’s ignore the fact that reducers even exist and simply update the state manually:
export class Store {
// …
dispatch(action) {
this.state = {
todos: {
data: […this.state.todos.data, action.payload],
loaded: true,
loading: false,
},
};
}
// …
}

After we’ve dispatched this ‘ADD_TODO’ action, our state tree now looks like this:
{
todos: {
data: [{ label: ‘Eat pizza’, complete: false }],
loaded: false,
loading: false,
}
}

Writing Reducer functionality
Now we’ve got an understanding that a reducer updates a slice of state, let’s start by defining that initial slice:
export const initialState = {
data: [],
loaded: false,
loading: false,
};

Creating a Reducer
Next up, we need to supply our reducer function that state argument, with a default value of the above initialState object. This sets up the reducer for initial load, when we invoke the reducer in the Store to bind all initial state, inside all of the reducers:
export function todosReducer(
state = initialState,
action: { type: string, payload: any }
) {
// don’t forget to return me
return state;
}

We should probably be able to guess the rest of the reducer at this point:
export function todosReducer(
state = initialState,
action: { type: string, payload: any }
) {
switch (action.type) {
case ‘ADD_TODO’: {
const todo = action.payload;
const data = […state.data, todo];
return {
…state,
data,
};
}
}

return state;
}

Okay, so this is great so far – but the reducer needs hooking up to the Store so we can invoke it to pass the state and any actions.
Back inside the Store, we should have this so far:
export class Store {
private state: { [key: string]: any };

constructor() {
this.state = {};
}

get value() {
return this.state;
}

dispatch(action) {
this.state = {
todos: {
data: […this.state.todos.data, action.payload],
loaded: true,
loading: false,
},
};
}
}

We now need to hook in the ability to add reducers to the Store:
export class Store {
private state: { [key: string]: any };
private reducers: { [key: string]: Function };

constructor(reducers = {}, initialState = {}) {
this.reducers = reducers;
this.state = {};
}

}

We’re also supplying any initialState to the Store, so we can supply this when we invoke the Store should we wish to.
Registering a Reducer
To register a reducer, we must remember that todos property on our expected state tree – and bind our reducer function to it. Remember, we’re managing a slice of state called “todos”:
const reducers = {
todos: todosReducer,
};

const store = new Store(reducers);

This is the magic piece where the property todos is then the result of the Store invoking the todosReducer – which as we know returns new state based on a particular action.
Invoking Reducers in the Store
The reason reducers are called “reducers” is because they reduce new state. Think Array.prototype.reduce, where we end up with one final value. In our case, this final value is the new representation of state. Sounds like we need a loop.
What we’re going to do is wrap our “reducing” logic in a function, which here I’ve called reduce:
export class Store {
// …
dispatch(action) {
this.state = this.reduce(this.state, action);
}

private reduce(state, action) {
// calculate and return new state
return {};
}
}

When we dispatch an action, we’ll in fact call the reduce method we’ve created on the Store class – and pass the state and action inside. This is actually called the root reducer. You’ll notice it takes the state and action – much like our todosReducer also does.
So, let’s dive into our private reduce method, because this is the most important step for the composition of our state tree to fully click.
export class Store {
private state: { [key: string]: any };
private reducers: { [key: string]: Function };

constructor(reducers = {}, initialState = {}) {
this.reducers = reducers;
this.state = {};
}

dispatch(action) {
this.state = this.reduce(this.state, action);
}

private reduce(state, action) {
const newState = {};
for (const prop in this.reducers) {
newState[prop] = this.reducers[prop](state[prop], action);
}
return newState;
}
}

What’s happening here is:

We create a newState object which will contain the new state tree
We iterate this.reducers, which we register in the Store
We map across each property on our reducer, i.e. todos, to the newState
We invoke each reducer, one at a time, and invoke it – passing in the slice of state (via state[prop]) and the action

The prop value in this case, is just todos, so you can think of it like this:
newState.todos = this.reducers.todos(state.todos, action);

Reducing initialState
There’s one final piece, our initialState object. If you want to use the Store(reducers, initialState) syntax to provide store-wide initial state, we need to reduce it as well upon Store creation:
export class Store {
private state: { [key: string]: any };
private reducers: { [key: string]: Function };

constructor(reducers = {}, initialState = {}) {
this.reducers = reducers;
this.state = this.reduce(initialState, {});
}

// …
}

Remember when we talked about return state at the bottom of each reducer? Now you know why! We have this option to pass {} as the action, meaning the switch cases will be avoided – and we end up with a state tree we supply through the constructor.
Enabling subscribers
You’ll often hear the term “subscribers” in the Observable world, where each time an Observable emits a new value, we are notified via a subscription. A subscription is simply “give me data when it’s available, or changes”.
In our case, this would be handled like so:
const store = new Store(reducers);

store.subscribe(state => {
// do something with `state`
});

Store Subscribers
Let’s add a few more properties to our Store to allow us to setup this subscription:
export class Store {
private subscribers: Function[];

constructor(reducers = {}, initialState = {}) {
this.subscribers = [];
// …
}

subscribe(fn) {}

// …
}

Here we have our subscribe method, which now accepts a function (fn) as the argument. What we need to do is pass each function into our subscribers array:
export class Store {
// …

subscribe(fn) {
this.subscribers = […this.subscribers, fn];
}

// …
}

That was easy! So where does it make sense to inform our subscribers that something changed? In the dispatch of course!
export class Store {
// …

get value() {
return this.state;
}

dispatch(action) {
this.state = this.reduce(this.state, action);
this.subscribers.forEach(fn => fn(this.value));
}

// …
}

Again, super easy. Any time we dispatch, we reduce the state and loop our subscribers – and pass in this.value (remember that’s our value getter).
Buuuuuuut, there’s just one more thing. When we call .subscribe() we won’t (at this point in time) get the state value right away. We’ll only get it after we dispatch. Let’s make a concious decision to inform new subscribers of the current state, as soon as they subscribe:
export class Store {
// …

subscribe(fn) {
this.subscribers = […this.subscribers, fn];
fn(this.value);
}

// …
}

That was also nice and easy – we get given fn – the function – via the subscribe method, and we can just simply invoke that function as soon as we subscribe, and pass the value of the state tree in.
Unsubscribing from the Store
When we subscribe, we always want to be able to unsubscribe – for purposes such as avoiding memory leaks, or simply because we don’t care about the data anymore.
All we need to do is return a function closure, which when invoked will unsubscribe us (by removing the function from our list of subscribers):
export class Store {
// …

subscribe(fn) {
this.subscribers = […this.subscribers, fn];
fn(this.value);
return () => {
this.subscribers = this.subscribers.filter(sub => sub !== fn);
};
}

// …
}

We simply use the function’s reference, iterate our subscribers, check if the current subscriber does not equal our fn, and by using Array.prototype.filter, it magically is removed from our subscribers array.
And we can use it as follows:
const store = new Store(reducers);

const unsubscribe = store.subscribe(state => {});

destroyButton.on(‘click’, unsubscribe, false);

And that’s all we need.
The beauty of subscriptions is we can also have multiple subscribers, meaning different parts of our application are interested in different slices of state.
Final Code
Here’s the full picture and finished solution:
export class Store {
private subscribers: Function[];
private reducers: { [key: string]: Function };
private state: { [key: string]: any };

constructor(reducers = {}, initialState = {}) {
this.subscribers = [];
this.reducers = reducers;
this.state = this.reduce(initialState, {});
}

get value() {
return this.state;
}

subscribe(fn) {
this.subscribers = […this.subscribers, fn];
fn(this.value);
return () => {
this.subscribers = this.subscribers.filter(sub => sub !== fn);
};
}

dispatch(action) {
this.state = this.reduce(this.state, action);
this.subscribers.forEach(fn => fn(this.value));
}

private reduce(state, action) {
const newState = {};
for (const prop in this.reducers) {
newState[prop] = this.reducers[prop](state[prop], action);
}
return newState;
}
}

You can see that in reality, there isn’t much going on here.
Wrapping up
That wasn’t so bad was it? We’ve likely used/seen/heard about all these different terminology examples, but haven’t necessarily dived underneath to think about how they are composed.
We’ve finally understood what a Store does for us, by creating our own. It’s taking the magic away from simply creating an action, reducer, and just letting it “work”. We fully grasped the concepts and mechanics of what’s happening; our dispatch tells the Store to carry out a process of defining new state by invoking each reducer and attempting to match our action.type with a switch case. Our state tree is simply a final representation of having invoked all of our reducers.
For me, this was the biggest part in understanding Redux, and I hope it’s helped you on your way too!
You can take this one step further with my NGRX course for Angular, which is free for everyone, to learn how to master state management with NGRX Store and Effects.

Link: https://toddmotto.com/redux-typescript-store

Building an API with Django REST Framework and Class-Based Views

This article first appeared on Codeburst.io
What and Why Are We Building?
With the rise of Single-Page Applications and the trend of separating monoliths into services with distinct front and backends, knowing how to make your own RESTful API for your backend is more important than ever.
Officially, a RESTful API is a Representational State Transfer-ful Application Programming Interface. Big words, but what it really boils down to is putting data onto your web server in a way that’s accessible to other servers and clients, working through HTTP requests and responses and carefully structured URL routes to represent specific resources.
It looks a lot like this:

http://wiki.hashphp.org/HttpPrimer
HTTP is short for Hypertext Transfer Protocol and it’s a set of rules that dictate how data is packaged and communicated throughout the web. There are other protocols that go along with HTTP, but HTTP will be the focus for now for simplicity.
An HTTP request looks something like this:
POST /cgi-bin/process.cgi HTTP/1.1
User-Agent: Mozilla/4.0 (compatible; MSIE5.01; Windows NT)
Host: www.tutorialspoint.com
Content-Type: application/x-www-form-urlencoded
Content-Length: length
Accept-Language: en-us
Accept-Encoding: gzip, deflate
Connection: Keep-Alive

licenseID=string&content=string&/paramsXML=string

https://www.tutorialspoint.com/http/http_requests.htm
And an HTTP response looks something like this:
HTTP/1.1 200 OK
Date: Mon, 27 Jul 2009 12:28:53 GMT
Server: Apache/2.2.14 (Win32)
Last-Modified: Wed, 22 Jul 2009 19:15:56 GMT
Content-Length: 88
Content-Type: text/html
Connection: Closed


<body>
<h1>Hello, World!</h1>
</body>
</html>

https://www.tutorialspoint.com/http/http_responses.htm
Clients send HTTP requests to the server and the server sends back HTTP responses. Many things can fit within requests and responses, though most of the times the data is either metadata about the request/response or some kind of JSON string or both, when dealing with APIs.
This is a brief walkthrough of how to make a barebones API for a ‘Todo list’ application using the Django Rest Framework.
Keep in mind this isn’t a comprehensive guide, so you should be somewhat familiar with making AJAX calls with JavaScript and Django itself. You can make an API in any modern language and the concepts behind it are similar but I am choosing Python because:

I know it
It’s clean and explicit
Django and Django Rest Framework are both mature, stable, and well-documented
Django and Django Rest Framework gives you a lot out of the box
Pluggable authentication systems
Serializers
Views
Browseable client and admin panel
Auto-generated documentation for your API
An awesome ORM
Highly customizable on every level

In a nutshell, this is what we’ll be creating:

We structure our endpoints in accordance with common RESTful guidelines so that we have clear endpoints that return expected resources.
Setup
First, we use virtualenv and virtualenvwrapper to make a virtual environment to install Python packages in a way that doesn’t interfere with other projects and environments. In this environment, we install Django, Django Rest Framework, and coreapi (for Django Rest Framework).
ktruong:auth-api ktruong$ which python3
/usr/local/bin/python3
ktruong:auth-api ktruong$ mkvirtualenv –python=/usr/local/bin/python3 auth-api

(auth-api) ktruong:auth-api ktruong$

pip install django djangorestframework coreapi

Now, we create the django project, make folders, and adjust some project settings:
(auth-api) ktruong:auth-api ktruong$ pwd
/Users/ktruong/git_projects/blogs/auth-api
(auth-api) ktruong:auth-api ktruong$ touch README.md
(auth-api) ktruong:auth-api ktruong$ django-admin.py startproject auth_api
(auth-api) ktruong:auth-api ktruong$ cd auth_api
(auth-api) ktruong:auth_api ktruong$ ls
auth_api manage.py
(auth-api) ktruong:auth_api ktruong$ python manage.py startapp users
(auth-api) ktruong:auth_api ktruong$ python manage.py startapp todos
(auth-api) ktruong:auth_api ktruong$ ls
auth_api manage.py todos users
(auth-api) ktruong:auth_api ktruong$

settings.py
INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘rest_framework’,
‘todos’,
‘users’,
]

AUTH_USER_MODEL = ‘users.User’

https://gist.github.com/KTruong008/e951617ed1bc55611e92c5531f7a9005
Notice how we explicitly set our AUTHUSERMODEL to a custom User model (we’ll write the actual model, users.User, later). We could use the default User model that comes from Django but it becomes unnecessarily complicated to change it down the road.
A solution is to write our own User model that subclasses the same AbstractUser model that Django’s User model subclasses. Doing this will give us the same functionality but allow us to easily customize our User model down the road.
Project Level URL Routing
We’ll be building the features in this order:
URLs → views → serializers → models
This means we’ll be referencing some files before we make them, which may feel strange, but doing it this way is more intuitive because it follows the path of the HTTP request more closely.
When the request first comes into our server, we need to decide where to route that request. Kind of like a receptionist to our web server, our top-most URL routes will route the request to the proper modules and views.
We’ll use the innermost auth_api folder to store the top-most url routes along with our project-wide settings:
auth_api/urls.py
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework.documentation import include_docs_urls

from auth_api import views

urlpatterns = [
url(r’^admin/’, admin.site.urls),
url(r’^docs/’, include_docs_urls(title=’Todo API’, description=’RESTful API for Todo’)),

url(r’^$’, views.api_root),
url(r’^’, include(‘users.urls’, namespace=’users’)),
url(r’^’, include(‘todos.urls’, namespace=’todos’)),
]

https://gist.github.com/KTruong008/deaeee721a5b0e17870db607e5974e8c
When Django parses the incoming request, it will use regex to match the URL to the urlpatterns we write and forward the request to the place we want, which could contain more URL routes or a view.
We set up routes for our Django admin, documentation (automatically generated thanks to DRF), routes for users, routes for todos, and our API root.
Making the Root View of the API
One of the routes we defined earlier routed to views.api_root. Though not necessary, making a root view that acts as a table of contents to other routes in your API when requests matches your domain name exactly is easy to implement and improves developer experience.
The urlpatterns we wrote route requests and the views we will write will handle those requests and return HTTP responses. To write our apiroot, we can use DRF’s built in decorator, @apiview, to wrap our view with some nice utilities:

Specifies which HTTP methods we allow the view to respond to
Wraps normal HTTP request and response objects to provide a more uniform interface to work with HTTP data.

auth_api/views.py
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework.reverse import reverse

@api_view([‘GET’])
def api_root(request, format=None):
return Response({
‘users’: reverse(‘users:user-list’, request=request, format=format),
‘todos’: reverse(‘todos:todo-list’, request=request, format=format),
})

https://gist.github.com/KTruong008/a6f389cacf118b7258ed519879491761
Configuring URLs for Users and Todos
We need to create routes for when the request matches /todos/* or /users/* (as per the table we made earlier) and route them to the proper views to be handled:
todos/urls.py
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from todos import views

urlpatterns = [
url(r’^todos/$’, views.TodoList.as_view(), name=’todo-list’),
url(r’^todos/(?P<pk>[0-9]+)/$’, views.TodoDetail.as_view(), name=’todo-detail’),
]

https://gist.github.com/KTruong008/22bfed3f00ffb8adf2d130a7f9600bd4
users/urls.py
from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from users import views

urlpatterns = [
url(r’^users/$’, views.UserList.as_view(), name=’user-list’),
url(r’^users/(?P<pk>[0-9]+)/$’, views.UserDetail.as_view(), name=’user-detail’),
]

https://gist.github.com/KTruong008/ddc26d308719cad8afc6fbca56f2c9f3
Writing the Views
Views handle the request and return a response and by handling, I mean we can do anything we want with it – from hitting the database, modifying the request, structuring the response, or injecting our own logic into it.
With respect to APIs, all the core views often do the same thing conceptually:

Parse the request for data and the HTTP method
Query the database (DB) to fetch the model object(s), if needed
Serialize the data (we’ll discuss this more later)
Do something with the object/data (create, read, update, delete)
Return an HTTP response

Views are most often written as functions and an example of a function-based view that handles our API request looks something like this:
@api_view([‘GET’, ‘POST’])
def snippet_list(request):
“""
List all snippets, or create a new snippet.
"""
if request.method == ‘GET’:
snippets = Snippet.objects.all()
serializer = SnippetSerializer(snippets, many=True)
return Response(serializer.data)

elif request.method == ‘POST’:
serializer = SnippetSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view([‘GET’, ‘PUT’, ‘DELETE’])
def snippet_detail(request, pk):
"""
Retrieve, update or delete a snippet instance.
"""
try:
snippet = Snippet.objects.get(pk=pk)
except Snippet.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)

if request.method == ‘GET’:
serializer = SnippetSerializer(snippet)
return Response(serializer.data)

elif request.method == ‘PUT’:
serializer = SnippetSerializer(snippet, data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

elif request.method == ‘DELETE’:
snippet.delete()
return Response(status=status.HTTP_204_NO_CONTENT)

Examples from http://www.django-rest-framework.org/tutorial/2-requests-and-responses/
https://gist.github.com/KTruong008/254888fc3553ef9929c26997522ccbca
Again, we see that ‘views’ essentially do is:

Parse the request for data and the HTTP method
Query the database (DB) to fetch the model object(s), if needed
Serialize the data (we’ll discuss this more later)
Do something with the object/data (create, read, update, delete)
Return an HTTP response

It’s relatively straight-forward and explicit, but imagine having to write our views likes this for:

Todo_detail
Todo_list
User_detail
User_list

There would be a lot of logic duplication. Instead, we could use an object-oriented approach and use classes and inheritance to reuse common blocks of logic. Using class-based views, we could write our views like this:
from todos.models import Todo
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.reverse import reverse

from todos.serializers import TodoSerializer

class TodoList(generics.ListCreateAPIView):
queryset = Todo.objects.all()
serializer_class = TodoSerializer

def perform_create(self, serializer):
serializer.save(user=self.request.user)

class TodoDetail(generics.RetrieveUpdateDestroyAPIView):
serializer_class = TodoSerializer

def get_queryset(self):
return Todo.objects.all().filter(user=self.request.user)

https://gist.github.com/KTruong008/696d32650f1c69b1a11c3f8e81362ea0
With that we accomplish the exact same functionality as the example above that uses function-based views, only with significantly less code.
But less code is not always better, so you’ll have to decide where to draw the line in terms of how explicit or terse you want your code to be. Personally, I feel class-based views strike that perfect balance, plus they force you to grow as a developer by exposing you to classes, inheritance, and object-oriented programming, which is probably the bulk of the code you’ll be reading and/or writing as a developer.
In the above classes, we subclass generic classes provided by DRF and the generic classes provide methods and properties that encapsulate the common logic so we don’t have to keep rewriting it, but we can still access, overwrite, and customize the logic if needed.
Blocks of logic like the ones that parse the DB for the correct model instance–or carry out error handling, or determining which serializer to use and how to instantiate it, or structure the response, or parse the request–are already written for you and are readily available to the classes that you write if you subclass the generic ones.
There is honestly a lot of cleverly written code hidden behind these generic views with a lot of concepts and techniques to learn from that are beyond the scope of this guide, but the best way to really learn and understand is to download the source code, read it, and tinker. I also recommend reading the documentation on these topics:
https://docs.djangoproject.com/en/1.11/topics/class-based-views/
http://www.django-rest-framework.org/api-guide/generic-views/
https://github.com/encode/django-rest-framework/tree/master
https://github.com/django/django
Try not to overthink it too much and remember that the 10 or so lines of code using class-based views do the exact same thing as the many more lines of codes using function-based views in the above example, just more concise.
Repeat for Users:
users/views.py
from users.models import User
from rest_framework import generics
from rest_framework.response import Response
from rest_framework.reverse import reverse

from users.serializers import UserSerializer

class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer

class UserDetail(generics.RetrieveUpdateDestroyAPIView):
serializer_class = UserSerializer

def get_queryset(self):
return User.objects.all().filter(username=self.request.user)

https://gist.github.com/KTruong008/242b82436e90e9fb626c495d7df5ed64
Writing the Serializers
DRF serializers provide the service of serialization and deserialization. Serialization is the process of translating data structures into a format that can be stored, which in this case means turning querysets and model instances into native Python datatypes and then into JSON. Deserialization is the opposite, taking JSON and turning it into native Python datatypes and then into model instances.
Serializers are not magic.
If you’ve made an API in any language then you’ve used the same concepts serializers use. Serializers just give you a convenient interface to take data in one form and convert it into another. DRF serializers use an interface similar to that of Django forms in that you define the fields of the model you wish to serialize/deserialize and, when you instantiate the serializer with data, it will do the field validation for you.
http://www.django-rest-framework.org/api-guide/serializers/
Let’s write our serializers for Todos and Users:
Todos/serializers.py
from rest_framework import serializers

from todos.models import Todo

class TodoSerializer(serializers.HyperlinkedModelSerializer):
user = serializers.ReadOnlyField(source=’user.username’)

class Meta:
model = Todo
fields = (‘url’, ‘id’, ‘created’, ‘name’, ‘user’)
extra_kwargs = {
‘url’: {
‘view_name’: ‘todos:todo-detail’,
}
}

users/serializers.py
from rest_framework import serializers

from users.models import User

class UserSerializer(serializers.HyperlinkedModelSerializer):
todos = serializers.HyperlinkedRelatedField(
many=True,
view_name=’todos:todo-detail’,
read_only=True
)
password = serializers.CharField(write_only=True)

def create(self, validated_data):
user = User(
username=validated_data.get(‘username’, None)
)
user.set_password(validated_data.get(‘password’, None))
user.save()
return user

def update(self, instance, validated_data):
for field in validated_data:
if field == ‘password’:
instance.set_password(validated_data.get(field))
else:
instance.__setattr__(field, validated_data.get(field))
instance.save()
return instance

class Meta:
model = User
fields = (‘url’, ‘id’, ‘username’,
‘password’, ‘first_name’, ‘last_name’,
’email’, ‘todos’
)
extra_kwargs = {
‘url’: {
‘view_name’: ‘users:user-detail’,
}
}

https://gist.github.com/KTruong008/79b5d56df4e78663410caa14565cce41
Notice that UserSerializer is much more complex than TodoSerializer. Serializers, like our class-based views, come in many varieties and can inherit from many generic base classes. Within those base classes are methods and properties we can overwrite to customize what happens at certain hooks, like when a serializer updates or saves data.
We customize UserSerializer because we want to use the hashing feature that comes with Django’s AbstractUser when updating and saving users for security reasons.
Writing the Models
From client to url routes to views to serializers, and now to the last part in our little app, the models. Our models are what define our data. Django models get written in normal Python classes and they get mapped to SQL DBs, each attributed on the model getting mapped to a field in its respective table.
https://docs.djangoproject.com/en/1.11/topics/db/models/
We’ll create two models, Todo and User, and we’ll create a many-to-one relationship (foreign key) from our Todos to our Users, so a User can have many Todos but a Todo will only have one User.
todos/models.py
from django.db import models
from users.models import User

class Todo(models.Model):
created = models.DateTimeField(auto_now_add=True)
name = models.CharField(max_length=100, unique=True, blank=False, null=False)
user = models.ForeignKey(‘users.User’, related_name=’todos’, on_delete=models.CASCADE, null=False)

class Meta:
ordering = (‘created’,)

https://gist.github.com/KTruong008/1cb557b2c3dccf8c1367b57eef33a110
users/models.py
from django.db import models
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
Pass

https://gist.github.com/KTruong008/235e5d3bf198997311dd8aa173d0884a
We touched a bit on this earlier, but we don’t do anything extra with our User model. We use the same AbstractUser that the default Django User model uses, but defining our own User model gives us the ability to easily edit it later on while still retaining the same features as the default Django User.
Bringing It All Together
We’ve got all the code we need to make this API work, and now we just need to migrate our models and create a superuser.
ktruong$ python manage.py makemigrations todos users
ktruong$ python manage.py migrate
ktruong$ python manage.py createsuperuser
ktruong$ python manage.py runserver

Now go browse localhost:8000, login to the admin if needed, and play around with your new API.
The browsable API is just another out-of-the-box feature from DRF and it allows you to browse your API interactively in a browser. You can click through links, see relationships, see models and objects, perform any CRUD (create, read, update, delete) request, and do pretty much anything you can do with an API, but in a visible and interactive way.

Conclusion
We covered some fundamental concepts of building a RESTful API by creating a basic Todo API, with complete CRUD endpoints. Though very barebones, the instructions in this guide should serve as another step in the ladder to help you become a better developer and understand how to make your own API.
There’s still a lot more one can do to improve your API, such as adding authentication and authorization with JSON Web Tokens, adding unit tests, and more, which are also topics I plan on covering in the future.
Check out my other articles at:
https://medium.com/@ktruong008/latest

Link: http://blog.rangle.io/building-an-api-with-django-rest-framework-and-class-based-views/