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.
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)
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
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