Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds ➔
👥 Community & Social
•
Sichere ProgrammierungBreeze TTS 2 vs ElevenLabs: Open Source TTS Verdict(23.09.2026 um 05:44 Uhr)
••
Sichere ProgrammierungAgentic AI vs Generative AI: The 2026 Verdict(23.09.2026 um 05:44 Uhr)
•
Sichere ProgrammierungI made my agent prove every quote against the source document(23.09.2026 um 05:45 Uhr)
•
Sichere Programmierung8mb.video Alternative: Skip the Line, Skip the Upsell(23.09.2026 um 05:47 Uhr)
•
Sichere ProgrammierungBuilding a GTA 6 JSON API for entities and current status(23.09.2026 um 05:52 Uhr)
••
Sichere ProgrammierungEvery filter needs a documented exception(23.09.2026 um 06:01 Uhr)
•••
Sichere ProgrammierungBreeze TTS 2 vs ElevenLabs: Open Source TTS Verdict(23.09.2026 um 05:44 Uhr)
••
Sichere ProgrammierungAgentic AI vs Generative AI: The 2026 Verdict(23.09.2026 um 05:44 Uhr)
•
Sichere ProgrammierungI made my agent prove every quote against the source document(23.09.2026 um 05:45 Uhr)
•
Sichere Programmierung8mb.video Alternative: Skip the Line, Skip the Upsell(23.09.2026 um 05:47 Uhr)
•
Sichere ProgrammierungBuilding a GTA 6 JSON API for entities and current status(23.09.2026 um 05:52 Uhr)
••
Sichere ProgrammierungEvery filter needs a documented exception(23.09.2026 um 06:01 Uhr)
••
Intelligence View
⚡ tsecurity.de Intelligence

Mon architecture microservices e-commerce (et les erreurs à éviter)

L'architecture complète 4 APIs indépendantes qui communiquent entre elles: ┌──────────────┐ │ Frontend │ (Django/port 8004) └──────┬───────┘ │ ├──→ API Clients (Django/port 8000) → MariaDB ├──→ API Catalogue…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




L'architecture complète



4 APIs indépendantes qui communiquent entre elles:




┌──────────────┐
│ Frontend │ (Django/port 8004)
└──────┬───────┘
│
├──→ API Clients (Django/port 8000) → MariaDB
├──→ API Catalogue (Django/port 8001) → MariaDB
├──→ API Panier (Flask/port 8002) → Redis
└──→ API Commandes (Django/port 8003) → MariaDB






Chaque API:




  • A sa propre base de données (MariaDB ou Redis)

  • Tourne dans son propre container Docker

  • Est déployée indépendamment sur Kubernetes

  • A son propre repo Git






API Clients : authentification centralisée



C'est le point d'entrée pour tout ce qui touche aux utilisateurs.



Endpoints principaux:




POST /api/auth/register/  → Créer un compte
POST /api/auth/login/ → Se connecter (retourne un token)
GET /api/auth/validate-token/ → Valider un token
GET /api/auth/profile/ → Récupérer son profil






Modèle User:




class User(AbstractUser):
ROLE_CHOICES = [
('client', 'Client'),
('vendeur', 'Vendeur'),
('admin', 'Administrateur'),
]

role = models.CharField(
max_length=10,
choices=ROLE_CHOICES,
default='client'
)






Le truc important: les autres APIs ne gèrent PAS l'auth. Elles font juste une requête à l'API Clients pour valider le token.






Authentification externe pour les autres APIs



Voici comment j'ai fait l'auth dans les autres services:




# api/authentification.py (API Catalogue/Commandes)
class ExternalUser:
def __init__(self, user_id: int, first_name: str, last_name: str, role: str):
self.id = user_id
self.first_name = first_name
self.last_name = last_name
self.role = role

@property
def is_authenticated(self) -> bool:
return True

class ExternalTokenAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
auth_header = request.META.get("HTTP_AUTHORIZATION", "")
if not auth_header:
return None

parts = auth_header.split()
if len(parts) != 2 or parts[0] not in {"Bearer", "Token"}:
raise exceptions.AuthenticationFailed("Format invalide")

# Appel à l'API Clients
response = requests.get(
"http://apiclients:8000/api/auth/validate-token/",
headers={"Authorization": auth_header},
timeout=3
)

if response.status_code != 200:
raise exceptions.AuthenticationFailed("Token invalide")

data = response.json()
user = ExternalUser(
user_id=data['user_id'],
first_name=data['first_name'],
last_name=data['last_name'],
role=data['role']
)

return user, None






Ça me permet d'utiliser les permissions DRF normalement dans toutes les APIs.






API Catalogue : produits et avis



Gère tout ce qui touche aux produits.



Modèles principaux:




class Category(models.Model):
name = models.CharField(max_length=100, primary_key=True)
description = models.TextField()
enabled = models.BooleanField(default=True)

class Item(models.Model):
name = models.CharField(max_length=100)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
picture = models.ImageField(max_length=255)
stock = models.IntegerField(default=0)
average_rating = models.FloatField(default=0)
category_name = models.ForeignKey(Category, on_delete=models.CASCADE)
id_seller = models.IntegerField() # Référence vers l'API Clients

class Review(models.Model):
item = models.ForeignKey(Item, on_delete=models.CASCADE)
rating = models.FloatField()
comment = models.TextField()
id_client = models.IntegerField() # Référence vers l'API Clients






Le truc cool: Les avis mettent à jour automatiquement la note moyenne grâce aux signals Django:




# api/signals.py
from django.db.models import Avg
from django.db.models.signals import post_save, post_delete

@receiver(post_save, sender=Review)
def on_review_save(sender, instance, **kwargs):
agg = Review.objects.filter(item_id=instance.item_id).aggregate(avg=Avg('rating'))
Item.objects.filter(id=instance.item_id).update(
average_rating=round(agg['avg'] or 0.0, 2)
)

@receiver(post_delete, sender=Review)
def on_review_delete(sender, instance, **kwargs):
# Même chose pour la suppression









Gestion du stock



J'ai ajouté un endpoint spécial pour réduire le stock:




def reduce_stock(self, quantity):
if self.stock < quantity:
raise ValueError("Stock insuffisant")
self.stock -= quantity
self.save()






Cet endpoint est appelé par l'API Commandes quand une commande est validée.






API Panier : Flask + Redis



Contrairement aux autres, celle-ci est en Flask (plus léger pour un simple panier).



Stockage:




# Clé Redis: cart:<user_id>
# Valeur: JSON array d'IDs d'items

def get_cart_for_user(user_id):
cart_key = f"cart:{user_id}"
cart_data = redis_client.get(cart_key)
if cart_data:
return json.loads(cart_data)
return []

def save_cart_for_user(user_id, items):
cart_key = f"cart:{user_id}"
redis_client.set(cart_key, json.dumps(items))






Endpoints:




GET    /items          → Récupérer son panier
POST /items → Ajouter un item
PUT /items → Remplacer tout le panier
DELETE /items → Vider le panier
DELETE /items/<id> → Supprimer un item






Pourquoi Redis ? Parce que c'est temporaire. Si le serveur redémarre, on s'en fout de perdre les paniers.






API Commandes : l'orchestrateur



Celle-ci coordonne les autres services.



Workflow de création de commande:




def post(self, request):
# 1. Récupérer les infos des items depuis l'API Catalogue
for item_input in data['items']:
item_data = fetch_item_info(item_input['item_id'])

# 2. Vérifier et réduire le stock
stock_response = requests.post(
f"http://apicatalogue:8001/api/items/{item_id}/stock/",
json={'quantity': quantity}
)

if stock_response.status_code != 200:
return Response({'error': 'Stock insuffisant'}, 400)

# 3. Créer la commande
order = Order.objects.create(id_buyer=data['id_buyer'])

# 4. Sauvegarder les items (snapshot à l'instant T)
for item_info in items_info:
OrderItem.objects.create(
order=order,
item_id=item_info['item_id'],
name=item_info['name'], # Snapshot du nom
price=item_info['price'], # Snapshot du prix
id_seller=item_info['id_seller'],
quantity=item_info['quantity']
)






Pourquoi sauvegarder un snapshot ?



Parce que si le vendeur change le prix ou le nom du produit après, la commande doit refléter ce qui était affiché au moment de l'achat.






Génération de PDF



Bonus: chaque commande peut être exportée en PDF avec ReportLab:




from reportlab.platypus import SimpleDocTemplate, Table
from reportlab.lib.pagesizes import A4

def get(self, request, order_id):
order = Order.objects.get(id=order_id)

buffer = BytesIO()
doc = SimpleDocTemplate(buffer, pagesize=A4)

# Tableau des items
items_data = [['Article', 'Prix', 'Quantité', 'Total']]
for item in order.items.all():
items_data.append([
item.name,
f"{item.price}€",
str(item.quantity),
f"{item.price * item.quantity}€"
])

table = Table(items_data)
doc.build([table])

pdf_content = buffer.getvalue()
response = HttpResponse(pdf_content, content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="commande_{order.id}.pdf"'
return response









Les pièges de la communication inter-services






Erreur #1: Timeout par défaut trop court



Les requests Python ont un timeout par défaut infini. J'ai ajouté des timeouts partout:




response = requests.get(url, timeout=3)  # 3 secondes max









Erreur #2: Pas de gestion d'erreur



Si l'API Catalogue est down, l'API Commandes plantait. J'ai ajouté des try/catch:




try:
response = requests.get(url, timeout=3)
except requests.RequestException:
return Response({'error': 'Service indisponible'}, 502)









Erreur #3: Circular dependencies



Au début, l'API Catalogue appelait l'API Commandes qui appelait l'API Catalogue. Mauvaise idée.



Solution: Communication unidirectionnelle:




  • Frontend → APIs

  • API Commandes → API Catalogue (pour vérifier le stock)

  • API Catalogue ← Jamais d'appel sortant






Permissions et rôles



Chaque API a ses propres permissions:




# API Catalogue: seul le vendeur peut modifier ses items
class IsItemSeller(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
return request.user.id == obj.id_seller

# API Commandes: seul l'admin peut supprimer
class UserAdminPermission(permissions.BasePermission):
def has_permission(self, request, view):
return request.user.role == 'admin'









Déploiement Kubernetes



Chaque API a son deployment:




apiVersion: apps/v1
kind: Deployment
metadata:
name: apicatalogue
spec:
replicas: 1
template:
spec:
initContainers:
- name: wait-for-db
image: busybox:1.36.1
command: ['sh', '-c', 'until nc -z dbcatalogue 3307; do sleep 2; done;']
containers:
- image: ghcr.io/uha-sae53/api-catalogue:latest
ports:
- containerPort: 8001
env:
- name: DB_CATALOGUE_HOST
value: "dbcatalogue"






Le initContainer attend que la base soit prête avant de lancer l'API.






Conclusion



Cette archi microservices m'a appris:




  • La communication inter-services c'est chiant

  • Les timeouts sont ESSENTIELS

  • Un service = une responsabilité

  • Les snapshots de données évitent les incohérences



C'est plus complexe qu'un monolithe, mais ça scale mieux et c'est plus fun à développer.



Code complet: [GitHub]

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Mon architecture microservices e-commerce (et les erreurs à éviter)

Thematisch verwandte Begriffe: architecture, microservices, ecommerce, erreurs · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-18163 | IBM Financial Transaction Manager (FTM) for RedHat OpenShift could allow…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel • Rechts: nächster Artikel • unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger • Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick