As a developer, when I set out to write a microservice, I start with the desire to accomplish a specific thing. This is my job-to-be-done. But old-style microservices force me to back up and think about the system coding first. How do I create a web server? How do I start and stop it? What do I do with system interrupts? such distractions are not good. Furthermore, they point to the hidden cost we take on when tackling systems programming in tandem with our job-to-be-done.
In its simplest form, a microservice is an HTTP endpoint that performs one specific task. Sometimes we talk about microservices as consisting primarily of REST/JSON APIs, but really, any HTTP service that focuses on managing just one small task is a microservice.
Since the rise of the microservice architecture several years ago, developers have followed a familiar pattern when coding: write a complete HTTP server (often starting with a framework), add a request router (also often from a framework), and then add business logic. This makes for a burly bit of code weight.
In Rethinking Microservices I argue that this is not the way we should write microservices. It puts too much operational burden on the developer while complicating the security story. Starting from a hefty framework is inefficient. As I said there:
That's an awful lot of overhead to foist on a developer! While the path to installing such frameworks is small at the outset, there are several hidden costs:
- The compute resources are more expensive than they should be. Consequently the monetary cost of hosting such a service is increased.
- The security story inextricably involves the developer in the most crucial part of the operational story: The developer is responsible for fixing upstream vulnerabilities in supporting libraries. (And the operator/SRE/devops must involve the app developers in security maintenance.) Thus, the operational cost is higher.
- Finally, the cognitive cost of coding is higher. The developer has to think at the system level ("What ports am I using? How do I handle system interrupts?") in addition to thinking about the job-to-be-done ("What is the main job my code does?").
In Rethinking Microservices, I start with those problems and dive deeply into an explanation of why WebAssembly is a solution.
Now, with the first release of the open source Spin Framework, we at Fermyon have produced an example of what this new version of microservices looks like. Spoiler: it does not start with the developer writing (or importing) a web server. That is a job for the platform. Rather, the developer begins by writing a request and response handler. In other words, coding starts with the job-to-be-done.
In our documentation, we show examples of building HTTP microservices. But we extend services to listen not just for HTTP events, but also for Redis events. And we're in the process of adding more. In short, we want to extend the best of the microservice architecture into other types of triggers. (We have a really fun demonstration coming at our DockerCon talk in May, 2022.
WebAssembly, with its ultrafast startup times and small binary sizes, is enabling this next wave of cloud computing. The techniques and languages that we see showcased here on Wasm.Builders are the stepping stones to building a new generation of microservices that will get the job done without sending the developer down needlessly distracting paths.