gRPC en Kotlin : quand l'utiliser pour ne pas le regretter
Imaginez : vous écrivez des microservices en Kotlin, tout fonctionne, mais les requêtes entre eux deviennent lentes. L'API REST que vous aimiez tant commence à vous agacer — trop de sérialisation, trop de surcharge HTTP. Vous commencez à chercher "moyen rapide de communication entre microservices" et tombez sur gRPC. Et immédiatement, la question se pose : "N'est-ce pas excessif ? Ne vaut-il pas mieux laisser les choses comme elles sont ?"
Allons-y. gRPC en Kotlin n'est pas simplement "un protocole de plus". C'est une approche complètement différente de l'interaction entre services. C'est plus rapide, plus strict et plus puissant que REST, mais aussi plus complexe. Dans cet article, je vais vous dire quand gRPC est votre meilleur ami, et quand il vaut mieux s'en tenir au bon vieux REST. Et, bien sûr, je montrerai du code réel en Kotlin.
Qu'est-ce que gRPC et pourquoi est-il si populaire dans le monde Kotlin ?
gRPC est un framework d'appel de procédure distante (RPC) de Google. Il utilise Protocol Buffers (protobuf) pour la sérialisation des données et HTTP/2 pour le transport. Si REST, c'est comme envoyer des lettres par la poste (chaque requête est une lettre séparée), alors gRPC, c'est comme une conversation téléphonique directe : rapide, bidirectionnelle et avec des latences minimales.
Pour les développeurs Kotlin, gRPC est particulièrement intéressant car :
- Les coroutines Kotlin s'accordent parfaitement avec les flux asynchrones de gRPC.
- Le typage strict de protobuf — moins d'erreurs au moment de l'exécution.
- La prise en charge du streaming bidirectionnel — idéal pour les chats, les jeux et les applications en temps réel.
Mais soyons honnêtes : gRPC n'est pas nécessaire partout. Et maintenant, je vais vous montrer comment comprendre s'il est nécessaire pour votre projet.
Quand utiliser gRPC en Kotlin : 5 scénarios en béton
1. Microservices avec des exigences de performance élevées
Si vos microservices communiquent avec des dizaines de milliers de requêtes par seconde, gRPC surpasse REST de 2 à 5 fois en vitesse. Tout cela grâce au format binaire de protobuf et au multiplexage de HTTP/2.
Exemple : vous avez un service de recommandations en Kotlin qui doit renvoyer un contenu personnalisé en quelques millisecondes. REST avec JSON serait "trop lourd" — chaque requête contient des noms de champs, des parenthèses et autres déchets textuels. Protobuf ne transmet que des nombres et des chaînes sans enveloppe superflue.
// Définition dans le fichier .protoservice Recommender { rpc GetRecommendations (UserRequest) returns (RecommendationsResponse);}
message UserRequest { string user_id = 1; int32 max_results = 2;}
message RecommendationsResponse { repeated Item items = 1;}Le code côté client Kotlin sera concis :
val stub = RecommenderGrpc.newBlockingStub(channel)val request = UserRequest.newBuilder() .setUserId("user_123") .setMaxResults(10) .build()
val response = stub.getRecommendations(request)println("Reçu ${response.itemsCount} recommandations")2. Streaming de données en temps réel
gRPC prend en charge quatre types de streaming : serveur, client, bidirectionnel et unary simple. En Kotlin, c'est particulièrement pratique avec les coroutines — vous pouvez diffuser des données sous forme de Flow.
Exemple : un serveur de logs qui envoie de nouvelles entrées au client en temps réel.
// Partie serveur en Kotlinclass LogServiceImpl : LogServiceGrpcKt.LogServiceCoroutineImplBase() { override fun streamLogs(request: LogRequest): Flow<LogEntry> = flow { val logSource = getLogSource(request.logType) logSource.collect { logEntry -> emit(logEntry) } }}
// Partie clientval stub = LogServiceGrpcKt.LogServiceCoroutineStub(channel)stub.streamLogs(LogRequest.newBuilder().setLogType("error").build()) .collect { log -> println("Nouveau log : ${log.message}") }Essayez de faire la même chose avec REST et WebSocket — ce sera lourd et lent.