Aller au contenu

Développement d'API Rest avec Connexion - Partie 1

Mise à jour :

logo connexion

Développer une API RESTful peut devenir un véritable casse-tête dès que vous avez besoin de gérer des spécifications précises, des validations complexes ou une documentation interactive. Heureusement, Connexion simplifie tout ce processus en vous permettant de décrire votre API directement dans un fichier OpenAPI (YAML ou JSON).

Contrairement à une idée reçue, Connexion ne dépend plus forcément de Flask. Bien qu’il s’intègre parfaitement à ce framework, il peut fonctionner de manière indépendante, offrant encore plus de flexibilité pour vos projets. En bref, Connexion devient une couche d’abstraction qui vous libère des tâches fastidieuses comme :

  • La validation automatique des entrées et des sorties.
  • La génération de documentation interactive via Swagger UI.
  • La gestion des erreurs HTTP et des schémas d’authentification.

L’objectif est simple : vous fournir un outil pour écrire des APIs robustes, évolutives et documentées en un minimum d’efforts. Peu importe votre stack existante, Connexion s’intègre comme un partenaire de choix pour vos projets RESTful. Franchement, que demander de plus ?

Un peu d’Histoire

Connexion est un framework Python développé par Zalando, le géant allemand du commerce en ligne, pour faciliter la création d’APIs RESTful conformes aux spécifications OpenAPI.

En 2015, Zalando a initié le développement de Connexion pour répondre à ses besoins internes en matière d’APIs robustes et bien documentées. Le projet a été rendu open source, permettant à la communauté de bénéficier de ses fonctionnalités.

Depuis sa création, Connexion a connu plus majeures, intégrant des fonctionnalités avancées telles que la validation automatique des requêtes et des réponses, la gestion des schémas d’authentification et la génération de documentation interactive via Swagger UI. Ces évolutions ont renforcé sa position en tant qu’outil incontournable pour les développeurs Python souhaitant créer des APIs conformes aux standards modernes.

Aujourd’hui, Connexion continue d’être activement maintenu et amélioré, avec une communauté engagée qui contribue à son développement et à son adoption dans divers projets à travers le monde.

Qu’est-ce qu’une API REST ?

Avant de plonger dans Connexion, il est essentiel de comprendre les bases des APIs REST. Ce modèle d’architecture est aujourd’hui incontournable pour développer des services web et interopérables. Pas besoin d’être un expert pour suivre, mais maîtriser ces concepts vous permettra d’avancer avec confiance.

Une API (Application Programming Interface) est une interface qui permet à des applications de communiquer entre elles.

REST (REpresentational State Transfer) est un style architectural qui impose des règles pour structurer ces interactions en utilisant les protocoles web, comme HTTP.

Une API REST se base sur des principes clés :

  • Stateless : chaque requête est indépendante et contient toutes les informations nécessaires.
  • Uniformité : une API REST expose des ressources (utilisateurs, produits, etc.) accessibles via des URL claires et standardisées.
  • Client-serveur : le client (frontend ou une autre application) et le serveur (l’API) sont indépendants.

Les APIs REST s’appuient sur les méthodes HTTP pour effectuer différentes actions :

MéthodeActionExemple
GETRécupérer une ressourceGET /users
POSTCréer une nouvelle ressourcePOST /users
PUTModifier une ressource existantePUT /users/1
DELETESupprimer une ressourceDELETE /users/1

Les APIs REST renvoient des codes de statut HTTP pour indiquer le résultat d’une requête. Voici les principaux à connaître :

CodeSignificationExemple d’utilisation
200OKRequête réussie
201CreatedRessource créée avec succès
400Bad RequestRequête mal formée
401UnauthorizedAccès non autorisé
404Not FoundRessource non trouvée
500Internal Server ErrorErreur côté serveur

Les ressources sont les données accessibles via l’API (comme des utilisateurs, des commandes, etc.). Chaque ressource est représentée par une URL :

GET /users # Liste des utilisateurs
GET /users/1 # Détails de l'utilisateur avec ID 1
POST /users # Ajouter un nouvel utilisateur
PUT /users/1 # Mettre à jour l'utilisateur avec ID 1
DELETE /users/1 # Supprimer l'utilisateur avec ID 1

Les APIs REST utilisent généralement le format JSON pour échanger des données. Exemple :

Requête POST pour créer un utilisateur :

{
"name": "Stéphane ROBERT",
"email": "stéphane.robert@example.com"
}

Réponse JSON :

{
"id": 1,
"name": "Stéphane ROBERT",
"email": "stéphane.robert@example.com"
}

Les APIs REST nécessitent souvent une authentification pour sécuriser les échanges. Les approches courantes incluent :

  • Token Bearer (comme JWT).
  • OAuth2 pour des systèmes tiers.

Tous ces concepts seront développés sous peu dans un guide dédié. Vous y trouverez des explications détaillées, des exemples concrets et des outils pratiques pour aller plus loin !

La norme OpenAPI : Une base solide pour vos APIs

OpenAPI, anciennement connu sous le nom de Swagger, est une spécification qui définit un standard pour concevoir, décrire et documenter vos APIs RESTful. À mes yeux, c’est l’une des meilleures choses qui soient arrivées au développement des APIs : elle structure vos idées, clarifie vos interfaces et fait gagner un temps précieux aux développeurs.

C’est quoi, au juste ?

La norme OpenAPI est un format de fichier, en JSON ou YAML, qui décrit tous les détails d’une API, notamment :

  • Les routes accessibles (endpoints).
  • Les méthodes HTTP utilisées (GET, POST, PUT, etc.).
  • Les paramètres attendus (query, path, body).
  • Les schémas de données échangés (souvent en JSON).
  • Les codes de statut possibles pour chaque route.

En gros, c’est comme un plan détaillé de votre API, lisible à la fois par les humains et les machines.

Pourquoi utiliser OpenAPI ?

Adopter OpenAPI, c’est bénéficier de nombreux avantages :

  • Documentation interactive : Avec des outils comme Swagger UI, vous obtenez une documentation conviviale et testable en temps réel.
  • Clarté : Tout est écrit noir sur blanc, réduisant les malentendus entre les équipes backend et frontend.
  • Standardisation : Que vous changiez d’équipe ou de projet, tout le monde comprend les APIs décrites avec OpenAPI.
  • Automatisation : Certains frameworks, comme Connexion, utilisent OpenAPI pour valider automatiquement les requêtes ou générer des stubs de code.

Structure d’un fichier OpenAPI

Un fichier OpenAPI est organisé de manière hiérarchique. Voici un exemple simple en YAML :

openapi: "3.0.0"
info:
title: "Exemple API"
version: "1.0.0"
description: "Une API pour dire bonjour"
paths:
/hello:
get:
summary: "Dire bonjour"
responses:
"200":
description: "Message de bienvenue"
content:
application/json:
schema:
type: object
properties:
message:
type: string
example: "Bonjour, monde !"
  • openapi : Spécifie la version de la norme (3.0.0 dans ce cas).
  • info : Donne des détails sur l’API (titre, version, description).
  • paths : Liste les routes disponibles (/hello ici).
  • responses : Décrit ce que l’API renvoie en cas de succès ou d’erreur.

OpenAPI est bien plus qu’une simple documentation : c’est un standard qui simplifie la collaboration, améliore la qualité de vos APIs et booste votre productivité. Si vous voulez structurer vos projets avec des bases solides, c’est une norme incontournable. Et vous allez voir, comment Connexion en tire parti.

Installation et configuration de base de Connexion

Connexion est facile à installer et ne nécessite que quelques étapes simples. Que vous utilisiez un environnement basé sur Flask ou une architecture indépendante, voici comment démarrer.

Avant de commencer, assurez-vous que votre environnement remplit ces conditions :

  • Python 3.10 ou supérieur.
  • Un outil de gestion d’environnement virtuel comme venv ou virtualenv.

Il est toujours recommandé d’isoler les dépendances de votre projet. Pour cela, créez un environnement virtuel :

Terminal window
python -m venv env
source env/bin/activate # Sur Windows, utilisez env\Scripts\activate

Pour installer Connexion, utilisez simplement pip :

Terminal window
pip install connexion[swagger-ui,uvicorn]

L’option [swagger-ui,uvicorn] inclut l’interface Swagger UI pour la documentation interactive de votre API.

Création d’un projet minimaliste

Créez un fichier Python, par exemple app.py, et un fichier OpenAPI openapi.yaml. Voici un exemple :

./openapi.yaml
openapi: "3.0.0"
info:
title: Hello World
version: "1.0"
servers:
- url: /openapi
paths:
/greeting/{name}:
post:
operationId: app.post_greeting
responses:
200:
description: "Greeting response"
content:
text/plain:
schema:
type: string
parameters:
- name: name
in: path
required: true
schema:
type: string
./app.py
from connexion import AsyncApp
from pathlib import Path
app = AsyncApp(__name__)
def post_greeting(name: str):
return f"Hello {name}", 201
app.add_api("openapi.yaml")
if __name__ == "__main__":
app.run(f"{Path(__file__).stem}:app")

Exécutez votre application :

Terminal window
python3 app.py
`ConnexionMiddleware.run` is optimized for development. For production, run using a dedicated ASGI server.
INFO: Will watch for changes in these directories: ['/home/bob/Projets/lms']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [467173] using WatchFiles
INFO: Started server process [467175]
INFO: Waiting for application startup.
INFO: Application startup complete.

Vous devriez voir un message indiquant que le serveur est en cours d’exécution sur le port 8080. Accédez à l’URL suivante dans votre navigateur.

connexion openapi

Testez votre première route /greeting/{name} en l’appelant via une commande curl :

Terminal window
curl -X POST http://localhost:8000/openapi/greeting/St%C3%A9phane
Hello Stéphane

On reçoit bien la réponse à notre requête.

Avec ces quelques étapes, vous avez configuré votre première API avec Connexion. Bien sûr, ce n’est que le début ! Dans les chapitres suivants, nous explorerons des fonctionnalités avancées comme la validation des données et la sécurisation de vos routes.

Gestion avancée des routes avec Connexion

Après avoir configuré une API basique avec Connexion et le fichier OpenAPI ci-dessus, explorons des fonctionnalités avancées pour enrichir et personnaliser vos routes. Cela va nous permettre de prendre en charge des cas d’usage plus complexes.

Voici un rappel du fichier openapi.yaml utilisé :

openapi: "3.0.0"
info:
title: Hello World
version: "1.0"
servers:
- url: /openapi
paths:
/greeting/{name}:
post:
operationId: app.post_greeting
responses:
200:
description: "Greeting response"
content:
text/plain:
schema:
type: string
parameters:
- name: name
in: path
required: true
schema:
type: string

Et voici le fichier Python associé :

app.py :

def post_greeting(name):
return f"Hello, {name}!", 200

Cette configuration fournit une route POST /openapi/greeting/{name}, qui retourne un message de bienvenue.

Ajout de paramètres query

Pour enrichir cette route, ajoutons des paramètres optionnels dans l’URL. Par exemple, un paramètre lang pour personnaliser la langue du message.

Mise à jour de openapi.yaml :

paths:
/greeting/{name}:
post:
operationId: app.post_greeting
parameters:
- name: name
in: path
required: true
schema:
type: string
- name: lang
in: query
required: false
schema:
type: string
enum: [en, fr, es]
default: "en"
responses:
200:
description: "Greeting response"
content:
text/plain:
schema:
type: string

Mise à jour de app.py :

def post_greeting(name, lang="en"):
greetings = {
"en": f"Hello, {name}!",
"fr": f"Bonjour, {name}!",
"es": f"Hola, {name}!",
}
return greetings.get(lang, f"Hello, {name}!"), 200

Test :

Terminal window
curl -X 'POST' \
'http://127.0.0.1:8000/openapi/greeting/John?lang=es' \
-H 'accept: text/plain' \
-d ''
Hola, John!

Validation automatique des données

Grâce à OpenAPI, Connexion valide les paramètres et renvoie automatiquement une erreur si quelque chose ne va pas. Par exemple :

  • Si lang contient une valeur invalide, Connexion retourne une réponse 400 Bad Request avec un message d’erreur clair.
  • Si le paramètre obligatoire name est manquant, une erreur similaire est renvoyée.

Vous pouvez tester cela en appelant la route avec un lang non pris en charge comme it.

Terminal window
curl -X 'POST' \
'http://127.0.0.1:8000/openapi/greeting/John?lang=it' \
-H 'accept: text/plain' \
-d '' | jq
{
"type": "about:blank",
"title": "Bad Request",
"detail": "'it' is not one of ['en', 'fr', 'es']\n\nFailed validating 'enum' in schema:\n {'type': 'string', 'enum': ['en', 'fr', 'es'], 'default': 'en'}\n\nOn instance:\n 'it'",
"status": 400
}

Ajout d’un body JSON

Étendons encore la route pour accepter des données supplémentaires via le body d’une requête JSON. Par exemple, un message personnalisé à inclure dans la réponse.

Mise à jour de openapi.yaml :

paths:
/greeting/{name}:
post:
operationId: app.post_greeting
parameters:
- name: name
in: path
required: true
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
custom_message:
type: string
description: "Message personnalisé"
required: [custom_message]
responses:
200:
description: "Greeting response"
content:
text/plain:
schema:
type: string

Mise à jour de app.py :

def post_greeting(name, body):
custom_message = body.get("custom_message", "")
return f"Hello, {name}! {custom_message}", 200

Test : Envoyez une requête avec le body suivant :

Terminal window
curl -X 'POST' \
'http://127.0.0.1:8000/openapi/greeting/Damien' \
-H 'accept: text/plain' \
-H 'Content-Type: application/json' \
-d '{
"custom_message": "Welcome to Our API !"
}'
Hello, Damien! Welcome to Our API !%

Combiner plusieurs méthodes HTTP

Ajoutons une méthode GET pour la même route /greeting/{name}, qui retourne un message sans body.

Mise à jour de openapi.yaml :

paths:
/greeting/{name}:
get:
operationId: app.get_greeting
parameters:
- name: name
in: path
required: true
schema:
type: string
responses:
200:
description: "Greeting response"
content:
text/plain:
schema:
type: string

Mise à jour de app.py :

def get_greeting(name):
return f"Hello, {name}!", 200

Avec cette mise à jour, vous pouvez appeler :

Terminal window
curl -X 'GET' \
'http://127.0.0.1:8000/openapi/greeting/Toto' \
-H 'accept: text/plain'
Hello, Toto!%

Conclusion

Nous venons de parcourir les bases et quelques fonctionnalités avancées de Connexion. Vous avez appris à configurer une API REST, à gérer des routes avec des paramètres dynamiques et à valider automatiquement les données grâce à OpenAPI. Ces outils sont déjà suffisants pour créer une API fonctionnelle, documentée et évolutive.

Mais ce n’est que le début ! Dans la seconde partie, nous approfondirons les fonctionnalités de Connexion pour répondre à des besoins encore plus complexes :

  • Sécurisation des APIs avec OAuth2, JWT, et Basic Auth.
  • Validation avancée des données grâce aux schémas JSON et OpenAPI.
  • Gestion des erreurs HTTP personnalisées pour enrichir l’expérience client.
  • Tests automatisés pour garantir la robustesse de vos APIs.
  • Bonnes pratiques pour structurer vos fichiers OpenAPI et votre code.

La suite promet d’être encore plus passionnante !

Plus d’infos