Transport wire Décidé
HTTP/2 + CBOR sur le port 443, TLS hybride post-quantique — le colis postal standard, parce qu'on ne contrôle pas les routes. gRPC écarté (deuxième langue de sérialisation, fragile en réseau hostile), HTTP/3 noté comme upgrade opportuniste, TCP maison disqualifié.
La décision
HTTP/2 + CBOR. Des endpoints HTTPS ordinaires (PUT /v1/chunks/{addr}, POST /v1/chunks/exists), les structures en CBOR, les chunks en octets bruts, le multiplexage H2 pour les flux parallèles.
- Indistinguable du trafic web normal sur 443 — proxies d'entreprise, DPI, hôtels : tout passe, parce que c'est du HTTPS ordinaire. Pour un produit installé chez des PME qu'on ne contrôle pas, l'argument n°1.
- Dégradation gracieuse — un boîtier qui force HTTP/1.1 ne casse rien : le protocole reste correct, juste moins multiplexé. gRPC, lui, casse net.
- Une seule langue de sérialisation — CBOR partout : les nœuds, les requêtes, les réponses. Les chunks voyagent nus, zéro enveloppe.
- Débuggable au curl, codes de statut standards, compatible avec chaque reverse-proxy / LB / WAF de la planète.
- Le « contrat généré » de gRPC, on l'a autrement — client et serveur vivent dans le même workspace Rust : une crate de types partagés fait le même travail, sans générateur ni deuxième schéma.
- TLS hybride post-quantique obligatoire — X25519 + ML-KEM-768 (exigence gravée).
- Versionnage par préfixe
/v1/+ un endpoint de capacités (le serveur annonce : taille max de batch, features, transports) — les vieux clients continuent de marcher.
HTTP/3 : upgrade opportuniste, pas fondation. Ses gains visent exactement notre charge (pas de head-of-line blocking sur liens avec pertes, migration de connexion wifi→4G en plein backup) — mais l’UDP est bloqué dans assez de réseaux d’entreprise pour que le fallback H2 soit obligatoire de toute façon. Deux transports = double matrice de tests : on l’ajoutera derrière l’endpoint de capacités le jour où le gain le justifie.
C’est quoi, CBOR — et pourquoi lui
{"taille": 512} fait 15 caractères en JSON, ~8 octets en CBOR. C'est une norme IETF (RFC 8949) — c'est par exemple le format interne des passkeys/WebAuthn. Deux atouts décisifs : les octets bruts sont natifs (nos adresses et clés de 32 o voyagent telles quelles — JSON les gonflerait de +33 % en base64), et surtout le mode canonique est défini par la norme (clés triées, encodages minimaux) — la raison de son choix initial : chez nous adresse = hash(octets), le même contenu doit produire les mêmes octets partout, pour toujours. Protobuf est explicitement non-déterministe, MessagePack n'a pas de profil canonique normalisé : CBOR avait le déterminisme déjà spécifié. Le réutiliser pour l'API = une seule langue dans tout le produit.
Et par rapport à un protocole TCP maison ?
Performance : l'overhead HTTP/2 sur un chunk de 2 Mio ≈ 0,01 % (9 octets de frame + headers compressés HPACK). Les goulots réels sont des ordres de grandeur au-dessus : le WAN, le disque, le fsync, le CPU de chunking. Le mythe « custom = rapide » vient des domaines à millions de minuscules messages (trading, jeu) — pas du transfert de gros blobs, où le framing s'amortit. Et H2 fait même gagner : une connexion multiplexée au lieu d'une par flux (handshakes TLS économisés). Un TCP maison, c'est payer l'enfer des réseaux d'entreprise pour un 1 % qu'on ne verra jamais.
gRPC — pourquoi pas, en détail
- Une deuxième langue de sérialisation — protobuf en plus de notre CBOR canonique : deux schémas, deux toolchains, pour toujours. Le contre le plus lourd.
- Fragile en réseau hostile — exige HTTP/2 de bout en bout, trailers compris ; proxies et boîtiers d'inspection les cassent régulièrement → tickets de support indéboguables à distance.
- Pas fait pour les gros colis — optimisé pour beaucoup de petits messages, pas des blobs de 8 Mio (limites de message, fragmentation à gérer soi-même).
- Outillage dédié requis (grpcurl, reflection), grpc-web pour le navigateur, bizarreries de load-balancing.
L’écosystème Rust
| Rôle | Crate | Note |
|---|---|---|
| Runtime async | tokio | Le standard de facto |
| HTTP/2 serveur | axum (sur hyper + tower) | Middlewares tower : timeouts, rate-limit, retry |
| HTTP/2 client | reqwest (ou hyper direct) | Pooling, multiplexage H2 |
| TLS | rustls + provider aws-lc-rs | X25519MLKEM768 (hybride PQ) disponible |
| CBOR | minicbor | Déjà choisi pour les nœuds — encodeur canonique partagé |
| HTTP/3 (futur) | quinn + h3 | Pour l’upgrade opportuniste, le jour venu |
La stack tokio/hyper/axum/rustls est la plus éprouvée de l’écosystème Rust — c’est celle qui fait tourner une part significative de l’infrastructure web moderne.