skip to content
Scott's Ramblings
Patrick Federi, Unsplash

Rust: From Systems to Services

/ 7 min read

You awake one day under the desk in the austere surrounds of your swiss-based IT startup, cold sweat on your brow, the taste of stale lager in your mouth. The startup is already months old, but is yet to produce a product, or even a guiding vision. Your boss stumbles in. Hans? Yes, Hans.

In a haze of high-alpine clarity he shouts: I’ve got it! We’ll build an app to catalogue mountain passes!, then mumbles something about how the Swiss will always pay for mountain-themed accessories. You cannot fault his logic.

As the Lead Engineer, the task is now on you to take this blue-sky visioneering and reify it into something concrete, and optimally, money-earning. This means technology decisions. You’ve heard a lot about Rust lately, and how it is the bees knees and then some. But before you can type cargo init into your extensively customized shell, Hans blurts out - we should probably use something established - like Quarkus or go - to reduce our time to market. Indeed, the team happens to have extensive experience with Quarkus, the popular Java framework. Does it seem like Rust is going to make enough of a difference to switch? Said otherwise - is this a helpful insight, or the series-A addled ramblings of a madman?

Let’s dig in.

Sketching out the system

The team’s very important business goal established, it is now time to sketch out our app. You’d like to establish a modern foundation for the team, that is, make reasonably sensible technology choices, and you’d like it to be as straightforward to work on as possible; no-one wants to listen to developers blame their tooling for low productivity for the next X years. Your startup cares deeply about developer experience and rapid iteration, and everything should work well locally and in the cloud. This precludes a bunch of the fancier cloud services - but honestly, you don’t have elaborate hyperscale ISV dreams, so this feels like a reasonable compromise.

The API

To start with, you figure you’ll need a couple resources:

  • /api/v1/passes - Provides REST-style CRUD manipulation of mountain pass information - country, location, height, and so on.
  • /api/v1/pass_image/:pass_id: - Provides an aerial image of a given mountain pass by ID. This performs image manipulation, and has a nice opportunity to “fan out” some work in parallel. Something a bit “chunkier” in terms of resource consumption!

To complete your sketch, you figure your pass model will look roughly like this:

/api/v1/passes/123
{
"id": 123,
"name": "Gotthard Pass",
"country": "Switzerland",
"ascent": 2106,
"latitude": 1.32,
"longitude": 4.56
}

The Architecture

To build the API, you’ll need a database to store all the things. PostgreSQL feels like the default relational choice these days, and has the added advantage that the hyperscalers provide managed oferrings of it, and there are even battle-tested Kubernetes operators should you choose to go down that path.

Humbled by your years of engineering and a deep back catalogue of retrospectively poor decisions, you sense that future extensability might be something to bake in from the get-go, and decide to bolt an event bus on the side, emitting events about the pass data changing. You figure Kafka is the default sensible choice here - and another example of a nice, open-source tool that is broadly supported on the hyperscaler platforms and Kubernetes - so Kafka it is.

For aerial imagery of the passes, you’ll fetch OpenStreetMaps tiles, and stitch them together into mosaics.

Finally, we’ll also want observability - distributed tracing, metrics, and logs - all nicely wrapped up together, and for this we’ll use OpenTelemetry.

All told, your architecture looks like this:

Diagram

Taking a step back, you realise that this architecture - an API, a database, a message bus, and some observability wrapped around it - seems like a pretty typical way to structure a modern app. How convenient! - it is almost as if your observations about the technology choices made to build this are likely to apply to all sorts of other apps too!

Simple, right?

Language and Framework

Now that you’ve got a handle on what you want to build, and the broad-strokes architectural components - you’re getting to the meat of the development sandwich. What language and framework makes sense?

You want to use Rust - it’s shiny and new, and honestly, the idea that a language can provide better performance and thus lower energy impact is something you think we should all care more about. On the other hand, it is ultimately a language built for systems programming, and has only really moved iup into the web service space in the last couple years. How will developer productivity be?

Armed with a professional awareness that pragmatism is a thing, and picking up a new language with no experience is perhaps not that, you decide to spend a week hacking out a proof-of-concept on a couple of different stacks before proposing this final detail to the rest of your team.

Java + Quarkus

Java doesn’t have the most modern rep, but it has been there, plodding consistently along, for your whole career. It is fast, and even faster with GraalVM and native compilation, and runs on everything that has registers and a bit (narrator: a lot) of RAM.

You’ve used Quarkus before, and it was amazing. With opinionated pluggable extensions for all the things, GraalVM support out of the box, and a focus on native container development, it is about as far as you can get from the Weblogic-based EJB3 enterprise-java of yore.

Golang

You’re not particularly enthused about go - it seems very verbose and C-like - but have noticed the change in the wind. With massively succesful projects including Cilium and Kubernetes written in it, and companies like Datadog and Google using it for their own services - it would be remiss to exclude it. With less of a clue about the golang ecosystem than that of Java, you’ll kick decisions like framework choice down the road to the proof-of-concept itself.

Rust

… and of course, Rust. Will it provide enough of a upgrade on top of Quarkus to offset what you’ve heard is quite the learning curve? As with golang, the details here will emerge as your proof-of-concept progresses, and will be informed by the experience with the two previous languages.

Next Up …

In the next installments, you’ll write up your experiences with each of these language-specific proof-of-concepts - to try and decide which platform makes the most sense for the long-awaited Mountain Pass App in this modern world we live in.