4 ms·
I've actually found overhead to increase significantly when using micro-services vs a monolithic codebase. Automated integration testing is far more complex. En
by optimuspaul 11y ago
I've actually found overhead to increase significantly when using micro-services vs a monolithic codebase. Automated integration testing is far more complex. Ensuring that a change in one micro service doesn't break things in another can be daunting. But when you have a common codebase dependencies are far more clear.
Of course if you have tons of cash and resources to throw at it then that isolation could be beneficial. But is it worth it? I have no idea.
- vonmoltke 11y ago> Ensuring that a change in one micro service doesn't break things in another can be daunting. That is what I was referring to when I mentioned nebulous APIs. In a properly-designed system, each component (be it a module of a monolithic system or service in a microservice system) should be a black box with known APIs and no side effects. Part of defining the API is defining the acceptable values that can come across the wire. If designed correctly, breaking another service should not be possible without an API change. An API change should be something signed off by systems engineering and communicated to all affected teams before it happens. Done right, this is a fairly heavyweight process and so, as others have said, is only something that should be done when a project reaches a certain level of complexity (both code and team).
- wvenable 11y agoThe more your system is broken down into smaller components the more you have to break an API to make a change. Unless all change consists of nothing but bug fixes and performance enhancements, changes to the API is as common as anything else. If your need is respond quickly to changing requirements this setup falls flat.
- cpitman 11y agoYes, if services are too small than it will be hell. A lot of microservice proponents talk about how services should align to a "bounded context", essentially a domain of the business. That makes it more likely that (1) there are well defined interfaces between business domains and (2) changes will be grouped into a single service as opposed to requiring changes throughout the codebase. Also, if it's being done right, you rarely "break" an API in a single blow. You add new functionality, possibly via a new API. You give your consumers ample time to migrate. Only then do you remove the old API. One of my old teams had a hard requirement that all APIs had to be backwards compatible for 2 versions, which was essentially a year. We got very good at adding functionality without any impact on consumers that had not upgraded yet.
- lowbloodsugar 11y agoWe've never had to break an API to make a change. Changes to the API should not break existing consumers. That's just as true for monoliths as it is for microservices.
- wvenable 11y agoA change to an API necessarily, by definition, breaks existing consumers. You can add to an API without breaking consumers but you can't change or remove.
- lowbloodsugar 11y agoThere are at least two ways to change an API without breaking it: * Adding a new method to the API does not break the API. * In certain language/middleware combinations, adding new properties to a parameter object does not break the API. If we have a method that needs to change, we add a new method. New clients use the new method, and we support old clients until they are retired. When using JAX-RS, we can add new properties to JSON objects provided they are annotated correctly.
- wvenable 11y agoYou effectively have to maintain a backwards compatible system but that limits the amount of change that you can really do. It also definitely makes the system more complicated but more stable. That's the trade off. If you're constantly changing/breaking the API then that's just a monolith in micro-service clothing. But the system can be simpler and you can make more significant changes quicker.
- lowbloodsugar 11y agoIf you think of "the system" as the entire suite of applications across space and time, then the one approach is no more complicated than the other. One involves some effort thinking about backwards compatibility, the other with trying to get a bunch of teams to all commit to the right branch, and then get it integrated at the same time. My experience is that the latter proves far more disruptive to production. One of our groups (the monolith team) has one month code freezes while they integrate all the teams work into the latest monolith. Our teams really have no limits on the changes they can do. If the change really is so complex that it requires changing every system, then we just build another system with zero dependencies. In fact we did that once. Got it working really fast. Usually branch-by-abstraction resolves any big issues, while updated method objects or just new methods handle most "changes". Granted, this is with several hundred developers across multiple engineering departments. YMMV.
- dreamfactory2 11y agoSo you either use versioning or RESTy immutable endpoints. Anything else is going to be unmaintainable
- cpitman 11y agoIn most environments systems are already distributed, it's just that each "component" is a massive monolith. Sometimes, it's the cobol monolith, the .Net monolith that partially replaced it, and the NodeJS monolith that is going to replace everything (for sure, this time we mean it). Integration testing is already complex in these environments, regardless of whether the components are monoliths or microservices. BDD style integration tests should be almost equivalent, regardless of the architecture, since they are driven by the business domain.