Sounds almost sarcastic. How do you deliver API changes without alerting other teams?
Sounds almost sarcastic. How do you deliver API changes without alerting other teams?
It also helps with zero-downtime deployments:
1) spawn a new instance of the service with the new API, side by side with the old one
2) now incoming traffic (which still expects the old API) is routed to the new instance with the new API, and it's OK, because it's backward-compatible
3) shut down the old instance
4) eventually some time later all clients are switched to the new API, we can delete the old code
Anecdotally, a robust backward-compatibility has been seen as a hinderance to e.g. Java's progress (so much that a newer language, Kotlin, was created to break free from that burden).
However, I do think it can be easier to deal with for internal services then for something like Java. When the number of users is in the dozens rather then the millions, it's a lot easier to make sure everyone gets moved over to the new version.
The point of organizations and products is to work as a tightly coordinated machine. The decoupling that microservices create seems opposite to that goal.
Happy to hear different perspectives.
>it's harder to keep everything aligned due to the extra separation (e.g. different code bases, multiple databases, no static validation of remote interfaces etc.)
It's solvable with appropriate tooling. I.e. you can store API definitions in a separate repository and make the services or CI/CD check API usage is valid at build time.
>tightly coordinated machine
What do you mean by that? For example, we have 10 teams all developing different features in parallel, with a tight release schedule. If there was tight coordination for every change, we'd degrade to a waterfall on the scale of the whole organization. Major API changes are discussed in advance during P/I planning; for minor changes, it's a matter of simply notifying other teams "hey, add this to your backlog, please" (we enforce backward compatibility for zero downtime anyway, so it's not urgent)
> What do you mean by that? Data and workflow have to be unified across the company's products to provide the user with a seamless experience. As above, to me this seems may contradict some components of microservices like splitting the database, since one ends up with the same constraints (synchronization, shared schema) while complicating the orchestration (since now cross-system integration is needed).
Sure, something like Reddit or HN can break the unified experience, but any important or productivity system will greatly suffer from such fragmentation. I assume it can be achieved with micro-services, but it seems somewhat harder.
Sounds almost sarcastic. To deliver API changes without alerting other teams you, of course, simply deploy the changes without sending a message to the other teams.
The non-sarcastic answer is that sometimes you want to make changes that will not affect an APIs users in any significant way. Of course you would still document these changes in a change log that the consumers of the API may or may not check. Or you may want to hype/market these changes for clout reasons.
Maybe it's an API that services multiple sets of users with different partially-overlapping requirements and they don't all need to know about the new change.
Maybe it's a soft launch for a surprise feature that's going to be announced later.
Maybe the other team is on vacation and you just want to get changes out the door before some holiday.
When engineering an API meant for consumption by disparate services it’s imperative to provide back words compatibility.
This is pretty basic stuff anyone designing a serious API should be taking into account.
Sometimes the cost is worth it. Most of the time it's not
I've always worked on monoliths, and I've almost never needed to coordinate a release with anyone. I just merge my branch and deploy. Github and shopify talk about merging and deploying monoliths hundreds of times per day without coordination.
The case where you would need to coordinate a release in a monolith is exactly the same case where you would need to coordinate a release in microservice app. That's the case where your change depends on someone else releasing their change first. It doesn't matter if their change is in a different service, or just in a different module or set of modules in the same application.
Now, most application are not well architected - micorservices or monoliths. In the case of a poorly architected app deploying a monolith is much easier anyway. Just merge all that spaghetti and push one button, vs trying to coordinate the releases of 15 tangled microservices in the proper order.
If you really need to change the API, give the new API another name. You may choose to think of this as "versioned APIs", if you want, but "versioned" and "renamed" are the same thing.
Document and set expectations accordingly. I've done this move before breaking apart a monolith into separate micro services and this is key. Spending more time on good documentation is generally a good idea regardless.
I'm assuming we're not talking about public facing APIs. That's a situation where versioning might make a lot more sense.
[1] I'm aware that that's not always true (e.g. adding a field that's ridiculously large choking up the parser).
They have multiple versions of calls. The older one function as before and never change. Want different behavior - here is your_interface_v1(), your_interface_v2(), etc.
You still alert team about new functionality but they're free to consume it at their own pace. This of course involves a boatload of design and planning.
I am in general against microservices and consider those as the last resort when nothing else works. To me a microservice is mostly my monolith interacting with another monolith.
When monolith becomes big enough that it needs 2 teams I usually handle it by each team releasing their part as a library that still gets linked into the same monolith. That is my version of "microservice" when the only reason for it to exist is to have two or more "independent" teams.
But other behavior changes are also not necessarily something that requires a team to be alerted. A good design provides an abstraction where the caller shouldn't have to care about the underlying implementation or details of how a request is fulfilled.