TL;DR
Utilisez les Server-Sent Events (SSE) pour les mises à jour unidirectionnelles du serveur vers le client, comme les notifications et les flux en direct. Utilisez WebSocket pour la communication bidirectionnelle, comme le chat et les jeux. Le SSE est plus simple et fonctionne via HTTP. WebSocket est plus complexe mais prend en charge la messagerie bidirectionnelle. Le Modern PetstoreAPI implémente les deux pour différents cas d'utilisation en temps réel.
Introduction
Vous avez besoin de mises à jour en temps réel dans votre API. Le statut d'un animal passe de « disponible » à « adopté » — les clients doivent le savoir immédiatement. Utilisez-vous WebSocket ou Server-Sent Events (SSE) ?
La plupart des développeurs optent par défaut pour WebSocket parce qu'il est « plus puissant ». Mais le SSE est souvent le meilleur choix. Il est plus simple, fonctionne via HTTP standard et gère la reconnexion automatiquement. WebSocket ajoute une complexité dont vous n'avez peut-être pas besoin.
Modern PetstoreAPI implémente les deux protocoles. SSE pour les mises à jour de statut des animaux et les notifications de commande. WebSocket pour les enchères en direct et le chat en temps réel. Chaque protocole sert des cas d'utilisation différents.
Dans ce guide, vous apprendrez les différences entre SSE et WebSocket, verrez des exemples concrets tirés du Modern PetstoreAPI et découvrirez quand utiliser chaque protocole.
Qu'est-ce que les Server-Sent Events (SSE) ?
SSE est un protocole basé sur HTTP pour diffuser des événements du serveur au client.
Comment fonctionne le SSE
Le client ouvre une connexion et reçoit les événements au fur et à mesure qu'ils se produisent :
const eventSource = new EventSource('https://petstoreapi.com/v1/pets/notifications');
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Pet update:', data);
};
eventSource.addEventListener('adoption', (event) => {
const data = JSON.parse(event.data);
console.log('Pet adopted:', data.petId);
});
Le serveur envoie des événements :
GET /v1/pets/notifications
Accept: text/event-stream
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
event: adoption
data: {"petId":"019b4132","userId":"user-456"}
event: status-change
data: {"petId":"019b4127","status":"AVAILABLE"}
Fonctionnalités du SSE
1. Communication unidirectionnelle
Le serveur pousse les données vers le client. Le client ne peut pas renvoyer de messages via la connexion SSE (mais peut utiliser des requêtes HTTP régulières).
2. Basé sur HTTP
Utilise HTTP standard. Fonctionne à travers les proxies, les pare-feu et les CDN.
3. Reconnnexion automatique
Si la connexion est interrompue, le navigateur se reconnecte automatiquement.
4. ID d'événement pour la reprise
Le serveur peut envoyer des ID d'événement. Le client reprend à partir du dernier événement reçu :
id: 123
event: adoption
data: {"petId":"019b4132"}
id: 124
event: status-change
data: {"petId":"019b4127"}
En cas de déconnexion, le client envoie l'en-tête Last-Event-ID: 124 pour reprendre.
5. Protocole simple
Format textuel. Facile à déboguer avec curl :
curl -N -H "Accept: text/event-stream" \
https://petstoreapi.com/v1/pets/notifications
Limitations du SSE
1. Unidirectionnel seulement
Le client ne peut pas envoyer de messages via SSE. Des requêtes HTTP distinctes sont nécessaires pour la communication client-serveur.
2. Texte seulement
SSE envoie du texte. Les données binaires doivent être encodées en base64.
3. Limites de connexion du navigateur
Les navigateurs limitent les connexions SSE par domaine (généralement 6). Ce n'est pas un problème pour la plupart des applications.
4. Pas de compression intégrée
La compression HTTP fonctionne, mais il n'y a pas de compression au niveau du protocole comme avec WebSocket.
Qu'est-ce que WebSocket ?
WebSocket est un protocole bidirectionnel full-duplex via une connexion persistante.
Comment fonctionne WebSocket
Le client et le serveur peuvent tous deux envoyer des messages à tout moment :
const ws = new WebSocket('wss://petstoreapi.com/auctions/019b4132');
// Send message to server
ws.send(JSON.stringify({
type: 'bid',
amount: 500
}));
// Receive messages from server
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('Auction update:', data);
};
ws.onclose = () => {
console.log('Connection closed');
// Manual reconnection logic needed
};
Le serveur peut envoyer à tout moment :
{"type":"bid","userId":"user-456","amount":550}
{"type":"outbid","newAmount":550}
Le client peut envoyer à tout moment :
{"type":"bid","amount":600}
{"type":"watch","petId":"019b4132"}
Fonctionnalités de WebSocket
1. Bidirectionnel
Le client et le serveur peuvent tous deux envoyer des messages à tout moment. Véritable communication bidirectionnelle.
2. Faible latence
Connexion persistante. Pas de surcoût HTTP par message. Idéal pour les jeux, le chat, la collaboration en direct.
3. Support binaire
Peut envoyer des données binaires directement. Pas besoin d'encodage base64.
4. Protocole personnalisé
Utilise ws:// ou wss:// (sécurisé). N'est plus HTTP après la poignée de main initiale.
5. Basé sur des trames
Les messages sont encadrés (tramés). Peut envoyer des messages partiels et les réassembler.
Limitations de WebSocket
1. Configuration complexe
Nécessite un serveur WebSocket. Plus complexe que les points de terminaison HTTP.
2. Reconnnexion manuelle
Pas de reconnexion automatique. Vous devez implémenter la logique de réessai.
3. Problèmes de proxy
Certains proxies d'entreprise bloquent WebSocket. Les proxies HTTP ne comprennent pas ws://.
4. Avec état (Stateful)
Le serveur doit suivre les connexions. Plus difficile à adapter que HTTP sans état (stateless).
5. Pas de fonctionnalités HTTP
Impossible d'utiliser la mise en cache HTTP, les codes d'état ou les en-têtes standard après la poignée de main.
Comparaison côte à côte
| Caractéristique | SSE | WebSocket |
|---|---|---|
| Direction | Serveur → Client | Bidirectionnel |
| Protocole | HTTP | Personnalisé (ws://) |
| Reconnexion | Automatique | Manuelle |
| Support Navigateur | Tous modernes | Tous modernes |
| Compatible Proxy | Oui | Parfois |
| Complexité | Simple | Complexe |
| Données Binaires | Non (texte seulement) | Oui |
| Latence | Faible | Très faible |
| Scalabilité | Élevée (sans état) | Moyenne (avec état) |
| Cas d'utilisation | Notifications, flux | Chat, jeux, collaboration |
Comment Modern PetstoreAPI utilise les deux
Modern PetstoreAPI implémente à la fois SSE et WebSocket pour différents scénarios.
SSE pour les mises à jour des animaux
Point de terminaison : GET /v1/pets/notifications
const events = new EventSource(
'https://petstoreapi.com/v1/pets/notifications?userId=user-456'
);
events.addEventListener('adoption', (e) => {
const data = JSON.parse(e.data);
showNotification(`${data.petName} was adopted!`);
});
events.addEventListener('status-change', (e) => {
const data = JSON.parse(e.data);
updatePetStatus(data.petId, data.status);
});
Implémentation côté serveur :
app.get('/v1/pets/notifications', (req, res) => {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const userId = req.query.userId;
// Subscribe to pet updates
const subscription = petUpdates.subscribe(userId, (event) => {
res.write(`event: ${event.type}\n`);
res.write(`data: ${JSON.stringify(event.data)}\n\n`);
});
req.on('close', () => {
subscription.unsubscribe();
});
});
Cas d'utilisation :
- Changements de statut d'animal (disponible → adopté)
- Notifications de commande (passée, expédiée, livrée)
- Mises à jour d'inventaire
- Changements de prix
WebSocket pour les enchères en direct
Point de terminaison : wss://petstoreapi.com/auctions/{auctionId}
const ws = new WebSocket('wss://petstoreapi.com/auctions/019b4132');
// Place bid
function placeBid(amount) {
ws.send(JSON.stringify({
type: 'bid',
amount
}));
}
// Receive updates
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
switch (msg.type) {
case 'bid':
updateCurrentBid(msg.amount, msg.userId);
break;
case 'outbid':
showOutbidNotification(msg.newAmount);
break;
case 'auction-end':
showAuctionResult(msg.winner);
break;
}
};
Implémentation côté serveur :
wss.on('connection', (ws, req) => {
const auctionId = req.params.auctionId;
const auction = auctions.get(auctionId);
ws.on('message', (data) => {
const msg = JSON.parse(data);
if (msg.type === 'bid') {
const result = auction.placeBid(msg.userId, msg.amount);
// Broadcast to all participants
auction.participants.forEach(participant => {
participant.send(JSON.stringify({
type: 'bid',
userId: msg.userId,
amount: msg.amount
}));
});
}
});
});
Cas d'utilisation :
- Enchères en direct
- Chat en temps réel avec support
- Planification collaborative des soins pour animaux
- Mises à jour d'inventaire en direct pendant les ventes
Tester les API en temps réel avec Apidog
Apidog prend en charge le test des API SSE et WebSocket.
Tester les SSE
1. Créer une requête SSE :
GET https://petstoreapi.com/v1/pets/notifications
Accept: text/event-stream
2. Valider les événements :
- Vérifier les types d'événements
- Valider les charges utiles JSON
- Tester le comportement de reconnexion
- Vérifier les ID d'événements
3. Scénarios de test :
- Déconnexions
- Redémarrages de serveur
- Ordre des événements
- Reprise à partir du dernier événement
Tester les WebSocket
1. Créer une connexion WebSocket :
wss://petstoreapi.com/auctions/019b4132
2. Envoyer des messages de test :
{"type":"bid","amount":500}
{"type":"watch","petId":"019b4132"}
3. Valider les réponses :
- Vérifier les formats de message
- Tester le flux bidirectionnel
- Vérifier la gestion des connexions
- Tester les scénarios d'erreur
4. Scénarios de test :
- Multiples connexions concurrentes
- Ordre des messages
- Délais d'expiration de connexion
- Logique de reconnexion
Quand utiliser chaque protocole
Utiliser SSE quand :
- Mises à jour unidirectionnelles - Le serveur pousse les données vers le client, le client n'a pas besoin de renvoyer de messages
- Configuration simple - Vous souhaitez utiliser l'infrastructure HTTP standard
- Reconnexion automatique - Vous ne voulez pas implémenter de logique de réessai
- Compatible avec les proxys - Besoin de fonctionner à travers les pare-feu d'entreprise
- Notifications - Mises à jour de statut, alertes, flux en direct
Exemples :
- Notifications d'adoption d'animaux
- Mises à jour du statut des commandes
- Changements d'inventaire
- Alertes de prix
- Flux d'actualités
Utiliser WebSocket quand :
- Bidirectionnel - Le client et le serveur envoient des messages fréquemment
- Faible latence critique - Jeux, collaboration en temps réel
- Données binaires - Envoi d'images, d'audio, de vidéo
- Protocole personnalisé - Besoin d'un contrôle total sur le format des messages
- Haute fréquence de messages - Des centaines de messages par seconde
Exemples :
- Enchères en direct
- Chat en temps réel
- Jeux multijoueurs
- Édition collaborative
- Diffusion vidéo en direct
N'utilisez pas WebSocket juste parce que :
❌ « C'est plus avancé » - Complexité sans avantage
❌ « Tout le monde l'utilise » - SSE est souvent plus simple
❌ « C'est plus rapide » - SSE est suffisamment rapide pour la plupart des cas d'utilisation
❌ « C'est bidirectionnel » - Avez-vous réellement besoin de bidirectionnel ?
Conclusion
SSE et WebSocket permettent tous deux la communication en temps réel, mais ils sont conçus pour des scénarios différents. SSE excelle dans les mises à jour unidirectionnelles du serveur vers le client avec reconnexion automatique et compatibilité HTTP. WebSocket brille pour la communication bidirectionnelle à faible latence.
Modern PetstoreAPI montre comment utiliser efficacement les deux protocoles. SSE pour les notifications et les mises à jour de statut. WebSocket pour les enchères en direct et le chat. Choisissez en fonction de votre cas d'utilisation, et non en fonction du protocole qui semble « meilleur ».
Testez vos API en temps réel avec Apidog pour vous assurer que les implémentations SSE et WebSocket fonctionnent correctement dans différents scénarios.
FAQ
Le SSE peut-il fonctionner à travers les pare-feu d'entreprise ?
Oui. SSE utilise HTTP standard, il fonctionne donc à travers les proxys HTTP et les pare-feu. WebSocket utilise un protocole personnalisé que certains proxys bloquent.
WebSocket est-il plus rapide que SSE ?
WebSocket a une latence légèrement inférieure (pas de surcoût HTTP par message), mais pour la plupart des applications, la différence est négligeable. SSE est suffisamment rapide pour les notifications, les flux et les mises à jour de statut.
Comment gérer la reconnexion SSE ?
Le navigateur gère la reconnexion automatiquement. Envoyez des ID d'événements depuis le serveur, et le client reprendra à partir du dernier événement reçu en utilisant l'en-tête Last-Event-ID.
Peut-on utiliser SSE avec des applications mobiles ?
Oui. iOS et Android prennent en charge SSE via des clients HTTP natifs ou des bibliothèques. SSE fonctionne partout où HTTP fonctionne.
Quel est le temps de connexion maximum pour SSE ?
Il n'y a pas de limite stricte. Les connexions SSE peuvent rester ouvertes indéfiniment. Certains proxys ou équilibreurs de charge peuvent avoir des délais d'attente (généralement 30-60 secondes), mais le navigateur se reconnectera automatiquement.
WebSocket peut-il envoyer des données binaires ?
Oui. WebSocket prend en charge les trames texte et binaires. Vous pouvez envoyer des images, de l'audio ou toute donnée binaire sans encodage base64.
Combien de connexions SSE un navigateur peut-il avoir ?
Les navigateurs limitent les connexions SSE par domaine (généralement 6). C'est rarement un problème — la plupart des applications n'ont besoin que d'une ou deux connexions SSE.
Faut-il un serveur spécial pour SSE ?
Non. N'importe quel serveur HTTP peut gérer SSE. Il suffit de définir les en-têtes corrects (Content-Type: text/event-stream) et de maintenir la connexion ouverte.
