← Back to projects

gRPC Microservices Stack

Distributed system with a gRPC server, Java client, and Angular UI — demonstrating high-performance RPC across services.

gRPCJavaAngularProtocol BuffersMicroservicesCloudflare

Overview

A multi-repo microservices demonstration using gRPC for efficient binary communication between a Java server, Java client, and Angular frontend. gRPC and Protocol Buffers offer lower-latency, strongly typed service contracts compared to JSON REST — a good fit for service-to-service calls.

I built this mainly to showcase the different communication modes gRPC supports — unary, server streaming, client streaming, and bidirectional streaming. The server app exposes gRPC endpoints that are consumed by the Java client app, which in turn acts as the backend-for-frontend for the Angular UI. The Angular app makes these interactions visual, so others can see and learn how gRPC works in practice.

What is gRPC?

gRPC is a high-performance, open-source RPC (Remote Procedure Call) framework originally from Google. It lets a client call a method on a server as if it were a local function. Under the hood it runs over HTTP/2 and serializes messages with Protocol Buffers — a compact, strongly-typed binary format defined in a shared .proto contract from which both client and server code are generated.

Why gRPC after HTTP/1 REST?

REST over HTTP/1.1 with JSON is simple, universal, and great for public, browser-facing, cacheable APIs. But for internal, high-throughput service-to-service communication it carries real costs that gRPC addresses:

  • Transport — gRPC uses HTTP/2: a single connection multiplexes many concurrent calls with binary framing and header compression, avoiding HTTP/1’s head-of-line blocking and connection churn.
  • PayloadsProtocol Buffers encode to a compact binary form that is faster to serialize/deserialize and smaller on the wire than JSON text.
  • Contracts — The .proto file is a single, strongly-typed source of truth. Stubs are generated for every language, eliminating contract drift and most hand-written DTO/mapping code.
  • Streaming — Streaming is a first-class primitive in the protocol, not something bolted on with SSE or WebSocket workarounds.

The trade-off: gRPC isn’t natively consumable by browsers and is harder to debug by hand than JSON. That’s exactly why this project puts a REST / SSE / WebSocket BFF (the Java client) in front of the browser and speaks gRPC behind it — using each protocol where it’s strongest.

The Four Communication Patterns

PatternShapeExample in this demo
Unary1 request → 1 responseFetch a single student profile
Server streaming1 request → many responsesStream the course catalog as it loads
Client streamingmany requests → 1 responseBatch-enroll students, get one summary back
Bidirectional streamingmany ↔ manyLive enrollment advising chat

Each pattern maps to a tab in the live demo, so you can watch the messages flow in real time.

Repositories

ComponentRole
grpc-servergRPC service definitions and server implementation
grpc-clientJava client consuming the gRPC service
grpc-Angular-uiAngular frontend interfacing with the backend

Technical Highlights

  • Protocol Buffers for strongly typed, auto-generated service contracts
  • All four gRPC communication patterns demonstrated with a real domain model
  • BFF pattern bridging browser (HTTP/SSE/WebSocket) to internal gRPC services
  • Full-stack integration: Angular UI → Spring Boot BFF → gRPC server → H2 database
  • Dockerized and deployed via Portainer with Cloudflare Tunnel for public access

Live Demo

Try the demo at grpc.johnpranoy7.dev.