Writing backend for mobile apps in several minutes

In Heads and Hands one of our two main fields of expertise is developing mobile applications (iOS, Android). Most of the apps use interactions with users, data storages and other tasks that all require the availability of one unified server. That is why for most of the apps we need to write its’ own backend cyke. Our mobile developers have little troubles doing this because it’s always a matter of asking web-developer to do this and to find a BaaS service that is appropriate even if it’s matter of just a several enquiries.

That is why we decided to find a tool that will help in short time to develop a small web-service that can be used in mobile application.

Our first party data was: knowledge of HTTP, REST, JSON and a beginner level of development on Python (Django).

Recently, we had a small project to test this tool in a field. The idea behind an application was in creating an app for an event where all speakers and their presentations can be found and viewed. After quick research we took these tools as our base: Python (as the main development language), Django (as basic platform) and Tastypie framework (as a framework to create web-services API). So, let’s start!

First of all we need to create a template of the Django app:

python django-admin.py startproject EventApp

In file settings.py we write the settings neccessary for the database, localisation and time. Then we install the tastypie package:

pip install django-tastypie

Be careful, it needs Python2.6+ and Django 1.5+ being installed. We didn’t check it beforehand, so used a little more time for this installation. Firstly the framework just didn’t want to work properly. Moreover, you need to install python-mimeparse package the same way.

Later we need to write down in this file settings.py:

INSTALLED_APPS += [‘tastypie’]

or to add the app ‘tastypie’ to the existing list.

Now it’s time to write a model for our industry:

# -*- coding: utf-8 -*-
from django.db import models
class Speaker(models.Model):
 name = models.CharField(max_length=32)
 company = models.CharField(max_length=32)
 photo = models.ImageField(upload_to=’photos’, blank=True, null=True)
def __unicode__(self):
 return self.name + ‘ (‘ + self.company + ‘)’
class Event(models.Model):
 title = models.CharField(max_length=64)
 speaker = models.ForeignKey(Speaker, blank=False, null=False)
 start_time = models.TimeField()
 end_time = models.TimeField()
def __unicode__(self):
 return self.title + ‘ (‘ + self.speaker.name + ‘)’

We wrote down a model for a speaker (Speaker) and a model for a speech (Event). Every speech must have its unique speaker. Now we need to make it possible to work with our model at full through the REST protocol.

We need to create an api package in our app and to have a file resources.py (it can also be created in the main package).

from tastypie.resources import ModelResource
from EventApp.models import Speaker, Event
class SpeakerResource(ModelResource):
 class Meta:
 queryset = Speaker.objects.all()
 resource_name = ‘speaker’
class EventResource(ModelResource):
 speaker = fields.ForeignKey(SpeakerResources, ‘speaker’, blank=True, null=True)
 class Meta:
 queryset = Event.objects.all()
 resource_name = ‘event’

Inside of this file we created classes of so-called resources, the main objects in our REST service. These resources are the ones we’ll appeal to. Every class has a link to the model it represents. The field queryset gives us back the number of objects received from database when contacting it. The field resource_name is not a necessary one, but it gives us an opportunity to show the name of the resource that gives you access to.

One more thing to keep in mind is that in class EventResources we wrote down the separate speaker field to show that the resource of the event is linked to the resource of the speaker.

All is left to do is to write down the application to our service in urls.py file. And this action is very simple to handle.

from django.conf.urls.defaults import *
from tastypie.api import Api
from api.resources import EventResource, SpeakerResource
v1_api = Api(api_name=’v1')
v1_api.register(SpeakerResource())
v1_api.register(EventResource())
urlpatterns = patterns(‘’,
 (r’^api/’, include(v1_api.urls)),
)

Now it’s time to launch our project.

python manage.py runserver

If the server launches correctly, you can open the page http://localhost:8000/api/entry/?format=json in your browser and see that framework sees our resources and shows us a scheme of our service:

{
 “events”: 
 {
 “list_endpoint”: “/api/v1/events/”
 , “schema”: “/api/v1/events/schema/”
 }
 ,”speakers”: 
 {
 “list_endpoint”: “/api/v1/speakers/”
 ,”schema”: “/api/v1/speakers/schema/”
 }
}

Format parameter is the one that compulsory shows us in which format do we need to receive the data, but instead of it we can just write a title Content-type: application/json in our enquiry. Apart from JSON it also supports xml, yaml, bplist.

By schema address you can see the description of the whole model structure (fields, types, descriptions), by list_endpoint address you can receive your resources that were written down in a base beforehand.

If you open an address http://localhost:8000/api/v1/events/?format=json you’ll see something like this:

{
 “meta”: 
 {
 “limit”: 20
 ,”next”: null
 ,”offset”: 0
 ,”previous”: null
 ,”total_count”: 4
 }
 ,”objects”: [
 {
 “id”: 3
 ,”speaker”: “/api/v1/speakers/2/”
 ,”start_time”: “08:39:25”
 ,”end_time”: “18:39:29”
 ,”title”: “Something here”
 ,”description”: “Description”
 }
 ]
}

As you can see, there is nothing complex about it. In meta section there is main info about the resource: the number of records, the size of distribution, etc. Simultaneously we can reach to a exact event by reaching it by its’ id — http://localhost:8000/api/v1/events/1/

We can also create a record by making a POST enquiry and by inputting a JSON format into it, to renew PUTrecord enquiry and to delete it with DELETE help.

Also in tastypie the ModelResource class has huge variety of fields and methods redefined. With its help you can change the structure of data given completely. For example, we want to have a speaker name instead of the link to it right from the start in order not to make an odd enquiry. In EventResource class we redefine the dehydrate method:

def dehydrate(self, bundle):
 try:
 speaker = Speaker.objects.filter(id=bundle.obj.speaker.id)
 bundle.data[‘speaker_name’] = speaker[0].name
 except Speaker.DoesNotExist:
 pass
 return bundle

There we find a speaker in a database and put him into bundle object which is a dictionary that is given by a resource. Now the answer to an enquiry looks like (the main part):

{
 “id”: 3
 ,”speaker”: “/api/v1/speakers/2/”
 ,”speaker_name”: “Vasily”
 ,”start_time”: “08:39:25”
 ,”end_time”: “18:39:29”
 ,”title”: “Something else”
 ,”description”: “Description”
}

It’s exactly what we’ve needed! Moreover, the enquiry to the resource can be made with different filters implied.

For example, you need to choose all the events for one speaker. Logically you need to have such enquiry:

http://localhost:8000/api/v1/events/?speaker=1 that will give you all the events from a speaker with id = 1. All is left is to write down one more field into the meta class of the resource:

filtering = {
 ‘speaker’: ALL_WITH_RELATIONS
 }

Conclusion

All right then, we can now reach the server and take data from it! This is exactly what we needed.

If this subject was an interest for you, we can continue our story by adding validation and authorization here all together with working admin panel in short time.