5 ms·
> A benefit of microservices is that each team can be responsible for releasing their services independently and without coordination with other teams. Sounds
by nurettin 5y ago
> A benefit of microservices is that each team can be responsible for releasing their services independently and without coordination with other teams.
Sounds almost sarcastic. How do you deliver API changes without alerting other teams?
- jeffbee 5y agoDon't ever change APIs. It's pretty simple. I don't know why the monolith people believe this is such a gotcha. 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.
- no_wizard 5y agoProper deprecation procedures. you can document how you uniformly deprecate and remove APIs. This is a strength of using something like OpenAPI for documentation, or GraphQL, for instance. It is then the responsibility of a consumer to deal with these deprecation(s). On the most basic level you could also do versioning, though its not my recommendation 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.
- willcipriano 5y agoI'd guess that 90-95% of tickets do not alter a existing API in a non-backwards compatible way
- linuxdude314 5y agoDo you not version APIs you design? 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.
- dzhiurgis 5y agoSure we do, it's been /v1.0/ for the last 2 years!
- habibur 5y agoAll API that I am running had been v1 the whole time.
- scottious 5y agosure, but all of that is a cost which you don't have to pay with a monolith. Versioning APIs and having to constantly think about backwards compatibility with independently moving services is not trivial. Sometimes the cost is worth it. Most of the time it's not
- TameAntelope 5y agoOh, you absolutely have to pay that cost with a monolith, it's just less clear and obvious because you can change all of the consumers when you make a change to an interface.
- nurettin 5y agoYes, and I have to consult with other teams when versioning, I don't just go "welp here's the next version I created and deployed without asking anyone because that's what the IBM microservices manifesto (2006) suggested and some random guy on HN insinuated I'm causing undue friction if I work with you guys"
- tombert 5y agoGenerally speaking if you're adding another field to a JSON or something, that doesn't really break the parser [1] or affect downstream. While you should still probably let the downstream teams know, it's not necessarily going to break anyone's code. [1] I'm aware that that's not always true (e.g. adding a field that's ridiculously large choking up the parser).
- darrylb42 5y agoor you have a customer that has strict validation on and adding a field breaks their ability to deserialize.
- wging 5y agoNot all changes result in a change to the way your service is called, and even those changes can (with some effort and care) be made backwards-compatible. Performance-level changes are one obvious one - for example, I wouldn't expect to have to keep my caller in the loop if I decrease my API's latency by 50ms, even though it might be a good idea. 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.
- bilalq 5y agoThis is how things were done at Amazon quite successfully. The golden rule is to never break API backwards compatibility. If you must, create a new version of the API and leave the old version functional. If you need to shut down old functionality, it becomes a campaign you have to drive to move your dependents off of it. One little thing that people often overlooked but was very important was to have API operations for describing your enums rather than just putting them in the docs. This allowed for easier adoption of them by API consumers and forced them to consider what to do in the case of an unrecognized value being encountered.
- kgeist 5y ago>The golden rule is to never break API backwards compatibility. If you must, create a new version of the API and leave the old version functional 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
- noogle 5y agoHow can accumulation of versions be prevented? Now the same team has to maintain two products, and the underlying mechanism is still limited by the older version. 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).
- ARandumGuy 5y agoThere isn't really a solution to version bloat aside from good processes and general diligence. There's no easy way to handle that sort of thing, unfortunately. 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.
- shuntress 5y ago> Sounds almost sarcastic. How do you deliver API changes without alerting other teams? 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.
- root_axis 5y agoNever break the API. If you need a new API contract use API versioning so that consumers can upgrade when it's convenient. Additionally, use contract testing.
- jokethrowaway 5y agoThat's why finding the right boundaries between services (yes, services, microservices is a harmful buzzword) is important, so that you minimise having to communicate and coordinate with other teams.
- volkk 5y ago100%. Boundaries are extremely important, and if you're a service onto which 7 other teams rely on, there's an issue with your teams and the way you've setup your services. Bounded contexts!
- FpUser 5y agoSomething like Microsoft does with the their interfaces 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.
- jacobsenscott 5y agoAlso, this (independent deployability) is simply not a feature of microservices. It is a feature of any well architected code base. 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.