Aller au contenu principal

API B2B / API interne avec Django DRF

Repères utiles :

info

Ce tutoriel explique comment penser une API destinée non plus seulement à un frontend utilisateur, mais à d'autres systèmes, organisations ou équipes techniques. L'objectif est de comprendre les enjeux spécifiques des APIs B2B et internes : stabilité, contrat, sécurité, intégration, versionnement, permissions et durabilité d'exploitation.

1. Introduction

Quand on découvre Django DRF, on pense souvent d'abord à un backend pour une application web ou mobile.

Mais dans beaucoup de produits réels, l'API n'est pas seulement consommée par un frontend maison. Elle est aussi — parfois surtout — consommée par :

  • d'autres équipes internes
  • d'autres services du même système
  • des partenaires
  • des clients B2B
  • des intégrations externes
  • des scripts, jobs ou plateformes techniques

Dès qu'on entre dans ce monde, les attentes changent. Une API B2B ou interne doit être non seulement fonctionnelle, mais aussi :

  • claire
  • stable
  • sécurisée
  • prévisible
  • intégrable
  • maintenable dans le temps

C'est précisément un terrain où Django DRF peut être très pertinent.

2. Le problème concret à résoudre

Imaginons plusieurs cas :

  • une entreprise cliente veut connecter son propre système à ton produit
  • une autre équipe interne veut exploiter tes données via une API
  • ton application doit échanger avec un ERP, un CRM ou un autre service métier
  • plusieurs micro-services ou services internes doivent lire et écrire certaines ressources
  • une plateforme partenaire doit pouvoir créer, lire ou synchroniser des objets

Le problème n'est plus simplement :

“comment faire une API qui fonctionne pour mon frontend ?”

Le problème devient :

“comment offrir une API fiable à d'autres systèmes, sans créer du chaos, de la fragilité ou de l'insécurité ?”

3. Qu'est-ce qu'une API B2B ?

Une API B2B est une API destinée à être consommée par d'autres entreprises, clients professionnels ou systèmes partenaires.

Dans ce contexte, l'API devient souvent une partie du produit lui-même. Elle ne sert pas seulement une interface graphique. Elle devient une surface de contrat entre ton système et d'autres organisations.

Exemples :

  • API de synchronisation de catalogues
  • API de gestion de commandes partenaires
  • API d'intégration avec des systèmes métier externes
  • API d'accès à des données ou statuts pour un client professionnel

4. Qu'est-ce qu'une API interne ?

Une API interne est une API conçue pour être utilisée à l'intérieur d'une organisation ou d'un système plus large.

Elle peut être consommée par :

  • d'autres équipes
  • d'autres services internes
  • des jobs techniques
  • des back-offices
  • des outils de reporting
  • des scripts d'exploitation

Elle n'est pas forcément publique. Mais cela ne veut pas dire qu'elle peut être bricolée. Au contraire, une API interne mal conçue crée souvent beaucoup de dette technique.

5. Pourquoi Django DRF est pertinent ici

Django DRF est particulièrement adapté à ce use case pour plusieurs raisons.

5.1 Il offre un cadre structurant pour l'API

Quand une API est consommée par d'autres systèmes, l'improvisation coûte cher. DRF aide à garder des conventions cohérentes autour de :

  • la représentation des données
  • la validation
  • les permissions
  • les réponses
  • les erreurs

5.2 Il est très bon pour les ressources métier structurées

Les APIs B2B ou internes exposent souvent des objets métier clairs :

  • comptes
  • commandes
  • dossiers
  • documents
  • produits
  • tickets
  • inspections
  • rapports

Django et son ORM rendent très naturelle la structuration de ces ressources.

5.3 Il aide à gérer sécurité et permissions

Même dans une intégration système-à-système, la question de l'accès est centrale. DRF aide à encadrer :

  • qui appelle
  • ce qu'il peut lire
  • ce qu'il peut écrire
  • dans quel périmètre

5.4 Il favorise la maintenabilité

Une API B2B ou interne peut vivre longtemps. Elle doit rester compréhensible, stable et évolutive. Django DRF fournit un cadre rassurant pour cela.

6. Quand utiliser Django DRF pour ce cas

Ce choix est particulièrement bon si :

  • tu exposes des ressources métier structurées à d'autres systèmes
  • tu veux une API durable et lisible
  • tu as besoin de sécurité et de permissions fines
  • tu veux standardiser les entrées/sorties
  • tu prévois plusieurs consommateurs techniques
  • tu veux garder une architecture propre à mesure que l'API grandit

Exemples typiques :

  • API client pour un portail B2B
  • API d'intégration partenaire
  • API interne entre équipes ou services
  • API d'administration technique ou d'exploitation
  • API de synchronisation entre systèmes d'entreprise

7. Quand Django DRF n'est pas forcément le meilleur choix

Django DRF n'est pas une réponse automatique à toute intégration.

Il peut être moins pertinent si :

  • ton besoin d'intégration est ultra-minimal et temporaire
  • le service est extrêmement simple et sans vraie logique métier
  • tu veux juste exposer quelques hooks ponctuels avec une stack déjà existante mieux adaptée à ce contexte
  • tu n'as quasiment aucune donnée structurée ou contrainte de contrat durable

Mais dès que l'API devient une interface importante du système, Django DRF redevient souvent très convaincant.

8. Pré-requis

Avant de tirer le meilleur de ce tutoriel, il est utile d'avoir déjà lu :

Les chapitres suivants sont aussi très liés :

9. Vocabulaire indispensable

Contrat API

Engagement implicite ou explicite sur la structure, le comportement et les attentes d'une API.

Intégration

Connexion entre ton système et un autre système.

Consommateur de l'API

Le client technique qui appelle l'API.

Périmètre d'accès

Ensemble des ressources qu'un consommateur a le droit de voir ou manipuler.

Versionnement

Manière d'introduire des évolutions sans casser brutalement les intégrations existantes.

Compatibilité

Capacité à faire évoluer l'API sans briser les usages déjà en place.

API publique / partenaire / interne

Trois niveaux d'exposition possibles, avec des contraintes souvent différentes.

10. Vision d'ensemble

Dans ce use case, l'API doit être pensée comme une interface de confiance entre systèmes.

Cela veut dire qu'elle doit être :

  • suffisamment claire pour être comprise
  • suffisamment stable pour être utilisée longtemps
  • suffisamment protégée pour éviter les abus ou erreurs
  • suffisamment explicite pour évoluer sans casser tout le monde

L'idée essentielle est donc :

une API B2B ou interne n'est pas seulement un tuyau technique ; c'est une surface contractuelle du produit ou du système.

11. Architecture type

Voici une architecture mentale simple.

graph TD
A[Client partenaire / système externe] --> B[API Django DRF]
H[Service interne / autre équipe] --> B
B --> C[Authentification et permissions]
B --> D[Serializers et validation]
B --> E[Logique métier]
E --> F[Base de données]
E --> G[Audit / logs / opérations]

11.1 Les consommateurs externes ou internes

Ils peuvent être très différents du frontend utilisateur. Ils n'ont pas forcément besoin d'une belle interface ; ils ont besoin d'une API claire et fiable.

11.2 L'API Django DRF

Elle sert de porte d'entrée stable.

11.3 L'authentification et les permissions

Elles encadrent le périmètre d'accès.

11.4 Les serializers

Ils aident à garantir la cohérence des données échangées.

11.5 L'audit et les logs

Ils deviennent très importants dès qu'il y a des intégrations système-à-système.

12. Ce qui change par rapport à une API pour frontend maison

Une API utilisée par ton propre frontend peut parfois tolérer une certaine proximité avec l'équipe produit.

En revanche, une API B2B ou interne consommée par d'autres équipes ou systèmes demande plus de discipline.

Pourquoi ? Parce que :

  • le consommateur n'est pas toujours dans ta tête
  • il ne connaît pas forcément tes hypothèses implicites
  • il dépend de la stabilité de ce que tu exposes
  • une rupture ou ambiguïté peut coûter cher

13. Construction pas à pas

Voici une manière saine de construire ce type d'API.

Étape 1 — Clarifier qui consomme l'API

Pose-toi :

  • est-ce un partenaire ?
  • une autre équipe ?
  • un autre service ?
  • un client B2B ?
  • un script interne ?

Cette réponse change beaucoup de choses.

Étape 2 — Clarifier l'objectif métier de l'intégration

L'API n'existe pas pour elle-même. Elle existe pour un usage.

Exemples :

  • synchroniser des commandes
  • exposer un catalogue
  • transmettre un statut
  • permettre une création contrôlée de dossiers
  • fournir un accès à certains rapports

Étape 3 — Clarifier les ressources exposées

Quelles ressources doivent vraiment être visibles ?

Il ne faut pas exposer tout ton système sans hiérarchie. Une bonne API expose ce qui est utile, pas tout ce qui existe.

Étape 4 — Clarifier le périmètre d'accès

Questions importantes :

  • le consommateur voit-il tout ?
  • seulement ses propres objets ?
  • seulement certaines organisations ?
  • seulement certaines actions ?

Étape 5 — Définir le contrat de données

Cette étape est centrale. Il faut penser :

  • quels champs sont exposés
  • quels champs sont obligatoires
  • quels formats sont attendus
  • quelles erreurs sont possibles
  • quelles règles doivent être explicites

Étape 6 — Penser la stabilité de l'API

Une intégration vit souvent plus longtemps qu'on ne l'imagine. Il faut donc éviter les changements brutaux et non réfléchis.

Étape 7 — Prévoir les erreurs et cas limites

Une bonne API B2B ou interne ne se contente pas d'un chemin heureux. Elle doit gérer proprement :

  • données invalides
  • droits insuffisants
  • objets introuvables
  • conflits métier
  • incohérences d'état

Étape 8 — Prévoir l'audit et le suivi

Si un partenaire ou un système envoie une mauvaise donnée, il faut pouvoir comprendre :

  • quand
  • comment
  • avec quel identifiant
  • sur quel objet
  • avec quel résultat

Étape 9 — Prévoir l'évolution future

Il faut se demander :

  • que se passe-t-il si de nouveaux champs arrivent ?
  • si une règle change ?
  • si un nouveau consommateur apparaît ?
  • si plusieurs intégrations coexistent ?

Étape 10 — Rester compréhensible

L'API doit rester explicable à :

  • ton équipe
  • l'équipe consommatrice
  • le support technique
  • le futur toi

14. Exemple concret mental

Prenons un exemple simple : une API B2B pour une plateforme de gestion documentaire.

Consommateurs

  • entreprises clientes
  • outils internes de reporting
  • service partenaire de validation

Ressources exposées

  • dossier
  • document
  • statut
  • historique minimal

Questions à résoudre

  • une entreprise ne voit-elle que ses propres dossiers ?
  • quels statuts peut-elle modifier ?
  • quels champs peut-elle renseigner ?
  • quelles erreurs renvoyer si un document manque ou est invalide ?
  • que faire si l'état d'un dossier interdit l'action demandée ?

Tu vois ici que l'API n'est pas juste une vue technique sur la base. Elle devient un contrat métier opérationnel.

15. Ce qu'il faut particulièrement surveiller

15.1 Les permissions

Une API inter-systèmes mal protégée peut exposer beaucoup trop de données.

15.2 Les changements de structure

Modifier un champ, une règle ou une réponse sans réflexion peut casser des intégrations en production.

15.3 Les hypothèses implicites

Ce qui semble évident à ton équipe ne l'est pas forcément pour une autre.

15.4 La qualité des erreurs renvoyées

Une erreur obscure rend une intégration très pénible à maintenir.

15.5 L'audit

Sans traces exploitables, le diagnostic des incidents devient très coûteux.

16. Erreurs fréquentes

Erreur 1 — Traiter une API B2B comme un simple backend frontend

Les exigences de stabilité et de contrat sont plus fortes.

Erreur 2 — Exposer trop de choses trop vite

Il vaut mieux une surface d'API claire et limitée qu'une exposition massive et confuse.

Erreur 3 — Négliger le périmètre d'accès

Une API B2B doit souvent être très stricte sur “qui voit quoi”.

Erreur 4 — Faire évoluer l'API sans stratégie

Les intégrations cassent vite quand les changements ne sont pas gouvernés.

Erreur 5 — Oublier les besoins internes de diagnostic

Une API sans logs, traces et compréhension de l'activité devient difficile à exploiter.

Erreur 6 — Penser qu'une API interne peut être brouillonne parce qu'elle n'est pas publique

Les APIs internes créent elles aussi beaucoup de dette si elles sont mal conçues.

17. Bonnes pratiques

17.1 Exposer un périmètre d'API intentionnel

Ne pas tout exposer par réflexe.

17.2 Traiter le contrat comme une responsabilité produit

Même sans formalisme excessif, il faut penser la stabilité et la clarté.

17.3 Garder une logique métier côté backend

Les systèmes intégrés doivent dépendre d'un backend fiable, pas de suppositions.

17.4 Soigner les permissions et le périmètre d'accès

Surtout si plusieurs organisations ou partenaires sont concernés.

17.5 Prévoir audit, logs et traçabilité

Indispensable dès que l'API a une importance opérationnelle.

17.6 Rester explicable et lisible

Une API bien pensée est une API qu'une autre équipe peut comprendre sans appel téléphonique permanent.

18. Variantes et évolutions possibles

Variante 1 — API interne simple

Une équipe interne expose quelques ressources à une autre équipe ou service.

Variante 2 — API partenaire ciblée

Une entreprise partenaire consomme une partie du système.

Variante 3 — API B2B plus riche

Plusieurs types d'objets, plusieurs droits, plusieurs périmètres d'accès.

Variante 4 — API avec exigences de stabilité plus fortes

Versionnement, compatibilité, gouvernance des changements.

Variante 5 — Écosystème d'intégrations plus mature

Plusieurs partenaires, plusieurs consommateurs internes, observabilité renforcée, outillage d'exploitation plus solide.

19. Comment savoir si tu vas dans la bonne direction

Tu avances bien si :

  • tu sais clairement qui consomme l'API
  • tu sais pourquoi il la consomme
  • tu sais quelles ressources sont réellement exposées
  • le périmètre d'accès est clair
  • l'API reste stable et compréhensible
  • ton équipe peut diagnostiquer les problèmes d'intégration sans naviguer à l'aveugle

20. Résumé final

Django DRF est un excellent choix pour les APIs B2B et internes lorsque l'on veut construire une interface système-à-système stable, claire, sécurisée et durable.

Sa force dans ce use case vient de sa capacité à bien combiner :

  • ressources métier structurées
  • validation et représentation cohérentes
  • permissions contrôlées
  • logique backend fiable
  • maintenabilité dans le temps

L'idée la plus importante à retenir est la suivante :

une API B2B ou interne n'est pas juste une commodité technique ; c'est une promesse opérationnelle faite à d'autres systèmes ou équipes.

21. Pour aller plus loin

La suite logique du wiki est maintenant :

Relire aussi :

22. Mini-projet guidé avec code

Pour rendre ce use case concret, on va prendre un exemple simple mais réaliste :

une API B2B où chaque partenaire envoie ses commandes via un token d'accès

Le but du mini-projet est de montrer :

  • comment exposer un contrat stable
  • comment isoler les données de chaque partenaire
  • comment sécuriser l'accès sans dépendre d'une session navigateur
  • comment versionner proprement l'URL dès le départ

23. Structure du mini-projet

partnerhub/
├── manage.py
├── partnerhub/
│ ├── settings.py
│ ├── urls.py
│ └── ...
└── integrations/
├── admin.py
├── models.py
├── serializers.py
├── permissions.py
├── views.py
└── urls.py

Repères utiles avant de lire le code :

  • settings.py active une authentification par token adaptée aux appels système-à-système.
  • models.py rend explicites le partenaire, son périmètre et les commandes qu'il pousse.
  • serializers.py matérialise un contrat API simple et stable.
  • permissions.py empêche un partenaire d'accéder au périmètre d'un autre.
  • views.py rattache automatiquement chaque commande au bon partenaire.
  • urls.py versionne l'API dès /api/v1/.
  • admin.py permet de superviser et débloquer facilement les intégrations.

24. Implémentation guidée avec code

Étape 1 — Créer le projet et installer DRF avec l'authentification par token

python -m venv .venv
source .venv/bin/activate
pip install django djangorestframework

django-admin startproject partnerhub .
python manage.py startapp integrations

Étape 2 — Déclarer DRF, l'authtoken et l'application

Dans partnerhub/settings.py :

INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"rest_framework",
"rest_framework.authtoken",
"integrations",
]

REST_FRAMEWORK = {
"DEFAULT_PERMISSION_CLASSES": [
"rest_framework.permissions.IsAuthenticated",
],
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework.authentication.TokenAuthentication",
],
}

Puis lancer :

python manage.py makemigrations
python manage.py migrate

Pourquoi ? Parce qu'une API B2B ou interne doit souvent être appelée par des systèmes, pas par un navigateur connecté en session.

Étape 3 — Modéliser le partenaire et la ressource exposée

Dans integrations/models.py :

from django.conf import settings
from django.db import models


class PartnerAccount(models.Model):
user = models.OneToOneField(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE,
related_name="partner_account",
)
company_name = models.CharField(max_length=150)
is_active = models.BooleanField(default=True)

def __str__(self) -> str:
return self.company_name


class PartnerOrder(models.Model):
STATUS_CHOICES = [
("received", "Received"),
("accepted", "Accepted"),
("rejected", "Rejected"),
]

partner = models.ForeignKey(
PartnerAccount,
on_delete=models.CASCADE,
related_name="orders",
)
external_reference = models.CharField(max_length=120)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default="received")
created_at = models.DateTimeField(auto_now_add=True)

class Meta:
constraints = [
models.UniqueConstraint(
fields=["partner", "external_reference"],
name="unique_external_reference_per_partner",
)
]

def __str__(self) -> str:
return f"{self.partner.company_name} - {self.external_reference}"

Pourquoi ? Parce qu'une API B2B sérieuse doit porter explicitement :

  • l'identité du partenaire
  • son périmètre de données
  • une référence métier externe
  • un statut clair et stable

Étape 4 — Créer le serializer du contrat API

Dans integrations/serializers.py :

from rest_framework import serializers

from .models import PartnerOrder


class PartnerOrderSerializer(serializers.ModelSerializer):
partner_name = serializers.CharField(source="partner.company_name", read_only=True)

class Meta:
model = PartnerOrder
fields = [
"id",
"external_reference",
"partner_name",
"total_amount",
"status",
"created_at",
]
read_only_fields = ["id", "partner_name", "status", "created_at"]

Pourquoi ? Parce qu'ici le serializer devient le contrat visible par l'intégrateur. Il faut qu'il reste simple, lisible et stable.

Étape 5 — Poser une permission dédiée aux partenaires actifs

Dans integrations/permissions.py :

from rest_framework.permissions import BasePermission


class IsActivePartner(BasePermission):
def has_permission(self, request, view):
partner_account = getattr(request.user, "partner_account", None)
return bool(request.user and request.user.is_authenticated and partner_account and partner_account.is_active)

def has_object_permission(self, request, view, obj):
partner_account = getattr(request.user, "partner_account", None)
return bool(partner_account and obj.partner == partner_account and partner_account.is_active)

Pourquoi ? Parce qu'une intégration B2B ne doit jamais pouvoir lire ou écrire dans le périmètre d'un autre partenaire.

Étape 6 — Écrire le viewset DRF versionné

Dans integrations/views.py :

from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated

from .models import PartnerOrder
from .permissions import IsActivePartner
from .serializers import PartnerOrderSerializer


class PartnerOrderViewSet(viewsets.ModelViewSet):
serializer_class = PartnerOrderSerializer
permission_classes = [IsAuthenticated, IsActivePartner]

def get_queryset(self):
return PartnerOrder.objects.filter(
partner=self.request.user.partner_account
).order_by("-created_at")

def perform_create(self, serializer):
serializer.save(partner=self.request.user.partner_account)

Pourquoi ce code est important ? Parce qu'il met en place les bases du contrat opérationnel :

  • chaque partenaire voit uniquement ses commandes
  • le backend fixe le rattachement du partenaire
  • l'intégrateur n'a pas à envoyer lui-même un identifiant de périmètre fragile

Étape 7 — Brancher les routes en versionnant l'URL

Dans integrations/urls.py :

from rest_framework.routers import DefaultRouter

from .views import PartnerOrderViewSet

router = DefaultRouter()
router.register("orders", PartnerOrderViewSet, basename="partner-order")

urlpatterns = router.urls

Dans partnerhub/urls.py :

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
path("admin/", admin.site.urls),
path("api/v1/", include("integrations.urls")),
]

Pourquoi v1 dès le départ ? Parce qu'une API B2B ou interne est un contrat dans la durée. Prévoir une stratégie de versionnement tôt évite beaucoup de douleur plus tard.

Étape 8 — Ajouter l'admin Django

Dans integrations/admin.py :

from django.contrib import admin

from .models import PartnerAccount, PartnerOrder

admin.site.register(PartnerAccount)
admin.site.register(PartnerOrder)

Pourquoi ? Parce que même une API system-to-system a besoin d'un endroit simple pour activer un partenaire, inspecter les ordres reçus et débloquer une intégration.

25. Vérification guidée

Préparer un compte partenaire

python manage.py createsuperuser
python manage.py runserver

Dans l'admin :

  • créer un utilisateur partner_a
  • créer son PartnerAccount
  • générer son token :
python manage.py drf_create_token partner_a

Envoyer une commande partenaire

curl -X POST http://127.0.0.1:8000/api/v1/orders/ \
-H "Authorization: Token TON_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"external_reference": "PO-2026-001",
"total_amount": "4200.00"
}'

Lister uniquement les commandes du partenaire

curl http://127.0.0.1:8000/api/v1/orders/ \
-H "Authorization: Token TON_TOKEN"

Ce que tu dois observer

  • le contrat API est court et stable
  • le partenaire n'envoie pas son propre identifiant de périmètre
  • les données sont automatiquement isolées par compte partenaire
  • l'authentification par token est adaptée à un appel système-à-système

26. Ce que cet exemple t'apprend vraiment

Cet exemple montre comment DRF est utilisé concrètement dans une API B2B ou interne :

  • les modèles rendent explicite la notion de partenaire
  • le serializer matérialise le contrat échangé
  • la permission protège le périmètre de données
  • le viewset garde l'API simple mais fiable
  • le versionnement d'URL prépare l'évolution future du contrat

Autrement dit, on voit ici qu'une API B2B n'est pas juste “une API comme une autre” : c'est une surface stable, sécurisée et pensée pour des systèmes externes ou internes.

success

Si tu comprends bien ce mini-projet, tu commences à penser une intégration comme un contrat durable entre systèmes, et non comme un simple endpoint pratique à brancher rapidement.