Introduction : REST est mort ? Non, un choix est simplement apparu
\n\nChaque développeur Java a écrit une API REST au moins une fois. C'est pratique, familier, et le JSON se lit à l'œil. Mais lorsque la charge augmente et que les latences deviennent critiques, REST commence à grincer. Et c'est là qu'entre en scène gRPC — une technologie de Google qui promet une vitesse comparable à un appel local, une vitesse de sérialisation 10 fois supérieure au JSON et un support intégré du streaming.
\n\nDans cet article, nous allons déterminer quand gRPC en Java est vraiment justifié et quand il vaut mieux rester sur REST. Pas de blabla — uniquement des scénarios réels, des exemples de code et des benchmarks honnêtes.
\n\nQu'est-ce que gRPC et pourquoi en parle-t-on ?
\n\ngRPC est un framework d'appel de procédure distante (RPC). Au lieu de JSON, il utilise Protocol Buffers (protobuf) — un format de sérialisation binaire. Au lieu de HTTP/1.1 — HTTP/2 avec multiplexage et compression des en-têtes.
\n\nPour Java, cela signifie :
\n- \n
- Typage strict des contrats via des fichiers
.proto\n - Génération automatique des clients et des serveurs \n
- Quatre types d'interaction : unary, server streaming, client streaming, bidirectional streaming \n
- Support intégré des timeouts, des deadlines et de l'équilibrage de charge \n
À quoi ressemble un fichier .proto typique ?
\n\nsyntax = "proto3";\n\npackage com.pythonlib.example;\n\nservice UserService {\n rpc GetUser (UserRequest) returns (UserResponse);\n rpc ListUsers (UserListRequest) returns (stream UserResponse);\n rpc UpdateUser (stream UserUpdateRequest) returns (UserResponse);\n rpc Chat (stream ChatMessage) returns (stream ChatMessage);\n}\n\nmessage UserRequest {\n int32 id = 1;\n}\n\nmessage UserResponse {\n int32 id = 1;\n string name = 2;\n string email = 3;\n}\n\nmessage UserListRequest {\n int32 page = 1;\n int32 size = 2;\n}\n\nmessage UserUpdateRequest {\n int32 id = 1;\n string name = 2;\n}\n\nmessage ChatMessage {\n string user = 1;\n string text = 2;\n}\n\n\nAprès compilation avec protoc, vous obtenez une classe Java prête à l'emploi avec des builders — pas de mappeurs manuels.
Quand gRPC en Java est-il le meilleur choix ? 5 scénarios
\n\n1. Microservices à forte charge
\n\nSi vous avez 50+ microservices qui communiquent entre eux des milliers de fois par seconde, gRPC réduit la latence de 30 à 50 % par rapport à REST. Protobuf prend moins de place, HTTP/2 permet de maintenir une seule connexion pour toutes les requêtes.
\n\nExemple pratique : nous avons migré un service interne de recommandations de REST vers gRPC. Le temps de réponse est passé de 12 ms à 4 ms, et le trafic a été réduit de 3 fois.
\n\n2. Streaming de données en temps réel
\n\ngRPC prend en charge nativement le server-side streaming, le client-side streaming et le bidirectional streaming. C'est idéal pour :
\n- \n
- Les logs et métriques (l'agent envoie un flux de données) \n
- Les systèmes de chat et notifications \n
- Le traitement de gros fichiers par morceaux \n
Implémentation d'un serveur avec server streaming en Java :
\n\nimport io.grpc.stub.StreamObserver;\n\npublic class UserServiceImpl extends UserServiceGrpc.UserServiceImplBase {\n\n @Override\n public void listUsers(UserListRequest request,\n StreamObserver<UserResponse> responseObserver) {\n for (int i = 0; i < 10; i++) {\n UserResponse user = UserResponse.newBuilder()\n .setId(i)\n .setName("User_" + i)\n .setEmail("user" + i + "@pythonlib.ru")\n .build();\n responseObserver.onNext(user);\n try {\n Thread.sleep(200); // simulation de latence\n } catch (InterruptedException e) {\n responseObserver.onError(e);\n }\n }\