3 ms·
# Microservices Agreed the same database gets difficult but I guess, where two things need to change dependently there's coordination overhead, that's inescapa
by Guid_NewGuid 4y ago
# Microservices
Agreed the same database gets difficult but I guess, where two things need to change dependently there's coordination overhead, that's inescapable. You can in general use e.g. schemas to keep domains fairly separate. Whether it's your HTTP API interface changing or the change needs to be coordinated in the same process I don't think you have a way to avoid these meetings. (or like the 3rd party team I work with you just change your HTTP API and break production without telling us :shrug:).
I guess my point is languages like Java and C# are much maligned for their "boilerplate" and it doesn't let 10x genius programmers go brrrrrr etc. But that boilerplate serves a purpose. Projects (in C#, I can't speak to Java but I believe it has a similar concept) compile to separate .dll's, or .so's. In general a project will publicly expose interfaces, i.e. contracts, and keep its internals encapsulated. Crucially projects all live in the same codebase in the same monolith, they're folder/directory level separation, but on steroids. There are tricks with attributes and reflection that can break this separation but with the additional constraint that dependencies cannot be circular you're forced to make decisions about where exactly things live. This is where the dynamic crowd throw up their hands and say "there are so many layers of pointless abstraction!". I'd agree these languages tend to too many layers but the layers provide the foundation which can support a project growing from 1-2 devs all the way through to 50+.
I'm maybe finally becoming a grumpy old programmer and I'm glad much of the consensus is swinging away from the no-types, no schema, no rules position of the past decade. People forgot Chesterton's fence and decided the layers didn't provide anything, then they added them back, as network boundaries, which was indescribably worse and more of a headache.
# Testing
I guess it's a semantics debate really. I think the red-green-refactor loop of TDD doesn't bring much. I've never seen it applied well on a statically typed codebase and where I've seen advocates try and apply it I've seen them tunnel-vision to suboptimal outcomes in order to fulfil the ceremonial needs of the process.
I think a few tests that take place at the project/dll/so boundary and use as much of the real dependencies as possible are far preferable to high coverage. This is probably a no-true-Scotsman area of debate. Maybe TDD has been done properly and productively by some groups, I've never seen it and no one I've met ever has (check out my confirmation bias!).
- deleted 4y ago[deleted]
- randomdata 4y ago> Whether it's your HTTP API interface changing Interfaces don't change under microservices. Communication by contract enshrines a contract. You must ensure that your API does not break legacy users no matter what changes you want to make going forward. You have committed to behaviour forevermore once you submit the contract to other teams. This may be another reason why IPC is often preferred over straight function calls as some languages, particularly those with static types, make extending functionality without breakage quite hard. An HTTP API can more easily resort to tricks to return different results to different callers. > I think the red-green-refactor loop of TDD doesn't bring much. You find little value in writing a specification for your work or you find little value in automatic validation that the program works according to your spec? "Red-green-refactor" is a little more specific in that it says that you should write a spec only for the work you know you are going to work on in the short term, whereas TDD in general leaves room for things like writing the entire application's spec before getting down to business. I think this is most practical in the real world, generally speaking. Often you don't know what your entire application should do in the beginning, making writing a full spec unrealistic. > I've never seen it applied well on a statically typed codebase Interesting, as I have only ever seen specifications (be it TDD or "Word documents") written for work that is done in statically typed languages. In my experience, the dynamic programming languages tend to attract the cowboy coders who don't understand why other (future) developers need more complete documentation or why specs are important and have no care to see that those things are done.
- Guid_NewGuid 4y agoApologies for the delay in a reply. I think this has been a constructive discussion certainly for how I think about things. > Interfaces don't change under microservices. Communication by contract enshrines a contract. You must ensure that your API does not break legacy users no matter what changes you want to make going forward. You have committed to behaviour forevermore once you submit the contract to other teams. I think this entails a couple of things. Firstly, it's a trade-off. If we discover some incorrect assumption is baked in to both sides of an interface we're kind of stuck and have a hard time with the migration path going forward. This isn't unsolvable and paths exist to correct it, but they're substantially harder than just updating both parts in the same commit. It moves coordination overhead as a trade-off. Secondly, what I think actually happens is that most companies using microservices aren't this disciplined and just end up bodging or implicitly coupling services. Probably the pattern I'm talking about is "distributed monolith". Not the good kind where you just scale out your monolith but where you drink the microservices kool-aid and create "microservices" by adding network boundaries at random. This is the real-world application of microservices I have seen where I've seen it. I don't doubt some people can use it correctly with proper rigour. But my theory is the pattern took hold because using "distributed monolith" (appears to help / ) helps tame the complexity of a dynamic monolith. I find it incredibly hard to believe the niche pattern of microservices done correctly would have become so popularized otherwise. > You find little value in writing a specification for your work or you find little value in automatic validation that the program works according to your spec? I find little value in providing that specification through the TDD approach or associated ceremony. I prefer as few tests as possible at as high a level as possible with as few mocks as possible. I'll take a single test that takes 15 seconds to run over 1000 tests running in milliseconds. Again for me this is a question of "what popularized this pattern?". I think there's a lot of healthy debate to be had about how much testing is needed. I think TDD appeared to provide the kind of guarantees that are really helpful in a dynamic language and gained a lot of advocates that way. When I had to write some (type hint free) Python I naturally defaulted to writing TDD since keeping a large system in your head and error free is basically impossible without an exhaustive suite of tests. It's an approach that works very well in one context that applied to other contexts unquestioningly delivers a lot of pain. Maybe you're lucky to have only worked with very deliberate and rigorous engineers in your career. Outside the top tier we're working with architecture astronauts and people who jump on whatever hype cycle happens to be passing which explains my anger with these concepts.