Skip to main content

Autonomous microservices don't share data. Period.

About this video

This session was presented at NDC Porto 2023.

Are you building a monolith using microservices? If a small change in business logic or in data requires you to modify code in more than one service, you probably are. Isn’t it unbelievable that even using the latest technologies like .NET Core, containers, serverless and more doesn’t help? In this session we’ll discuss why technology doesn’t change coupling. We’ll have a different look at microservices. One where they’ll truly be autonomous and not share data at all.

đź”—Transcription

00:05 Dennis van der Stelt
All right. My name is Dennis van der Stelt, and if you're all the way in the back, this is what I look like, but it's not that interesting. Neither is it that I'm working for a particular software, the company that makes end NServiceBus because we're here for microservices, and we want to see what microservices, how they can help us and how we build microservices and maybe via Docker and via Kubernetes and containers in general because who doesn't love containers? And this almost approves with anyone that has OCD. I don't because I think this is beautiful. It's evenly distributed, and the fact that not every color is distributed correctly, I don't care. This ship, the Rena looks like fabulous to me. I would've loved to work on the ship. And who doesn't like containers, right? Well, even containers can sometimes mess up. Containers isn't always the solution, but we're always looking for a solution.
01:08 Dennis van der Stelt
And why is it that we're always looking for a solution? It's because we want to build a system with the perfect architecture and we're always looking for architectural solutions and styles. Why are we, even if development... Software development is quite new, right? It doesn't exist for eons or whatever, but it's been existing for quite a few decades and still we're looking for the perfect architecture. And one of the reasons, I think, is always because of the maintenance cost. We built this system that initially looks beautiful, but eventually there's always, it grows larger and larger, and there's a lot of maintenance cost. And that doesn't mean that it costs a lot of money to maintain a system. The problem is that there's this huge thing that's historically been built over time where initially we thought we'd had the perfect architecture but it didn't really work.
02:08 Dennis van der Stelt
And we can try Docker, and we can try serverless Azure functions and AWS Lambdas, but it doesn't really help. And now, we have microservices, and let's see if that might help us build a better architecture or build a better system that's better maintainable. But first, I always like to go a few steps back and see history and how we got here and how we got to be introduced to microservices. And my history starts around here. I don't know who knows what kind of computer this is? And I see someone. Yeah, you know it, but you don't like it.
02:50 Dennis van der Stelt
Oh, for those who don't know, this is a Commodore 64. I didn't own a Commodore 64, but where I come from, it's the better known system because this was my system. I don't know if anyone's familiar with that. This was my system. The first one I owned was an MSX One. And you can see the black thing on top of it. If you open it up, you could insert a cartridge and then start playing games like this one. This was the first game I played on my MSX. I played it connected with a wired joystick. And when I stood up, I always took a few steps back as if I had to for in the game, and I pulled my MSX off the table. Whatever. Anyway, this was the game. This was what the cartridge looked like. And at some point, I decided to see what happens if I started up the computer without the cartridge.
03:50 Dennis van der Stelt
So, I took it out, and I was presented with this and a nice book, and I learned to do print Hello World and go to 10 and this was the end result. And I was like, "Wow, this was awesome." And I was programming MSX BASIC. It was around the year that these movies were released. Can anyone guess which year this was? I always hear '84. I don't know why, as if there's some magic on screen that makes everyone say it's '84, but it's actually '85. So, that was your second guess. But yeah, '85. And this was what I looked like back in '85 when I was already programming, and I loved it. What I didn't know was that I was programming in procedural, right with 10, 20, 30 and gotos, go-sups all over the place. I was programming in basic, but Fortran and COBOL were similar types of languages.
04:48 Dennis van der Stelt
And to me, I was in heaven, unicorns, rainbows and everything. And I wrote the best code ever. The thing is the more lines of code that I wrote, what I didn't know was I started writing spaghetti code, right? When I was that young, I had no idea what spaghetti code was. And I also didn't know that someone said the goto statement was considered harmful. The person who initially coined this, he came from my hometown, Rotterdam, and he was Edsger Dukstra. I don't know if you know him, but he said we should all do structured programming. So, early '70s, I wasn't even born yet, we got if statements, wild loops, functions. And when people started doing that, everything was rainbows and unicorns again until some people thought, "We can still do better." So, in '80s, around the '80s, we got object oriented programming and lots of stuff like classes and polymorphism and inheritance.
05:52 Dennis van der Stelt
The most important thing, I think, that was introduced with OO, object oriented programming, was encapsulation, right? We were, for the first time, really looking how we could get high cohesion and low coupling. So, we built beautiful systems with classes and objects, and I don't know what else. And we had lots of classes calling other classes. And this introduced us to something new, which was if we changed something somewhere in our code, even though we thought that we had proper encapsulation, somewhere elsewhere that we didn't even touch suddenly broke, right? So, apparently there were still weak links to all the code that we didn't expect to break, and we wanted encapsulation, but we ended up with procedural code again, even though we thought we were doing object oriented programming. So, we still created spaghetti code, and all the coupling was weighing us down, and all the dependencies were breaking our system over and over again.
07:00 Dennis van der Stelt
And then, the '90s arrived, and we got something component object model and Don Box became famous for it. He wrote a book on it, and he did a lot of stuff with it. And now, we didn't have classes that called everywhere. Well, we still had them, but we also had components, and we thought we could componentize everything. I don't know if anyone remembers layered architecture, something we were introduced to. It was basically something like this. We had several layers, and always you had to go from the top to the bottom. Now, you could say that you always end up with presentation and business and data layer, but these were actually in our code. So, we had components inside our layers, and those were calling each other all the time, etc, etc. And I was introduced to this type of architecture, and I got very annoyed by the fact that I had to go through all the layers over and over again because most of the time it didn't really make sense.
08:03 Dennis van der Stelt
So, we sometimes skipped the service layer, or back then we called it the process layer, but we didn't dare call, sorry, skip the business layer because we thought that's basically a sin you can never do. Even if we build a website, and we had this login thingy where I had to retrieve someone's username, we had to go through all those layers. These days, I'm less of actually introducing all the layers separately in my code as components or tiers or whatever that I had to go through, so these days, I try to call my database as soon as possible, but back in the day when I was introduced into layers, and I wasn't this age anymore, but I can't find a more recent picture, and I kind of like this one. I was asking the architect, "Why do we have these layers? How do you design or come up with an architecture?" And he said, "You have to align the business and the business needs to your software architecture."
09:10 Dennis van der Stelt
However, no matter what project I was on, I always ended up with these layers. So, I really questioned what's the benefit of all those layers. And they were talking about separations of concern, and I don't know what else. I wasn't convinced. And then, we got web services and service-oriented architecture around the year 2000. And I was extremely enthusiastic because this was going to solve all my problems. I also already mentioned Don Box writing books about COM. Do you know which framework he released after starting over three times again within Microsoft? Best framework ever.
09:56 Dennis van der Stelt
We worked with WCF, Windows Communication Foundation. Yeah, quite a lot. Who's still working with Windows Communication Foundation? Wow. Nice. Anyway, with Windows Communication Foundation, we got SOAP, XML and XSDs. What's not to love? And even better, we got the WS* specification, or as some people lovingly called it the WS dev star. But remember, this was in a time where we just didn't know better. We were just introduced into it. And if I can go back to the future, back to 1985 when I was this young boy, I would tell myself, "Don't get an SOA," which if you're Dutch is kind of weird because it translates to STD. Whatever.
10:42 Dennis van der Stelt
Anyway, the thing was, at the same time that we were trying to introduce service-oriented architecture into our systems and everything, there were other people trying to solve a different problem. By then, companies grew larger or started automating and digitizing more and more stuff and all these systems needed to talk to each other, and that was a lot of work. So, people were trying to solve system integration, and this was the rise of the enterprise NServiceBus or better known as BizTalk Server, IBM WebSphere, et cetera. So, they had this solution to make sure that all these things could talk to each other. And there were some, maybe architects, I don't know. And they thought, "Well, we're doing service-oriented architecture. There's this thing that they invented, which is called web services and an enterprise NServiceBus. There's literally servers in everything. This must mean something."
11:46 Dennis van der Stelt
So, we took the web services, and we shaped it to a form that we could implement web services literally everywhere. However, that didn't really solve the maintenance nightmare, and it introduced a ton of other problems. If you've worked with WCF, and a lot of you have, then you probably know which kind of problems. But anyway, we decided that this was not a solution to our problems.
12:15 Dennis van der Stelt
And Grady Booch, the father of UML, he basically had this all figured out earlier than a lot of other people. He said this about SOA, and he concluded it with, "What a rubbish." So, probably he was being sarcastic.
12:30 Dennis van der Stelt
Anyway, the thing that we did with web services is we got the same thing with the same kinds of blocks except now they were all out of process. So, we started doing network calls. Even if it's on the same computer, we had to serialize to XML, and I don't know what else. And we had web services calling web services. We introduced a ton of latency, and that was part of the problems.
12:54 Dennis van der Stelt
Another thing that SOA was classified as was a reuse. You could build this business component and then reuse it in some other system. And this sounded really promising. I don't know how many people did that here with WCF, but the only example that I ever found was look up for postal codes. So, that didn't really work well.
13:18 Dennis van der Stelt
There was one thing though, with service-oriented architecture, and that was the boundaries. I don't know if anyone remembers the four tenets from Don Box. One of them was you shouldn't cross server's boundaries. And back in the day, I had no idea what he was talking about. I thought I was, but I wasn't. And the reason you can't cross boundaries was because we were looking for the encapsulation within our code. I'll get back to this later.
13:48 Dennis van der Stelt
Anyway, I think another thing was that we started out with classes for the encapsulation. We moved over to bigger and bigger things and ended up with services, whatever a service is. I think we were looking for the right size of our services. Maybe we found it with microservices. An example, if we're going back into history, where I messed up with the service-oriented architecture, I needed to build an application where users could consult and add data or modify data, which is probably every system in the world, but mine was literally so small. There were users and a bunch of data.
14:30 Dennis van der Stelt
So, I started thinking, "Okay, so I want to do service-oriented architecture." And Layla Porter already mentioned it this morning, if you went to her session is like, "So, you want to do microservices?" And her question was like, "Are you sure?" And then, the next question was, "Are you sure you're really sure?"
14:50 Dennis van der Stelt
I should have asked that question to myself, as well. I couldn't find the right services. So, I went to the architect again, and he said, "Well, you have users and data. I can't find another way. Let's split them up this way," which was a really, really bad idea because the user interface needed to request the data. And at some point there were some users that could only see a small part of the data or modify certain amounts of data. So, I went back to the architect again and said, "This isn't working. And surely I can't have the user interface decide where my data is coming from because that's supposed to be in another layer, logical layer, whatever."
15:34 Dennis van der Stelt
So we came up with this. We decided to add another layer because that's always a good idea. Right? Geek&Poke already had this figured out quite sometime before I did apparently, and I still implemented it this way, and this is what the developers did to me because they had to come up with all kinds of tricks to combine the data. So, I should have asked myself this question. I was definitely doing it wrong, and it definitely hurt it.
16:06 Dennis van der Stelt
And then, microservices came along, and obviously this was the solution to all our problems. First of all, there was no SOAP and XML and XSD anymore. That was already a huge win because the code was fine, it was the XML that was the problem. The thing is we now have REST and JSON and Swagger and Swagger Client and GraphQL, and I don't know what else. And this was so much better. And together with Docker, which was also introduced and Kubernetes, everything was a blast. And we now had microservices calling microservices.
16:46 Dennis van der Stelt
And this is what Layla Porter also mentioned this morning. We ended up with distributed monoliths most of the time just introducing lots and lots of latency. And Simon Brown, he also regularly speaks at conferences. He said, "If you can't build monoliths right, what makes you think microservices are the answer?" And a great, great example is on Stack Overflow. There was a person who asked the question, "I built my entire system according to microservices architecture." And his question was, "What did I do wrong? Because every single time that one user does one request on my system, I end up with 30,000 HTTP requests."
17:33 Dennis van der Stelt
And the first comment was the best. Was something like, "I don't know that much about microservices, but 30K seems a tad too much." Anyway, it was unlikely that he could be helped anymore. The thing is, he ended with something like this probably, and I don't know if anyone recognizes this animation. It's being used by a company that is extremely successful. Sorry? Yes. Netflix. They make more money than I do. So-
18:14 Audience
He worked from there.
18:18 Dennis van der Stelt
But they are highly successful. The thing is, we all want to be as successful as Netflix. However, we don't have their resources, most of us, and even more importantly, most of us are in a very different business domain.
18:40 Dennis van der Stelt
Next to that, we have almost no idea how they actually set up the microservices, what they're using it for, if it's an architecture they use all over the place or only in certain places, why they are using it in certain places.
18:57 Dennis van der Stelt
So, we still don't know that much, only that microservices is the answer to all our problems. But I hope by now you've seen a pattern, which I'll come back to, as well. But we need some guidance still, and that's why we're here at conferences, to make sure that the coupling isn't that bad anymore. And the thing is, I don't think technology is the answer. So, before I'll start looking into what is the answer, let's debunk some of the myths on microservices.
19:34 Dennis van der Stelt
This was one of the best one. You couldn't write more than an X number of lines of code. Luckily, that was dropped quite fast because it didn't make sense. If you wanted to do some data access and use maybe, I don't know what for it and security and what else, oftentimes we could build a small function, but there was a lot of codes supporting that function. So, we dropped this fairly quickly. Another thing is XML versus JSON. We dropped the XML because JSON is much better, and you can clearly see why JSON is much better.
20:17 Dennis van der Stelt
Maybe someone can explain it because I didn't really get it why JSON is so much better. I know it's less verbose. And that's apparently something that people say is a huge deal breaker. I know about the fallacies of distributed computing, and that bandwidth isn't infinite. I have a book. So, if at the end of the talk you approach me and have a question, you can take away a book because I only have a handful left over from a previous conference. It's more readable, but I don't read JSON that often. But XML, however, had some great features like XSD, XPath, and Xquery, XSLTs. Who didn't create their web block from XML? Anyway, it's funny because JSON now gets more and more and more features like all these tools, and maybe it's comparing apples to oranges, but more like these kinds of apples. I mean the technologies aren't exactly the same.
21:26 Dennis van der Stelt
There are definitely improvements that are being made, but who said those improvements couldn't be made on top of XML, for example? And I'm not saying JSON at bat, right? So, you can sleep well if you're using JSON all over the place instead of XML. The best part is if you are a developer in the browser, for example, using JavaScript or Angular or React, it's great for communication because the browser understands JSON and JavaScript, and oftentimes we get our data from the database and then map it from a relational model to domain objects and then from domain objects to data transfer objects, then to the view model and from the view model to JSON. And then finally, there's no more mapping needed because the browser understands JSON. So, go JSON. Maybe that's a solution to our problems. However, it doesn't improve our architecture. So, JSON isn't bad, and it's definitely a good thing, but everyone was talking about microservices saying, "I love it that we now can use JSON because it's so much better."
22:36 Dennis van der Stelt
And these are just small examples of what people said about microservices, but I think we haven't spoken about the elephant in the room with microservices, and that's this thing. The question that the person on Stack Overflow wrote, and that's about RPC or remote procedure calls. In other words, normally we call a method, and it's extremely fast because it's in process. I don't know if you have a task delay of 40 seconds in your methods, then it doesn't sound that great anymore. But RPC, Remote Procedure Calls, make it a lot worse. So, why is it bad to call another service? One of the reasons is as long as you're waiting for a service, you're basically bound to it. You can't continue work, and there's async/await and everything, but you are dependent on the other service to do something for you, and you have to wait for it. And having dependencies is definitely not a good thing. I hope you know Memphis Depay. He didn't really say this, but whatever. Anyway, you lose autonomy when you start calling other services.
23:48 Dennis van der Stelt
So, let's look at an example, right? Imagine you want to buy some liquor from a liquor store, and you have your wallet with you. And I don't know if you've seen this movie with McLovin in it. Normally, when I pay at the liquor store, I myself decide how I want to pay, if I want to use my credit card or pay in cash or maybe a combination even. McLovin didn't make the decision. He handed over his wallet, and he got into a lot of problems. As you can see, he's hit in the face. Go see the movie if you want to know. I can't even remember the name. Superbad, yes. Excellent. Anyway, if you hand over not your money but your business data, then you no longer have the authority over your own data.
24:43 Dennis van der Stelt
So. Others start making decisions on your data, which is yours. And that's when you lose autonomy and you don't have proper encapsulation. And that's when a lot of these dependency issues start existing. Because for example, if you have 300 microservices and you shared with, I don't know how many of them, your data, and the data turns out to be incorrect, you don't know who copied your incorrect data or which services queried your data. But in the meantime, invoices have been calculated in some other part of the system. Payments have been processed. Maybe a customer got, because of all those payments, a preferred status based on your incorrect data. So, you are not autonomously responsible anymore for your data. And if everyone can just query your business data and make decisions on it, at some point in time, this is how you'll be looking at your architecture.
25:48 Dennis van der Stelt
And I'm not, again, I'm not saying throw away RPC for something else because RPC has its place. I don't know how you would call your data storage without RPC. Most well known is probably SQL Server to most of us or Oracle. You call your database using RPC, and there are definitely other places. But remember it's those things calling other things, that's where the coupling is happening and weighing us down. So, RPC definitely doesn't improve the coupling and cohesion. Now, we were talking about microservices, and deployment is also a good one. I sometimes read the most amazing things. I had to read this sentence a couple of times because I didn't think I fully understood it when I read it the first time. But apparently, throwing the word agile and operational, and I don't know what else, makes something better, but I don't think that deploying 300 microservices makes things better over deploying a single monolith because in the past we could just write one schema update and also make changes to our schema and to our database while deploying our system.
27:13 Dennis van der Stelt
And right now, we have to take into account versioning over all those services. And I don't know what else. I know that if all our microservices are running somewhere in Docker containers, in Kubernetes clusters, we can just take away one and replace it with another, much easier than deploying our entire monolith. But don't forget that even with a small number of lines of code in our microservice, it's still, if we replace it with a better version, a total rewrite and those things introduce bugs because we don't know what happened everywhere with our microservices. There's coupling everywhere. We can get into a lot of problems there. I know who does love microservices, and that's the operations department because now they have to deploy our microservices and maintain a massive infrastructure and monitor everything. But instead of doing it on one server or a couple of servers, they have to do it 300 times over, so they get the best tools ever.
28:25 Dennis van der Stelt
There are definitely nice things about Docker and Kubernetes. For example, talking about deployment, it's isolated. Kubernetes make it easy or whatever solution you're using makes it easy to scale. It is multi-cloud, so you can pick something up and move it somewhere else to another region, to another data center, to whatever. If it works on your machine, you can just deploy it somewhere in Azure or whatever. Docker, it improves the encapsulation and isolation of your processes, but it does not improve the runtime architecture of your system. You can design or draw a lot of boxes and say, "Look how loosely coupled everything is," but in runtime, you get something like this, and you might end up the same way that other person on Stack Overflow was ending up, drowning in HTTP requests. So, there's still a lot of coupling and still a lot of dependencies and what is it? Sprinkling some Docker magic over it, even though Docker is awesome for its reasons, it doesn't improve our architecture.
29:48 Dennis van der Stelt
So, let's talk about what is working and how we can achieve high cohesion and low coupling. First of all, there's no golden hammer, definitely not in technologies. I think the answer is right here. It's with the audience in NDC. I think we have to take a few steps back and look better at those service boundaries that I was talking about earlier and finding the right encapsulation. It's all about high coupling and low cohesion and whether or not these cloudy things are layers or components or web services or whatever. I think we've been looking at the boundaries incorrectly and we've been putting things together that aren't highly cohesive, and that's why we have to call each other and share data because otherwise our systems won't work. What we actually want is this, where we put all the things that belong together inside some service and achieve low coupling and high cohesion.
31:06 Dennis van der Stelt
And it starts when we listen to our business analysts or product owners or whatever, we've always been told to listen to the nouns and the verbs they've been saying, nouns like customer and product and order, and those become our entities in our system. And then, we think of the verbs. For example, a customer orders a product or an order shipped to a customer or a customer received the discount. And when we look at those, that's when we start introducing coupling because we have to get data all over the place to make those verbs work.
31:47 Dennis van der Stelt
That's how we've always been doing it. And architects also look at this, right? They look at it with this helicopter view, and they look at the nouns and the verbs. Maybe they don't tell you that, but they start drawing boxes, and then they hand it over to a developer, and they have to fill in the blanks. And the blanks are with our order, for example, our attributes. Every order has a customer. It has one or more products. Those products have prices. There's a discount possibly and a shipping status. And once the shipping status is done, then we know our order is completed.
32:29 Dennis van der Stelt
For example, a product has prices, but if prices changes, we can't have the prices change inside our order and so on and so on. All of that has to be in it, and I think we need to look way more closely at those attributes, and we need to ask ourselves if they have to be in the same transaction or share the same consistency boundary. That's that word again, boundary. For example, discount and product info. What we can do is look at the consistent requirements and state it as a requirement and maybe a really stupid one. Like if a customer has a specific discount, they cannot order purple product, sorry, some kind of product or whatever, and your product owner or business analyst will tell you, "What? Are you insane?" And that's when we found our boundaries. We have found something that doesn't share the same high consistency as another thing.
33:31 Dennis van der Stelt
So basically, the discount and product info do not belong together. They don't belong inside a single clause or whatever that's called an order. They're not related. They don't share the same transaction. Let's look at another example. Price and discount. We can state it as a requirement again. If a product is on sale and there's like a 25% discount, but the customer is a preferred customer and they get 10% discount by default. Should they still get the customer discount if the product is already on discount? Probably not. So, they share the same consistency boundary, and they share the same little cloud thingy, whatever it is. I just thought the image was nice, and I can't help it that they were clouds, but whatever. They are things that belong together. So, you can imagine that the top left one is, for example, something called the customer. It shares the first name and last name.
34:36 Dennis van der Stelt
The other one is a catalog item that shares some stuff. And then, we have to look, for example, at the price and a discount. They could go together, and I skipped ahead. There could be other entities like a prospect or whatever. This could theoretically be a sales service. This could maybe be marketing or catalog service or whatever.
35:01 Dennis van der Stelt
However, this thing, there's a customer status and a product discount because we want to make decisions on those two attributes, with lack of a better word, if we want to calculate the discount for an order. So, they have to be together. But what is this thing called? I have no idea. And what I've experienced is if you start giving them a name immediately, then you make assumptions on what should be in there. So, let's just call it a thing for now.
35:31 Dennis van der Stelt
Another thing is order status and shipping status, right? If the shipping status could be completed, but in Europe customers have like 15 to 30 days to return an item. So, shipping could have been completed, but the order isn't completed. And for the order to decide if it's completed or not, those things need to be together, and that's how you start splitting up everything.
36:01 Dennis van der Stelt
So, we still need to introduce some coupling because otherwise without any coupling, there are just things all over the place that can't make up a system, and we need to find the least volatile thing, the thing that hardly ever changes if it at all ever changes, and try to couple the things from the previous slide with this least volatile thing. And the least volatile thing in our system are most of the time identifiers. And we've known this from our databases. So, if we have our sales thing, we have a customer ID, and our marketing or products thingy could be a catalog item ID. And the bottom thing, where we calculate the order discount, there we have a customer status and a discount based on those identifiers. They know nothing about those objects or entities or whatever they are, insights, those other things. But they can still do their job based on those two identifiers.
37:12 Dennis van der Stelt
Now, this changes how we traditionally define our boundaries and whatever from what we've learned on school or university or whatever. And finding these attributes that share this boundary that should be within the same boundary, it also takes time. And this is often a problem because developers are waiting like, "I've heard the features. I know how to build it. Let me just get to it." But the architect is taking a decision, and it takes time, and it is a decision to towards the right direction because we should make sure that we don't end up with an unmaintainable nightmare again before it's too late. There's a room to shift somewhat in a different direction, but 180 degrees is extremely hard. So, don't start playing with technology again too early because then we'll end up with spaghetti code again. But once we have these highly cohesive things inside a business consistency boundary, you'll notice that the boundaries are really strong, and they hardly ever need to talk to each other and will end up with logical services. And they communicate less because why would code that's dealing with prices and discounts need to talk to a customer and their phone number?
38:49 Dennis van der Stelt
Those services don't need to share any data at all because they can perfectly do the work they need to do without the other. And why would code dealing with delivery for example, needs to know the price of the thing that it needs to deliver, right? It shouldn't cross those boundaries. Now, if we look at our monolith, this is our traditional monolith with a user interface and business logic and data storage, and those logical layers are always there, right? Instead, what we always had was that every layer was responsible for basically everything. And now, with these high consistency boundaries and everything, we end up with more vertical pillars. And if we take a look at one of those vertical pillars and we break it down, we again see our traditional logical layers, user interface, business layer, and data layer, but they contain literally everything from micro views to micro view models to microcontrollers to, I don't know, micro business logic thingies and whatever.
40:07 Dennis van der Stelt
But each service is responsible for everything from data to user interface. But then, how do we present against an interface, a unified interface that a user can understand. That's through a composite UI where we have, for example, in this mobile app or on a website or even an invoice or an email, we get the data we need from each service, but it's not like there's some magic thing that starts gathering data all over the place and knows where all the data is because every service owns a small part in the user interface. It's completely responsible for that. And that thing inside the user interface knows what it needs to present, knows where its own data resides, and can retrieve it. So, for example, if we have our Amazon website, again, and I simplified it a little bit, but you can imagine that the title and the image of a book comes from the product catalog.
41:15 Dennis van der Stelt
And I named the services here, but it's not necessary to give them those names. They could have on any e-commerce website, different names. And you can see here that, for example, the user reviews might come from marketing. The price might come from pricing or finance or whatever. The inventory might come from a different logical services, logical service. And that's how we build up our user interface. And you'll notice that even those micro views, they don't have to communicate with each other to make something work, right?
41:54 Dennis van der Stelt
Okay. So, we've seen lots and lots of things calling each other. And the funny thing is, I think, this is the history that I mentioned earlier on, that we started out with functions in structured programming and we now have functions again in Azure functions and AWS Lambdas, but that's something for another talk. The thing is they are calling each other with RPC all over the time.
42:21 Dennis van der Stelt
If we go back to our services, and perhaps the service oriented architecture if you haven't connected it yet, this person already who wrote a book with an unpronounceable name for me said, "We need inversion of communication and supplemental service-oriented architecture with an event-driven architecture. So, if we look at event-driven, if services can't call each other, they still have to somehow be in sync. And we'll do that using publish/subscribe, something Layla Porter also mentioned this morning, but without sharing business data because it can't cross the boundaries. That means that every event we publish is extremely small. We won't be publishing an event called order shipping address, for example, because that means that someone else might receive it. But we might have an event saying order accepted with just an order ID. And how this works is if we have two of those logical services, we can publish an order-accepted event, a business event, and the other one says, "Okay, I have my data. Apparently, the order is accepted. Now, I can invoice this order because I know everything about prices and the product prices, and I know how to calculate the order, etc. Even though I don't know the name of the product or if it's in stock, I don't care. That's not my responsibility. But I do know the price possible discounts, etc. And I do know what to do based on a single event with just an order ID." Again, because why would we communicate the address if no one's going to use it? And why would code dealing with prices and discounts need to receive data in some weird event about a customer's phone number, right? It doesn't need that data because it should be able to do everything that it needs to do based on the data that it has.
44:30 Dennis van der Stelt
Another example, the order accepted, some other service might also receive the event, prepare for example, some package or whatever. And as soon as it receives order paid with again, just an order ID, then it thinks, "Okay, I received all the events that I need. Let's ship the order. Again, I don't know the product name, I don't know the price, but what is interesting to me is the weight and the size and what kind of container to put it in." See, that's again containers. Who doesn't love containers? Anyway, "I also know shipping address because I am the technical authority of my business capability."
45:12 Dennis van der Stelt
One more thing, if we look at it again and say, "Customer became preferred," and provide some goods, for example, from a customer, my service doesn't know who made the customer preferred. It knows about a business event that's coming in. I even more importantly don't know why the customer became preferred, right? That's what I mentioned earlier. If I don't share data, someone else can't make decisions based on what's mine, but I do know that I need to ship faster or maybe use a different packaging again because of this.
45:50 Dennis van der Stelt
And never ever is this business data shared among these services, and they're finally autonomous, not like McLovin, and will end up with really hard boundaries between our services that have the proper encapsulation, and we might call them right sized services, but they are logical. So, you won't find them as a thing inside Visual Studio or JetBrains Rider or whatever you're using, right? This entire pillar, like I said, it owns user interface data, database schemas, et cetera, et cetera, business logic, so it's probably spread out over multiple projects, maybe even multiple solutions, maybe multiple Git repositories. But they are autonomous. And inside them, we have again components that process, events could make a decision, and based on that decision, publish an event. We can, inside our logical services within our boundaries, do whatever we like. We can have microservices talking to each other. Somewhere else, we could do domain driven design, maybe CQRS as an event sourcing, but there's no single solution that fits everywhere. We should use CQRS as an event sourcing where it's needed and especially technologies.
47:19 Dennis van der Stelt
Now, I'm almost done. Where do I start? What if I want to get rid of the spaghetti code, right? Layla Porter this morning showed this, and she made a big deal about owning this, so I added a copyright notice at the bottom of it. But she mentioned, and I agree with it, if you currently have a big ball of mud and you want to go to microservices, don't immediately go there because you'll end up with a distributed big bottle of mud. Try to find modules or services or logical services. And the first thing that I would do is embrace asynchronous messaging to start with the event-driven approach, but start really, really small.
48:05 Dennis van der Stelt
So, if you've built out your beautiful architecture with a customer and a product, and you've added some other stuff like Bitcoins and eBooks, and your system started growing and growing bigger and bigger into an unmaintainable nightmare, and you ended up with this, the first thing you want to do is start publishing events, and based on these events, create a very small component that is hosted somewhere completely else, maybe with its own database. I don't know. Somewhere else, you start publishing an event because that's basically a single line of code in your current monolith where you tell another component something happened, and the other component starts deciding on what should happen. And then, you can add more and more of these things within the boundary, which means that each boundary get their own database, maybe multiple databases, maybe every microservice within a boundary has their own database. I don't know. But this is how you start breaking up the big ball of mud or the spaghetti code or whatever we want to call it.
49:20 Dennis van der Stelt
And I modified this picture, but because of the blocks, I'm very bad at creating a smiley. We'll end up with multiple logical services that look happy, right? So, embrace asynchronous messaging. Another thing Layla said that I totally agree with, she was implying something else, "Don't roll your own."
49:41 Dennis van der Stelt
So, if you start with messaging, use a proper framework, and this is a random framework in particular. Anyway, I think microservices is for a lot of people that started introducing it, an attempt to reclaim the core meaning of SOA. Try to find the right size, try to find those boundaries, use publish/subscribe and an event-driven architecture, whatever that means to start publishing events, and you'll end up with autonomous services where each of these logical services is the technical authority for a specific business capability. And you'll end up with high cohesion and low coupling. Microservices is, I think, as a way done right? And I changed the title of my slide a little bit because autonomous microservices was clickbait. I still delivered on my promise to explain to you why things shouldn't share data.
50:48 Dennis van der Stelt
If you want to know more though, I created a presentation on eventual consistency that was also recorded at NDC in Oslo about eventual consistency where I demo some of this stuff.
51:02 Dennis van der Stelt
But there are more sessions, this NDC in Porto, for example. Layla has two sessions, especially the messaging part might be interesting. And William has also a really good session about some more examples, and you'll have a laugh for two or five or I don't know what else while he explains this. All sessions are really good, so I hope you'll find time to visit them.
51:31 Dennis van der Stelt
I'm Dennis van der Stelt. If you go to this link, you'll find the previous one again as well, including an offer from me that if you ever want to talk about this more outside of NDC or want to learn how to introduce messaging or event-driven architecture or whatever inside your organization and don't know where to start or want to use the experience that I have, there's an offer there to set up a conference call for free, et cetera, et cetera. And with that, I thank you for attention, and if you have questions, feel free to come up. And if you didn't notice there were 416 slides.