Aller au contenu

Un exemple d'Application Programming Interface

·769 mots·4 mins
Auteur
My name
A little bit about me

Une API est (comme le dit si bien le lien ci-contre) une interface pour interagir avec une application en particulier. Il s’agit de définir la manière et les méthodes disponibles pour interagir avec un contexte. C’est ce qui rendra votre application accessible ou non depuis l’extérieur, et qui fera en sorte que d’autres systèmes pourront communiquer avec elle.

Cette API peut se présenter sous plusieurs formes, en fonction de vos besoins et des spécifications. L’idée de cet article est de présenter une interface de type REST avec Flask. Pour l’exemple, on va partir d’une structure simple (et pour éviter la bête liste de choses à faire, ce sera la liste de cadeaux, puisque c’est bientôt les fêtes de fin d’année).

C’est quoi, et comment ça s’utilise?
#

En utilisant curl! Non, sans blague: avec tout et n’importe quoi. REST définit juste un ensemble de règles à respecter, pas un protocole de communication. C’est souvent (toujours?) utilisé au travers du protocole HTTP car les headers, les verbes et les codes d’erreur déjà définis dans la norme rendent l’API simple à mettre en oeuvre.

Parmi les verbes, on a :

  • GET pour la récupération d’une ressource à partir d’une URI. C’est ce qui se passe quand le navigateur récupère un ensemble d’informations depuis un site Internet par exemple; tapoter http://www.brol.be dans la barre d’adresse, appuyez sur Entrée et cela fera un GET sur la ressource identifiée à cette URI.
  • POST pour la création d’une nouvelle ressource. Ce verbe est généralement utilisé par les formulaires lors de l’envoi d’informations.
  • PUT pour la mise-à-jour d’une ressource.
  • PATCH pour la mise-à-jour partielle.
  • DELETE pour la suppression.
  • HEAD pour récupérer uniquement le header d’une ressource. En gros, cela fait la même chose qu’un get, mais sans récupérer le contenu.
  • OPTIONS pour récupérer les actions possibles sur une URI.

A part GET et POST, les autres verbes sont/étaient finalement assez peu utilisés, mais présentent un réel intérêt dans la mesure où une même URI peut présenter un comportement différent suivant le verbe associé à l’action. Imaginez avoir l’URL suivante qui soit accessible:

http://my-site.be/api/gifts

Avec un GET, vous récupéreriez la liste complète de toutes les entrées présentes; tandis qu’un POST vous permettrait d’ajouter une nouvelle entrée. De même qu’un HEAD pourrait simplement transmetter la date à laquelle la liste a été mise-à-jour pour la dernière fois. De cette manière, pas besoin de faire un GET complet pour le client, si sa dernière requête est ultérieur à la dernière date de mise-à-jour.

En continuant l’exemple avec l’URL suivante:

http://my-site.be/api/gift/1

Un PUT permettra de mettre la ressource portant l’identifiant numéro 1 à jour, grâce à un ensemble de données passées en paramètres, tandis qu’un DELETE supprimera purement et simplement cette ressource.

Exemple pratique
#

Pour un exemple pratique, l’idéal est de commencer avec Flask. D’abord parce que c’est du Python (et donc, c’est bien), ensuite parce que la syntaxe est suffisamment claire que pour arriver à un résultat sans trop se fouler.

Il existe plusieurs librairies pour faciliter l’écriture d’une API Rest directement à partir de la base de données (à pouf: Flask-Restless pour SQLAlchemy et Flask-peewee).

Pour définir l’API en elle-même, rien de plus facile: on définit tout d’abord une fonction:

from flask import request

@app.route('/api/objects', methods=['GET', 'POST'])
def endpoint():
   if request.method == 'GET':
       pass
   elif request.method == 'POST':
       pass

Parmi les options, on spécifie quels verbes peuvent être utilisés, et en fonction du contexte, on traite les informations différement.

Maintenant qu’on a l’idée principale, on peut passer par un projet un chouia plus complet, avec une base de données et un modèle qui-va-bien en utilisant peewee (au niveau des dépendances, on a flask et flask-peewee):

from datetime import datetime
from flask import Flask
from flask import render_template
from flask_peewee.rest import RestAPI
import peewee

app = Flask(__name__, static_folder='static', static_url_path='') # création de l'appli Flask
database = peewee.SqliteDatabase('ev.db', threadlocals=True)  # création de la base de données.

database.connect()

class Event(peewee.Model):
    """
    Définition d'un nouvel évènement.
    Contient un champ description et une date.
    """

    description = peewee.TextField()
    date = peewee.DateTimeField(default=datetime.now)

    def __unicode__(self):
        return u"%s @ %s" % (self.description, self.date)

    class Meta:
        database = database

try:
    Event.create_table()
except Exception:
    pass

@app.route('/') # la racine de l'appli :)
def index():
    return render_template('index.html')

"""
Crée l'api, enregistre la classe Event définie ci-dessus, et crée les points d'accès.
"""
api = RestAPI(app)
api.register(Event)
api.setup()

if __name__ == '__main__':
    app.run(debug=True)

On lance ensuite l’application avec python application.py, et on accède à notre nouvelle API via l’URL http://localhost:5000/api/event. Cette action va faire un GET sur la classe et retournera la liste complète des instances.

Sources et ressources
#