APIs are a wonderful thing. They allow you to interact any client application such as a frontend application written in your choice of frontend JS frameworks (Ember.js, Angular, React, Backbone, etc) or a mobile application.

If you're like me and come from a fullstack background such as Django or Ruby on Rails, separating out an API can seem like a strange tactic. However, it allows you to expand rapidly when your project consists of more than a single standalone website

I, myself, come from a Django background, so my first experience writing APIs naturally came with the Django Rest Framework package, which is amazing.

Mapping everything out

There is a bit of a learning curve to begin with, but after you get the hang of it, development is straightforward. The documentation and guides really help out with this.

The basic flow that will be followed is Route > View > Serializer. There are plenty of other featuers of DRF that you'll run into, but these 3 areas are what we'll be discussing here, and they're all you need to get a barebones API up and running.

Routing

From your server's point of view, the first thing that happens is the route. A client is going to send a request to an endpoint, let's say api/kittens/. Your server needs to know what to do when that request comes in, and that is defined in the router.

There are 2 components to creating the router. First is creating the actual router, and the second part is adding the router urls into your project's urls


### proj/urls.py
from django.conf.urls import include, url
from django.contrib import admin

from .routers import router

# prefix all api endpints with api/
urlpatterns = [
    url(r'^admin/', include(admin.site.urls)),
    url(r'^api/', include(router.urls)),
]

### proj/routers.py
from rest_framework import routers

from animals.views import KittenViewSet

# endpoint will be named "kittens", which is tacked onto the api/ prefix
router = routers.SimpleRouter()
router.register(r'kittens', KittenViewSet)

Views

The view or viewset is going to determine if and what data to show. On the view is where you determine permission rules and write a query to fetch the appropriate data.

It's closely related to Class Based Views, so many of the same functions are inherited to create conformity and familiarity with normal Django.


### views.py
from rest_framework.viewsets import ModelViewSet

from .models import Kitten
from .serializers import KittenSerializer

# determine which data to show, and how to serialize the data
class KittenViewSet(ModelViewSet):
    queryset = Kitten.objects.all()
    serializer_class = KittenSerializer

Serializers

The serializer determines how we show the data. We have a database query, and we need to format and display that data in a certain way. The renderer works behind the scenes to render the data as JSON (can be changed if needed), but the serializer can determine fields and it's also the place to add in model method data.


### serializers.py

from rest_framework.serializers import ModelSerializer

from .models import Kitten

# determine how to serialize the fields and which fields to show
class KittenSerializer(ModelSerializer):
    class Meta:
        model = Kitten