// SYSTEM_LOG_ENTRY_20260716● DECRYPTED
Four Services, One Graph: gRPC Microservices in Go
GogRPCGraphQLMicroservicesElasticsearch

Four Services, One Graph: gRPC Microservices in Go

AUTHOR: ADITYA_PANDEY // Account, catalog, and order services speaking binary gRPC internally, aggregated behind a single GraphQL endpoint — with PostgreSQL and Elasticsearch each doing what they are actually good at.

Microservice tutorials usually stop at "two services and a REST API". go-grpc-micro is my attempt at the version you'd actually run: four independent Go services, binary gRPC on the inside, one GraphQL endpoint on the outside.


The architecture

| Service | Responsibility | Storage | |---|---|---| | Account | User accounts | PostgreSQL | | Catalog | Product catalogue | Elasticsearch | | Order | Create & retrieve orders | PostgreSQL | | GraphQL | Aggregated API façade | — (talks gRPC to the other three) |

Every service is an isolated Docker container. Nothing is exposed except the GraphQL endpoint — the gRPC services only exist on the internal Docker network.

Why gRPC inside, GraphQL outside

  • Internal calls are chatty and structured → gRPC's binary protobuf wins on latency and gives you generated, typed clients for free
  • External consumers want flexibility → GraphQL lets the frontend ask for exactly the shape it needs, and `gqlgen` generates the resolver scaffolding from the schema
  • The façade also carries a WebSocket endpoint, wired for GraphQL subscriptions

One query hitting three services:

graphql
mutation {
  createOrder(accountId: "acct_123", products: [
    { productId: "p_001", quantity: 2 },
    { productId: "p_003", quantity: 1 }
  ]) {
    id
    createdAt
    totalPrice
  }
}

The GraphQL service resolves the account via the Account service, validates products against the Catalog service, and writes through the Order service — all over gRPC.

Polyglot persistence, on purpose

Accounts and orders are relational, transactional data → PostgreSQL. The product catalogue is a search problem → Elasticsearch. Using one database for both is how you end up writing `LIKE '%query%'` and calling it search.

Lessons

  • `docker-compose` network isolation is underrated as an architecture enforcement tool — if the only reachable port is the façade, nobody "temporarily" couples to an internal service
  • Generated gRPC clients make cross-service refactors mechanical instead of scary
  • A GraphQL façade is the cheapest API-gateway pattern there is: schema-first, typed end to end, and the aggregation logic lives in exactly one place

Stack: Go, gqlgen, google.golang.org/grpc, PostgreSQL, Elasticsearch, Docker Compose.

// END_OF_TRANSMISSION</ EXIT_SYSTEM_LOG >