Si vous avez déjà essayé d'appeler un service gRPC depuis un navigateur, vous connaissez déjà les difficultés. Les navigateurs ne peuvent pas communiquer directement en gRPC brut car ils ne peuvent pas contrôler les *trailers* HTTP. Vous finissez donc par ajouter un proxy comme Envoy juste pour traduire le trafic. ConnectRPC supprime cette étape. Il vous permet de construire des API basées sur Protobuf qu'un navigateur peut appeler directement, qui répondent à une simple commande curl, et qui sont toujours interopérables avec l'écosystème gRPC plus large.
Ce guide explique ce qu'est ConnectRPC, le problème que le protocole Connect résout, comment Connect se compare à gRPC, gRPC-Web et REST, et à quoi ressemble une requête Connect sur HTTP. Vous verrez également comment tester et déboguer des points de terminaison Connect et gRPC avec un client API standard.
Qu'est-ce que ConnectRPC
ConnectRPC est une famille de bibliothèques permettant de construire des API HTTP compatibles avec les navigateurs et gRPC à partir de Protocol Buffers. Vous définissez votre service dans un fichier .proto, générez du code et implémentez vos gestionnaires (*handlers*). Connect s'occupe du routage, de la sérialisation, de la compression et de la génération de clients.
Le projet a été créé par Buf, l'entreprise à l'origine des outils de compilation buf pour Protobuf, et est maintenant un projet *sandbox* de la Cloud Native Computing Foundation (CNCF). Cette origine est importante : Connect est conçu pour s'intégrer au même flux de travail "schema-first" que les équipes utilisent déjà avec buf et Protobuf.
Un serveur ConnectRPC prend en charge trois protocoles à la fois :
- gRPC : compatibilité totale, y compris le streaming et les *trailers*.
- gRPC-Web : prise en charge directe, sans nécessiter de proxy séparé.
- Connect : son propre protocole basé sur HTTP, optimisé pour le web.
Parce qu'un seul serveur gère les trois protocoles, un client gRPC peut appeler un serveur Connect, et un client Connect peut appeler n'importe quel serveur gRPC. Vous choisissez le protocole par client, souvent avec un simple changement de configuration et sans réécriture de code.
Le problème résolu par Connect
gRPC est rapide et fortement typé, mais il repose sur des hypothèses que le web ne respecte pas. Il s'appuie sur HTTP/2 et sur les *trailers* HTTP pour transporter les informations de statut. Les navigateurs n'exposent pas les *trailers* à JavaScript, donc un navigateur ne peut pas agir comme un client gRPC natif. La solution habituelle est gRPC-Web plus un proxy de traduction tel qu'Envoy, qui se place entre le navigateur et votre backend gRPC.
Cela fonctionne, mais cela ajoute des éléments mobiles. Vous devez maintenant exécuter et configurer un proxy, et déboguer un saut supplémentaire. Pour les équipes qui souhaitent des API typées et un accès via le navigateur sans cette surcharge, la configuration semble plus lourde qu'elle ne devrait l'être.
Connect emprunte une voie différente. Son propre protocole fonctionne sur HTTP standard, de sorte qu'un navigateur peut l'appeler directement et vous n'avez pas besoin de proxy pour le trafic navigateur. Si vous devez également servir des clients gRPC existants, le même serveur Connect les gère également. Vous obtenez un seul backend qui répond aussi bien aux navigateurs, aux outils en ligne de commande et aux services gRPC.
Connect vs gRPC vs gRPC-Web vs REST
Ces quatre approches se chevauchent, il est donc utile de les comparer.
gRPC utilise Protobuf sur HTTP/2 avec un *framing* binaire et des *trailers*. Il est efficace et prend en charge les quatre modes de streaming, mais il est difficile de l'appeler depuis un navigateur ou avec un shell. Si vous souhaitez un rappel sur la couche de transport, consultez comment gRPC et HTTP/2 fonctionnent ensemble.
gRPC-Web est une variante de gRPC conviviale pour les navigateurs. Il reste centré sur Protobuf et nécessite généralement un proxy pour se connecter à un véritable backend gRPC. Notre guide sur ce qu'est gRPC-Web explique sa place.
Connect conserve le schéma Protobuf et le modèle de méthode de style gRPC, mais son protocole fonctionne proprement sur HTTP/1.1, HTTP/2 et HTTP/3. Les appels unaires (*unary calls*) transportent un corps JSON ou Protobuf simple sans *framing* binaire gRPC, et les réponses utilisent de vrais codes de statut HTTP. Cette combinaison rend un appel Connect aussi accessible que n'importe quel appel REST.
REST est orienté ressources et son schéma est facultatif (*schema-optional*). C'est le style le plus universellement pris en charge, mais il lui manque la génération de code et le typage strict que Protobuf vous offre. Si vous évaluez les compromis, gRPC vs REST décompose les différences.
En bref : Connect vise à vous offrir le typage et les outils de gRPC avec la portée et la capacité de débogage de REST. Il s'appuie sur Protobuf et le modèle de méthode de gRPC tout en supprimant les éléments que les navigateurs et les shells ne peuvent pas gérer.
Une requête Connect sur HTTP
Voici ce qui rend Connect accessible. Un appel unaire Connect est une requête HTTP POST ordinaire. Le chemin de l'URL provient directement de votre schéma Protobuf, et le corps est du JSON ou du Protobuf binaire sans *framing* supplémentaire.
Le format du chemin est /<package>.<Service>/<Method>. Ainsi, une méthode Greet sur un GreetService dans le package greet.v1 se trouve à /greet.v1.GreetService/Greet.
Vous pouvez l'appeler avec curl :
curl \
--header "Content-Type: application/json" \
--data '{"name": "Jane"}' \
http://localhost:8080/greet.v1.GreetService/Greet
La réponse est du JSON simple :
{"greeting": "Hello, Jane!"}
Pas de client personnalisé, pas de proxy, pas de décodage binaire. C'est toute la requête. Parce que le corps est du JSON réel et que le statut est un vrai code de statut HTTP, chaque outil qui parle HTTP peut inspecter l'appel. C'est la propriété qui sépare le protocole Connect du gRPC brut, où la même requête serait enveloppée dans un *framing* binaire et porterait son statut dans un *trailer*.
Connect prend en charge deux types de contenu pour les requêtes unaires :
application/jsonpour les charges utiles (*payloads*) JSON lisibles par l'homme.application/protopour le Protobuf binaire compact.
Vous envoyez du Protobuf binaire lorsque vous souhaitez une taille de transmission plus petite et du JSON lorsque vous souhaitez une meilleure lisibilité pendant le développement. Pour envoyer du binaire, changez l'en-tête et passez un corps encodé :
curl \
--header "Content-Type: application/proto" \
--data-binary @request.bin \
http://localhost:8080/greet.v1.GreetService/Greet
Les appels de streaming utilisent un type de contenu différent (application/connect+proto ou application/connect+json) et encapsulent chaque message dans une enveloppe : un octet de drapeaux, une longueur de quatre octets en *big-endian*, puis le message. Les appels unaires (*unary calls*) ignorent entièrement cette enveloppe, c'est pourquoi ils se mappent si clairement sur une requête HTTP normale. Si vous choisissez entre les formats filaires pour vos charges utiles (*payloads*), Protobuf vs JSON couvre les compromis de taille et de lisibilité.
Support linguistique et outils buf
ConnectRPC propose des implémentations dans plusieurs langages. Go et TypeScript (pour le navigateur et Node.js) sont les implémentations stables et prêtes pour la production. Swift est disponible pour les plateformes Apple, Kotlin pour la JVM et Android, et Python est en version bêta. Cette diversité vous permet de partager un seul contrat Protobuf entre un backend Go et un frontend TypeScript sans écrire manuellement les clients.
La génération de code s'effectue via la chaîne d'outils buf. Vous décrivez votre service dans un fichier .proto, puis utilisez les plugins buf pour générer des messages et des gestionnaires (*handlers*) Connect. Un projet Go utilise deux plugins : protoc-gen-go pour les messages Protobuf et protoc-gen-connect-go pour les gestionnaires et clients Connect.
Les plugins sont listés dans un fichier buf.gen.yaml, et vous exécutez la génération avec une seule commande :
buf generate
Cela produit des structures de messages typées ainsi que le code serveur et client pour votre service. À partir de là, vous implémentez les méthodes du gestionnaire (*handler*) et les enregistrez sur un serveur HTTP. Étant donné que le code généré cible la bibliothèque standard net/http en Go, vous n'avez pas besoin d'un runtime de serveur séparé ; un gestionnaire Connect est un gestionnaire HTTP normal que vous pouvez monter à côté de vos routes existantes.
Test et débogage des points de terminaison Connect et gRPC
Étant donné que les appels unaires Connect sont de simples requêtes HTTP avec un corps JSON, vous pouvez les tester de la même manière que vous testeriez n'importe quel point de terminaison REST. C'est un avantage pratique : aucun client spécial n'est requis pour "sonder" votre service pendant le développement.
Dans Apidog, vous envoyez une requête unaire Connect comme une requête HTTP. Définissez la méthode sur POST, utilisez l'URL dérivée du schéma comme http://localhost:8080/greet.v1.GreetService/Greet, ajoutez l'en-tête Content-Type: application/json, et placez votre message dans le corps JSON :
{"name": "Jane"}
Vous recevez en retour la réponse JSON et un véritable code de statut HTTP, que vous pouvez affirmer directement. Apidog n'est pas un client Connect dédié, mais il n'a pas besoin de l'être ; vous utilisez la surface HTTP que le protocole Connect expose, exactement comme le fait curl, avec une interface utilisateur, des requêtes sauvegardées et un historique en prime. Pour une introduction rapide aux verbes impliqués, consultez ce que sont les méthodes HTTP.
Parce qu'un serveur Connect parle aussi gRPC, le côté gRPC de votre service est également testable. Apidog prend en charge les points de terminaison gRPC, vous pouvez donc importer le même fichier .proto, parcourir les méthodes de service et les appeler avec une requête typée. Cela signifie qu'un seul outil couvre les deux aspects du serveur : le protocole Connect convivial avec HTTP et le protocole gRPC natif. Si gRPC est votre principale préoccupation, comment tester efficacement les API gRPC détaille le flux de travail.
Une fois que vos requêtes fonctionnent comme prévu, vous pouvez les intégrer dans des vérifications automatisées. Enregistrez vos appels Connect et gRPC comme scénarios de test, puis exécutez-les en CI avec l'Apidog CLI. Installez-le avec Node :
npm install -g apidog-cli
Ensuite, exécutez un scénario ou une suite enregistrée, en désignant un environnement et en choisissant les formats de rapport :
apidog run \
--access-token "$APIDOG_ACCESS_TOKEN" \
-t <scenarioOrSuiteId> \
-e <environmentId> \
-r cli,html,junit
Le CLI est *headless* (sans interface graphique), il peut donc être intégré à n'importe quelle étape de CI capable d'exécuter Node. Il exécute des scénarios et des suites de tests enregistrés plutôt que d'envoyer des requêtes ad hoc, ce qui le rend adapté aux vérifications de régression sur vos points de terminaison Connect et gRPC. Pour un aperçu complet, consultez le tutoriel Apidog CLI pour tester une API en ligne de commande.
Foire Aux Questions
ConnectRPC est-il la même chose que gRPC ? Non. ConnectRPC est un framework qui implémente trois protocoles : gRPC, gRPC-Web et son propre protocole Connect. Un serveur Connect interopère avec les clients et serveurs gRPC, il s'intègre donc à l'écosystème gRPC, mais le protocole Connect lui-même est une conception séparée basée sur HTTP que les navigateurs et les shells peuvent appeler directement.
Ai-je toujours besoin d'un proxy comme Envoy pour atteindre un navigateur ? Pas pour le protocole Connect. Connect fonctionne sur HTTP standard, donc un navigateur peut appeler un serveur Connect sans proxy de traduction. Vous n'utiliseriez un proxy tel qu'Envoy que si vous avez besoin de faire le pont entre le trafic du navigateur et un backend qui ne parle que du gRPC natif.
Quels langages ConnectRPC prend-il en charge ? Go et TypeScript (navigateur et Node.js) sont les implémentations stables et prêtes pour la production. Swift, Kotlin et Python sont également disponibles, Python étant en version bêta. Toutes sont générées à partir du même schéma Protobuf.
Quelle est la relation entre Connect et buf ? ConnectRPC a été créé par Buf et utilise la chaîne d'outils buf pour la génération de code. Vous exécutez buf generate avec des plugins comme protoc-gen-connect-go pour produire des gestionnaires (*handlers*) et des clients à partir de vos fichiers .proto.
Puis-je tester un point de terminaison Connect avec un client API normal ? Oui. Les appels unaires Connect sont des requêtes HTTP POST avec un corps JSON ou Protobuf et un vrai code de statut HTTP. Tout client HTTP, y compris curl et Apidog, peut en envoyer un. Apidog peut également appeler le côté gRPC du même serveur en important le fichier .proto.
