5 ms·
Nothing prevents you from having multiple microservices sharing the same codebase. That said, the "it's just like the web" model doesn't sound fantastic to me.
by mercurial 12y ago
Nothing prevents you from having multiple microservices sharing the same codebase.
That said, the "it's just like the web" model doesn't sound fantastic to me. It sounds like your app now depends on contracts which are only enforced by good practices, not by something strongly typed you can check at compile time, unless you use something like protocol buffers to generate the boilerplate.
- jacques_chester 12y agoThis is where the test-driven world, which in my experience is strongest on the dynamic language side of programming, has come back around full circle. In microservices, everything is dynamically typed. There is no single binary produced by a single compiler performing whole-program checks of consistency. Even tools like protobufs don't help when code bases drift, or someone introduces a foreign tool, or someone upgrades versions and introduces a subtle mismatch, or some doesn't know you call their service and shuts it down ... Turns out that driving from tests, and starting those tests from the outermost consumer, is a fairly well-proved way of coping with such conditions.
- nawitus 12y agoThis reminded me of the AngularJS team deciding to go with (optional) runtime type checking over compile-time checking (which is what TypeScript has done to JavaScript). Their reasoning was that you can use runtime checking for REST responses, which can be argued to somewhat reduce the need for writing tests.
- mercurial 12y ago> There is no single binary produced by a single compiler performing whole-program checks of consistency. Even tools like protobufs don't help when code bases drift, or someone introduces a foreign tool, or someone upgrades versions and introduces a subtle mismatch, or some doesn't know you call their service and shuts it down ... Static typing is not a panacea, but large codebase plus dynamic typing everywhere sounds like a recipe for disaster. No matter the amount of testing. > Turns out that driving from tests, and starting those tests from the outermost consumer, is a fairly well-proved way of coping with such conditions. You need tests no matter what. However, static typing means a much greater confidence in your codebase.
- jacques_chester 12y agoAs soon as you distribute your system, you have dynamic typing, whether you like it or not. At runtime you are inspecting incoming messages and then routing them to code. It doesn't matter what language the code is written in, it will need to route and validate the messages at runtime. The type system cannot provide compile-time assurances of behaviour, because it cannot create a single consistent binary which enforces the guarantees. Your only remaining tool is to drive code from tests and only from tests.
- mercurial 12y ago> As soon as you distribute your system, you have dynamic typing, whether you like it or not. You have serialization/deserialization issues. You can still type your messages. > At runtime you are inspecting incoming messages and then routing them to code. It doesn't matter what language the code is written in, it will need to route and validate the messages at runtime. Of course. > The type system cannot provide compile-time assurances of behaviour, because it cannot create a single consistent binary which enforces the guarantees. If you make the assumption that you deploy up-to-date binaries, then knowing at compile time that your producer and consumer use the same data structure for the messages they exchange would give me much better confidence than "it looks like the API conforms to what's written on the wiki".
- jacques_chester 12y ago> You can still type your messages. You can hope that they respect the type. For a robust distributed system, you will have to check everything at runtime. > If you make the assumption that you deploy up-to-date binaries, then knowing at compile time that your producer and consumer use the same data structure for the messages they exchange would give me much better confidence than "it looks like the API conforms to what's written on the wiki". My reading is that we agree that running code is the only source of truth, we disagree on what guarantees distribution deprives us of.
- mercurial 12y ago
- danudey 12y agoMost systems I've seen these days don't have any compile-time type checking, since they're all written in Ruby, Python, or Node.js. In the normal case of development, you tend to have a broken-out system. For a game for example: + Game code --+ User authentication classes/functionality (which accesses DB) --+ Messaging classes/functionality (which accesses DB) --+ User metrics classes/functionality (which accesses DB) In the new design you'd have this: + Game code --+ User authentication classes/functionality (which accesses REST service) --+ Messaging classes/functionality (which accesses REST service) --+ User metrics classes/functionality (which accesses REST service) In other words, in a clean design, your Game code is accessing a library which provides user Authentication functionality, one which provides Messaging functionality, and one which provides Metrics functionality. In this new design, you have exactly the same thing - a library which abstracts the details of communicating with the service, encoding data, etc. A person making changes to those libraries, which other services use, is responsible for either not making backwards-incompatible changes, or, when that isn't possible, working with other teams to ensure a clean upgrade path (or doing it themselves, if your lines are sufficiently blurred).
- mercurial 12y ago> In this new design, you have exactly the same thing - a library which abstracts the details of communicating with the service, encoding data, etc. A person making changes to those libraries, which other services use, is responsible for either not making backwards-incompatible changes, or, when that isn't possible, working with other teams to ensure a clean upgrade path (or doing it themselves, if your lines are sufficiently blurred). The new design trades a "modular but monolithic" design for complexity and brittleness, IMHO. The ability to spin up new instances of a given service on demand is interesting, but it sure sounds like reinventing Erlang without Erlang's tooling.