Réalisation d’un backend dans le cloud pour application mobile (Part 1)

Update décembre 2016 : Découvrez mon livre sur le développement de backend pour application mobile avec Django

Dans ce billet nous allons voir comment mettre en place un backend dans le cloud de manière très simple, rapide et qui offrira une API sécurisée à vos applications mobiles (avec la documentation associée) et un backoffice d’administration.
Pour cela, nous allons utiliser une architecture reposant sur les services de Clever Cloud (plus d’infos ici :https://www.clever-cloud.com). Ainsi vous pouvez rester concentré sur votre coeur de métier (le développement des features de votre application), et laisser tout le reste (serveurs, montée en charge, administration, surveillance…) à la charge de Clever Cloud dont c’est le métier. Notre backend sera lui développé en Python Django.

Mais avant de rentrer dans le vif du sujet, décrivons déjà en quoi consistera notre backend. Pour faire quelque chose d’utile et de très courant, nous allons gérer des utilisateurs qui seront capables de voir les villes autour d’eux et d’en ajouter dans leur favori.

Ok?, c’est parti !

1. Création de l’application sous Clever Cloud

Allez sur votre compte Clever Cloud et choisissez Add an application.
Vous allez avoir le choix entre partir de zéro (ce que l’on va faire) ou lier votre compte à Github.
Plusieurs choix de langage vont s’offrir à nous mais dans le cas qui nous intéresse, nous allons sélectionner Python
Ensuite il faut choisir un type d’instance (voir la doc pour les différents types). Restons sur un instance XS.
Choisir un nom pour notre application, puis cliquer sur Créer.
A ce moment là Clever Cloud va vous proposer de rajouter des ADD-ON dont votre application pourrait avoir besoin. Nous allons donc rajouter un ADD-ON FS-Buckets afin de pouvoir stocker nos fichiers (images utilisateurs,…) sur un disque persistant. Ainsi même si on détruit notre application, nos fichiers eux ne seront jamais perdus.
Une fois l’ADD-ON rajouté, Clever Cloud vous propose de rajouter des variables d’environnement que vous pourriez retrouvez dans votre application. On peut passer cette étape.

Et voilà c’est fini. Votre application est prête à être déployée (sous peu que le code existe :)). Pour cela, il suffit d’ajouter le GIT remote fourni par Clever Cloud et de faire un push de votre code (nous verrons ça en 4°).

2. Ajouts des Add-ons

Comme nous venons de le voir, les Add-ons sont des modules dont votre application va avoir besoin pour fonctionner.
Ajoutons donc un ADD-ON pour notre base de donnée.
Cliquez sur Add an add-on et choisissez PostgreSQL. Puis choisissez la taille de la base de donnée qui convient à vos besoins (DEV pour cette démo). Il est important de bien choisir la taille dés le début, car il ne sera pas possible de changer après.
Du moins pas sans l’aide du support Clever-Cloud (qui est très réactif).

3. Création de notre projet Django

Notre environnement est donc mis en place le tout en moins de 10 minutes. Fini les installations de serveurs, les configurations de logiciel…

Fini aussi les différences entre la production et le développement

Il vous suffit de créer une application pour la production (avec ses add-ons) et une autre pour votre développement (avec ses add-ons aussi). Grâce au cloud et aux services de Clever Cloud, tout ce qui compte c’est votre code (votre répertoire GIT) que vous pourrez pousser soit sur la production soit sur le développement. Difficile de faire mieux.

Mais revenons à notre sujet à savoir le développement du backend proprement dit avec ses apis, leur documentation et le backoffice associé.

Ok tout d’abord créons notre environnement virtuel :

virtualenv citiesaroundenv
cd citiesaroundenv

Puis notre projet Django que l’on va nommer citiesaround:

django-admin startproject citiesaround

Avant d’aller plus loin dans la création du projet django, nous allons créer les fichiers spécifiques à clevercloud. Pour cela, nous devons créer un répertoire clevercloud:

cd citiesaround
mkdir clevercloud

Puis 2 fichiers dans ce répertoire clevercloud:

  • buckets.json qui va contenir la configuration de votre add-on FS-Bucket vu plus haut
[
   {
      "bucket_host": "bucket-e0416980-3930-42bb-aa41-4f5ca704918f-fsbucket.services.clever-cloud.com",
      "folder": "/static/storage"
 } 
]

L’identifiant de votre bucket doit être récupéré en allant cliquer sur votre add-on. Le répertoire (folder) indique vous souhaitez (et sous quel nom) stocker vos fichiers.

  • python.json  qui va indiquer quel est le nom de votre fichier wsgi à déployer ainsi que le nom donné à votre répertoire static.
{
   "deploy":{
      "module": "citiesaround_wsgi",
      "static": "/static/"
   }
}

Revenons maintenant à la racine de notre projet, et créons le fichier citiesaround_wsgi.py puisque c’est le nom que nous lui avons donné dans le fichier python.json:

# *coding: utf-8*
import sys
import os
sys.path.append(os.environ('APP_HOME'))
os.environ['DJANGO_SETTINGS_MODULE'] = 'citiesaround.settings'
os.environ['PYTHON_EGG_CACHE'] = '/tmp/.python-egg'
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

Rien de très original pour un projet python à part la ligne

sys.path.append(os.environ(‘APP_HOME’))

qui est en fait le path de notre application. APP_HOME étant l’identifiant de notre application CleverCloud récupéré dans une variable d’environnement fournie par CleverCloud.

Enfin nous devons aussi créer notre répertoire static ainsi que notre sous répertoire storage (Attention ce dernier doit être vide sinon le déploiement échouera).

mkdir static
mkdir static/storage
mkdir static/static

ok c’en est fini pour la configuration CleverCloud. Nous pouvons reprendre notre projet Django et installer toutes les librairies dont nous allons avoir besoin. Pour cela nous allons utiliser PIP et créer un fichier requirements.txt avec le contenu suivant:

django == 1.9
djangorestframework
djangorestframework-gis
django-filter
django-oauth-toolkit
psycopg2
Pillow
drfdocs

Et lancer l’installation via la commande:

pip install -r requirements.txt

Ok maintenant créons notre backoffice:

python manage.py startapp bo

et créons le modèle suivant (fichier models.py):

from __future__ import unicode_literals
from django.db import models
from django.contrib.gis.db import models

class AppUser(models.Model):
    email = models.CharField(max_length=100)
    password = models.CharField(max_length=255)
    firstName = models.CharField(max_length=100, null=True, blank=True)
    lastName = models.CharField(max_length=100, null=True, blank=True)
    birthday = models.DateField(null=True, blank=True)
    sex_choix = (
        (0, "homme"),
        (1, "femme"),
        (2, "Not set"),
    )
    sex = models.IntegerField(choices=sex_choix, null=True, blank=True)
    location  = models.PointField(null=True, blank=True)
    online = models.BooleanField()
    lastConnexionDate = models.DateTimeField(null=True, blank=True)
    createdAt = models.DateTimeField(auto_now=True)
    updatedAt = models.DateTimeField(auto_now=True)

    objects = models.GeoManager()

    def __unicode__(self):
       return u'%s' % (self.email)

class Cities(models.Model):
    name = models.CharField(max_length=100)
    isoCode = models.CharField(max_length=2)
    location = models.PointField(null=True, blank=True)
    createdAt = models.DateTimeField(auto_now=True)
    updatedAt = models.DateTimeField(auto_now=True)

    objects = models.GeoManager()

    def __unicode__(self):
       return u'%s' % (self.name)

class Favorites(models.Model):
    userId = models.ForeignKey('AppUser',  db_index=True)
    citiesId = models.ForeignKey('Cities', db_index=True)
    createdAt = models.DateTimeField(auto_now=True)
    updatedAt = models.DateTimeField(auto_now=True)
    unique_together = (("userId", "citiesId"),)
    def __unicode__(self):
        return u'%s - %s' % (self.userId,self.citiesId)

Rien de bien compliqué. On définit 3 classes : AppUser qui contiendra les données de nos utilisateurs, Cities qui contiendra les données des villes et Favorites qui contiendra les villes favorites pour un utilisateur donné.

Maintenant on définit les classes que l’on veut voir apparaitre dans notre backoffice, pour cela créons le fichier admin.py:

from models import *
from django.contrib import admin
from django.contrib.gis.admin import OSMGeoAdmin

class AppUserAdmin(OSMGeoAdmin):
    fieldsets = [
        (None, {'fields': ['email','online','lastConnexionDate','location','password','firstName','lastName','sex']}),
    ]
    list_display = ('email','online','lastConnexionDate','location','password','firstName','lastName','sex',)
    list_filter = ('online','sex',)
    ordering = ('email','online', 'lastConnexionDate',)
    search_fields = ('email','firstName','lastName',)

class CitiesAdmin(OSMGeoAdmin):
    fieldsets = [
        (None, {'fields': ['name','isoCode','location']}),
    ]
    list_display = ('name','isoCode','location',)
    list_filter = ('name','isoCode',)
    ordering = ('name','isoCode',)
    search_fields = ('name','isoCode',)

class FavoritesAdmin(admin.ModelAdmin):
    fieldsets = [
        (None, {'fields': ['citiesId','userId']}),
    ]
    list_display = ('citiesId','userId',)
    list_filter = ('userId','citiesId')
    ordering = ('userId','citiesId',)
    search_fields = ('userId','citiesId',)

admin.site.register(AppUser,AppUserAdmin)
admin.site.register(Cities,CitiesAdmin)
admin.site.register(Favorites,FavoritesAdmin)

A noter l’utilisation du module OSMGeoAdmin qui va permettre d’afficher directement une carte OpenStreetMap pour localiser l’utilisateur et les villes. De même pour l’utilisation dans nos modèles du type PointField qui va permettre de filtrer nos données en fonction de leur géolocalisation et de leur distance. Tout ceci est possible grâce à l’extension GeoDjango et l’utilisation des fonctions spatiales de PostgreSQL grâce à l’extension PostGis.

Pages: 1 2 3