DEV Community

Cover image for Meet Polyhymnia: The Random Quote Generator That Took the Scenic Route
Gouranga Das Samrat
Gouranga Das Samrat

Posted on

Meet Polyhymnia: The Random Quote Generator That Took the Scenic Route

Why a one-line SQL query became a four-language, five-hop distributed system — and why that's secretly a great way to learn system design.

The most over-qualified button you'll ever click

Somewhere in this project's proto file lives a service called Randomizer. Its entire job — its only job — is to pick one number out of a short list. That's it. That's the service. It has its own gRPC port, its own protobuf messages, and its own opinions about entropy.

That single fact tells you everything about Polyhymnia: a random quote generator that could have been a SELECT quote, author FROM quotes ORDER BY RANDOM() LIMIT 1; and one HTML page, and instead is four services, three languages, one build system juggling three different toolchains, and a network hop count that would make a CDN blush.

This is the first post in a four-part series pulling apart why it's built this way and what it's quietly teaching you about real distributed systems along the way. No PhDs required — just a tolerance for services that do less work than the plumbing required to reach them.

What it does vs. how it does it

Functionally, Polyhymnia is almost insultingly simple: you click a button, you get a quote and its author. There is no user data, no auth, no pagination, no edge cases worth mentioning.

Architecturally, that click sets off a small relay race:

┌────────────┐   HTTP GET    ┌──────────────┐
│  Frontend  │ ────────────▶ │  Go Gateway  │
│ (JS/HTML)  │ ◀──────────── │ (Orchestrator│
└────────────┘   JSON quote  └──────┬───────┘
                                     │
                 ┌───────────────────┼───────────────────┐
                 │ 1. GetAllIds       │ 3. GetQuoteById    │
                 ▼                    │                    ▼
          ┌─────────────┐             │             ┌─────────────┐
          │  Rust "db"  │◀────────────┘             │  Rust "db"  │
          │  service    │                            │  service    │
          └──────┬──────┘                            └─────────────┘
                 │ 2. SelectRandomId
                 ▼
          ┌─────────────┐
          │  C++ engine │
          │ (Randomizer)│
          └─────────────┘
Enter fullscreen mode Exit fullscreen mode

Five network hops. Three separate gRPC calls. Two backend services that only exist to serve one HTTP endpoint. The gap between "what this does" and "what it took to do it" is the entire point — and it's a deliberate constraint, not an accident of scope creep.

The name is doing a lot of work

Polyhymnia was the muse of sacred poetry and song in Greek mythology — a fitting name for something that ships one-liners. But the real pun is etymological: Poly (many) + Hymnia (words/song). Swap "many words" for "many languages," and you get the actual joke — this is a message (a quote) delivered through a genuinely polyglot pipeline: Go, C++, Rust, and JavaScript, four languages for one payload.

It's a rare case of a project name being both a classics reference and an architecture diagram.

The tech stack, with a straight face

Layer Language Responsibility
Frontend JavaScript / HTML / CSS One button, one quote, zero frameworks
API Gateway / Orchestrator Go HTTP entrypoint, drives the 3-step gRPC workflow
Mathematical Engine C++ Picks one ID at random, with unnecessary ceremony
Database Manager & Safety Layer Rust Owns quotes.db — the only service allowed to touch SQLite
Database SQLite Three columns: id, quote, author
Inter-service transport gRPC + Protobuf One shared contract, three independent codegens

Each row on that table is a genuine, deliberate architectural decision, not a random language pull from a hat. Go fronts the request because it's comfortable being a thin, concurrent I/O layer. Rust owns the only piece of mutable state in the system because "safety layer" is basically Rust's job title. C++ shows up purely to demonstrate that even picking a random array index can be turned into a systems-programming set piece, complete with hand-mixed entropy and pointer arithmetic. We'll get intimate with both of those services in Part 3.

Overengineering as a teaching tool, not a punchline

It would be easy to wave this project off as a joke and move on — and it is a joke, proudly, in the README's own words. But strip away the comedy and what's left underneath is a genuinely well-formed distributed system, built at a scale small enough to actually read in one sitting:

  • A single ingress point. Only the Go gateway speaks plain HTTP; everything downstream is gRPC-only. That's a real API gateway pattern, not a toy version of one.
  • Contract-first design. One .proto file is the single source of truth for every message and RPC. Three languages generate their stubs from it independently — nobody hand-writes serialization code.
  • Strict data ownership. Exactly one service is allowed to open the SQLite file. Nothing else touches it, ever, directly or otherwise.
  • A stateless compute service sitting next to a stateful one. The C++ engine holds no data and could be replicated infinitely with zero coordination. The Rust service holds the only state in the system and has to be far more careful about it. That contrast is a genuinely useful thing to internalize, and Polyhymnia hands it to you on a plate.
  • Orchestration, not choreography. The Go gateway explicitly sequences three calls rather than having services react to each other's events. That's a real, debatable system design choice with real tradeoffs — not an accident.

None of that is complicated in isolation. What makes Polyhymnia worth studying is that it's small enough to hold the entire system in your head at once, while still containing every major decision point a much bigger distributed system has to make. It's a system design course condensed into something you can git clone and run on a laptop in a few minutes.

Where this series goes from here

Over the next three posts, we're taking the project apart layer by layer:

  • Part 2 — the Go gateway: the art of being a professional middleman, and what its retry loop and error-mapping logic quietly teach about deadline budgets and failure taxonomy.
  • Part 3 — Rust's safety layer and C++'s beautifully unnecessary randomness: data ownership, parameterized queries, and what "overengineered" entropy actually looks like under the hood.
  • Part 4 — shipping the chaos: the shared protobuf contract, three independent codegen pipelines, Docker packaging, and one networking gotcha hiding in plain sight in the compose files.

If you want to follow along with the actual code, the repository is here: GourangaDasSamrat/Polyhymnia. Clone it, click the button a few times, and then come back for Part 2 — where we put the Go gateway under a microscope.

Top comments (0)