Microservices architecture guide: four things to consider prior to migration
You’ve decided that you’re going to make the leap and start migrating to a microservices architecture. You have very good reasons for this decision, perhaps the most important of which is your understanding of how difficult it’s going to be to safely deliver the application your users really want within the confines of a framework. In other words, you’re well past the “should I migrate to microservices?” part of the equation. We’re going to assume that you have a clear statement of why you should migrate, and we hope that our’s will resonate with yours, but if you don’t yet have a clear one, you should take a couple of steps back. Microservice architecture isn’t a magic bullet, and can sometimes do little more than create many small problems from one big problem.
You have other great reasons for wanting to move to microservice architecture, like smart ingress controllers, infrastructure as code & gitops, canary releases, cheap test environments, developer autonomy (both individually and in teams). But there’s something you really need to think about right now - the more things are simplified for those that already know how everything works, the more difficult it can be for newcomers to understand and learn.
Different teams working on different parts of your code want to approach problems in new ways, using new databases (or no databases), new threading models, different kinds of caching and logging and the DRY principle is screaming to you that these need to be separate projects entirely. Instead of one circus with three rings, you have three circuses with three rings each, and the potential to proliferate exponentially from there.
If you want the tl;dr version of it - we recommend that you really think about onboarding, offboarding and your general flow of how you document your code before you start your microservices migration. If you want the best possible speedup from delivery being continuous, your documentation needs to follow suit.
Onboarding and offboarding are constants
This is going to remain true even when you’re not hiring anyone new.
Don’t look at it as hiring and firing, look at it as having 20+ code bases where any given developer might need to quickly get up to speed as things change.
At the rate that microservices both proliferate and change, moving developers between teams will require different levels of ramping up, and ramping down (offboarding), which can lead to more instances of code bases changing maintainers. This is going to happen during less-than-ideal scheduling circumstances and might play out like this:
Engineering Manager: I need you to take over maintainership of the drop-ship service. Do you have any questions about it?
Developer: Yes! What questions should I have about it?
Engineering Manager: Very funny. It should be easy. Just make sure you ask Kathleen what we do for a release before she leaves.
The developer in the conversation above was working on something completely unrelated when that question came up. He dropped what he was doing to have a talk with Kathleen, who was already using her vacation time prior to leaving the company, and he took some notes.
Do you think those notes made any sense when he had to manage the first release on his own? It’s imperative that knowledge isn’t just transferred - because we never know exactly what we’re going to need to know. Rather, knowledge should be captured so it can be consumed by individuals in whatever way they learn things best.
If you’re going to succeed with microservices architecture in a startup environment where you have even mild turnover, you have to make sure all high-level concepts are clearly documented and up-to-date, that all procedures are enumerated, and that in general, the loss of a subject matter expert falls softly on your documentation rather than hard on the poor soul that has to get up to speed purely by their wits.
Losing very well-documented code
Frameworks become popular for many objective and technically-sound reasons like performance, design and novelty - all really good reasons. Many developers will trade better design for a lack of immediate features. Once frameworks reach feature parity with other frameworks in the same language, it can be really hard to decide which one might work the best for you.
A resounding criteria for selecting one out of many competing frameworks is documentation. This is because documentation is considered to be the first line of support for most frameworks, and most seasoned developers would be very concerned about walking into a bunch of code they knew nothing about with very little documentation … wait a second, that’s almost exactly what they’re going to be doing when you migrate to microservices architecture!
You don’t need to do anything about this other than realize it, and prioritize creating it as your new code solidifies. Objectively, it’s difficult to say when you should start making sure you’re writing comprehensive docs, the answer tends to just be “it depends.” Once you can finally refactor without major architectural changes, it’s time to document, and you need to stress how important it is to do this while things are fresh in everyone’s mind.
You can’t just Google the database class anymore
If you’ve ever dabbled in PHP, you’ve probably at least heard some conversations and strongly-held opinions about CodeIgniter. One thing that can’t be denied is, it’s one of the most well-documented MVC style frameworks around, and that documentation is definitely a feature.
That’s why I was extremely surprised one day when I actually thought I found something that wasn’t documented in it. A really helpful Stack Overflow user pointed out what I needed, and where it was actually documented, and I was able to get my job done on time.
You lose more than productivity when you hit a snag and can’t find anything, you lose a bit of hope. You know you’re going to need to ask someone on your team to stop whatever it is they’re doing and explain something to you. The cognitive overhead of this can actually make your team members ditch sound design decisions because they seem too complicated in favor of something they can probably get working on their own. It’s human nature.
The only person who can answer “how do I [x] with [foo]” is the person that wrote the Foo service, unless they’ve captured all the narratives needed for people to understand the code and design the way that they do.
Don’t assume tacit knowledge will transfer
If you’re unfamiliar with the term, tacit knowledge is the kind of knowledge that is implied through the observation of many different things. For our cases, the term pertains to knowledge that you acquire through seniority which is documentable, but not documented in a form that is readily conveyed or even discoverable when someone needs it.
Think of a car. Cars need fuel of some sort. Cars have a tank with a convenient opening to fill them up so they can go. When there’s no fuel, the car doesn’t move.
Giving someone up-to-date documentation that (and here’s the checklist):
- Matches the code, and explains functionally how it works (code comments)
- Describes the high-level flow of the code, and what’s intended to be reused (code not being reused is a classic symptom of bad documentation)
- Describes design decisions, coding style, antipatterns - what should a new contributor know and keep in mind?
- Offers learning paths (how do I add a new route? How do I add a new config option?) based on endeavor
- Describes future directions
… is like putting fuel straight into the tank with the nozzle. However, if you miss one or more of the bullets above, it would be like putting a little gas in the tank, then pouring the rest all over the body of the car in hopes that it will sink in somewhere. It’s also dangerous for fire safety reasons, but that’s not really part of this analogy.
This is a big part of your company history, but don’t make too many questions require an entire history lesson in order to answer. Document everything your future self might need in 3 years time to win a bet on what was actually decided way back when you started the microservices migration if it’s ever called into question.
Conclusion - you’re going to be fine
There’s a whole lot of under-documented software out there that does amazing things for people, despite the fact that their developer teams losing knowledge with even small amounts of churn and great code never gets reused. But with just a minimal amount of effort that mainly boils down to presence of mind when it comes to knowing what to capture things can really be better.
People can onboard to new code faster, with the same advantages as all of their peers. Imposter syndrome can be drastically curtailed and critical knowledge won’t get lost as careers grow and folks transition in and out of roles.
We hope you’ve enjoyed this post, and that you find and gain value from it. All of this is possible and quite a bit of it can be automated. If you’d like to see Swimm in action, sign up for a Swimm demo.