Intermédiaire

Concevoir une API REST

Avant d'écrire du code, il faut concevoir son API : quelles ressources exposer, comment nommer les routes, comment structurer les réponses.

Nommage des ressources

Les URI d'une API REST suivent des conventions :

RègleBon exempleMauvais exemple
Noms (pas de verbes)/api/v1/ventes/api/v1/getVentes
Pluriel/api/v1/produits/api/v1/produit
Minuscules/api/v1/clients/api/v1/Clients
Tirets (pas de underscores)/api/v1/chiffre-affaires/api/v1/chiffre_affaires
Hiérarchie logique/api/v1/clients/42/commandes/api/v1/commandesClient42

Pourquoi ces conventions ?

Ces règles rendent l'API prévisible : un développeur qui connaît une route peut deviner les autres.

CRUD et méthodes HTTP

Le mapping entre opérations CRUD et méthodes HTTP :

OpérationMéthodeURIDescription
ListerGET/api/v1/ventesToutes les ventes (paginées)
LireGET/api/v1/ventes/42Une vente spécifique
CréerPOST/api/v1/ventesNouvelle vente
RemplacerPUT/api/v1/ventes/42Remplacement complet
ModifierPATCH/api/v1/ventes/42Modification partielle
SupprimerDELETE/api/v1/ventes/42Suppression

Design d'URI pour une API de données

Pour une API orientée données, on dépasse le CRUD classique :

# CRUD standard
GET    /api/v1/ventes              # Liste paginée
GET    /api/v1/ventes/42           # Détail d'une vente
POST   /api/v1/ventes              # Créer une vente

# Filtrage et pagination (query parameters)
GET    /api/v1/ventes?region=IDF&annee=2024&limit=50&offset=0

# Tri
GET    /api/v1/ventes?sort_by=montant&order=desc

# Agrégation (sous-ressources)
GET    /api/v1/ventes/stats                   # Statistiques globales
GET    /api/v1/ventes/par-region              # Ventes groupées par région
GET    /api/v1/ventes/evolution-mensuelle     # Évolution dans le temps

# Export
GET    /api/v1/ventes?format=csv              # Export CSV

Endpoints d'agrégation

Les endpoints d'agrégation (/stats, /par-region) sont des sous-ressources de la collection. Ce n'est pas du CRUD, c'est de l'analytique — détaillé dans la section dédiée.

Versioning

Versionnez l'API dès le départ. La méthode la plus courante : inclure la version dans l'URL.

/api/v1/ventes
/api/v2/ventes    # Nouvelle version avec champs différents

Cela permet de faire évoluer l'API sans casser les clients existants. Un dashboard qui consomme /api/v1/ ne doit pas s'arrêter parce que le format de réponse a changé.

Exemple Flask complet

Déclaration des routes pour une ressource ventes avec Flask :

python
from flask import Flask, Blueprint, request, jsonify

app = Flask(__name__)

# Création du Blueprint
ventes_bp = Blueprint('ventes', __name__, url_prefix='/api/v1/ventes')

@ventes_bp.route('', methods=['GET'])
def lister_ventes():
    """Liste paginée des ventes avec filtres optionnels."""
    region = request.args.get('region')
    annee = request.args.get('annee', type=int)
    limit = request.args.get('limit', 20, type=int)
    offset = request.args.get('offset', 0, type=int)

    # ... logique de récupération des données ...

    return jsonify({
        "data": [],       # Les ventes
        "total": 0,       # Nombre total (avant pagination)
        "limit": limit,
        "offset": offset
    })

@ventes_bp.route('/<int:vente_id>', methods=['GET'])
def detail_vente(vente_id):
    """Détail d'une vente par son ID."""
    # ... logique de récupération ...
    return jsonify({"id": vente_id, "montant": 1500.0})

@ventes_bp.route('/stats', methods=['GET'])
def statistiques_ventes():
    """Statistiques agrégées des ventes."""
    # ... logique d'agrégation ...
    return jsonify({
        "total_ventes": 15000,
        "montant_moyen": 250.0,
        "nombre_ventes": 60
    })

# Enregistrement du Blueprint
app.register_blueprint(ventes_bp)

Blueprint

Un Blueprint Flask est un module de routes. Il permet d'organiser les routes par ressource (un Blueprint pour les ventes, un pour les clients, etc.). Le url_prefix évite de répéter le chemin de base dans chaque route.

Quelle URI est correctement conçue pour récupérer les commandes du client 42 ?

Pourquoi versionner son API dès le départ ?

À retenir

Points clés

  • Les URI utilisent des noms au pluriel, en minuscules, avec des tirets
  • Le mapping CRUD → HTTP est : GET (lire), POST (créer), PUT (remplacer), PATCH (modifier), DELETE (supprimer)
  • Pour les données décisionnelles, on ajoute des endpoints d'agrégation (/stats, /par-region) et d'export (?format=csv)
  • Le versioning (/api/v1/) protège les clients existants lors des évolutions
  • Un Blueprint Flask regroupe les routes d'une même ressource