Hermes: internal API gateway and service registry. One governed path for every internal call between microservices.

Hermes: the internal API gateway behind our microservices

By Saikat Barman ·

The hard part of microservices is the space between them

Split a system into enough services and the services stop being the problem. The calls between them become the problem.

Every team wires its own clients. Addresses sit in config files. Timeouts and retries depend on who wrote the code. When a request fails three hops deep, finding where takes longer than fixing it. And the question “which service may call which?” has no single answer.

I built Hermes to close that gap. Hermes is an internal API gateway and service registry: one asynchronous gRPC service that every internal call passes through. It is named after the messenger of the Greek gods, because carrying messages reliably is the whole job.

One address instead of many

Hermes has two parts.

A service no longer needs to know where any other service lives. It knows Hermes, and Hermes knows the rest.

Hermes turns a web of direct calls into one routed pathBefore: services call each other directlyService AService BService CService DService E5 services, up to 10 direct connections to manageAfter: every call goes through HermesHermesService AService BService CService DService E5 services, 5 connections, one place to control them
Before and after: direct calls versus calls routed through Hermes.

With five services, direct calls mean up to ten connections to secure, monitor and keep in sync. Through Hermes there are five. The gap widens with every service you add.

How a call travels

Every call follows the same path, whichever service makes it.

Every internal call is authorised, resolved and routed the same wayHermes gatewayCallerinternal service1 AuthoriseCheck ABACpolicy2 ResolveLook up targetin registry3 RouteForward overasync gRPCTargetinternal serviceRejectedpolicy says noRegistryAPI catalogueGrafanadashboardsdenylookuptraces and metrics
Call flow: three steps inside the gateway and the parts that support them.
  1. Authorise. Hermes checks the call against attribute-based access control (ABAC) policies. A caller without the right attributes is rejected before it reaches the target.
  2. Resolve. Hermes looks up the target in the service registry.
  3. Route. Hermes forwards the call over asynchronous gRPC. Nothing waits on a blocked thread, so one slow target does not stall the calls behind it.

Every call leaves traces and metrics behind, and those feed the Grafana dashboards.

What we get from it

The ten benefits group into four pillars, with security underneath all of them.

Ten benefits stand on four pillars and one security baseHermes: one governed path for every internal callControlInternal routingOrganised registryReliabilityFault tolerantResilientSpeedgRPC, low latencyNon-blocking asyncVisibilityTraceable callsEasy monitoringGrafana dashboardsSecurity base: ABAC enforced at the service level
Benefits: four pillars on a security base.

Control. Routing lives in one place. The registry keeps the estate organised: every internal API is listed and findable.

Reliability. Every call passes through one layer, so failure handling is built once and applied everywhere. That makes the platform fault tolerant and resilient without each team reinventing it.

Speed. gRPC keeps service-to-service latency low. Asynchronous communication keeps calls non-blocking, so the gateway handles many calls at once without tying up threads.

Visibility. Every call is traceable end to end. Monitoring is easy because the data comes from one source, and performance dashboards on the Grafana stack show how the whole estate behaves.

Security. ABAC is enforced at the service level. Each call is allowed or denied on the attributes of the caller and the target.

What it costs

A central gateway is not free, and pretending otherwise would be dishonest.

For a growing estate, I think the trade is worth it: a small, known cost per call in exchange for control, visibility and security that no team has to build twice.

The takeaway

Microservices do not fail because individual services are badly built. They fail in the gaps between services. Hermes gives those gaps an owner: one path, one registry, one set of policies and one view of what is happening.

How do you handle internal service-to-service traffic: a gateway, a service mesh, or direct calls? I would like to hear what has worked for you.