Bootiful CQRS and Event Sourcing with Axon Framework

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I'm going to talk about Seacrest an event sourcing a bit in more detail than I did this morning and it will involve some live coding and I'm going to ask you to be with me on that because every time I do that every practice session is like perfect you know that when you do that on stage things happen right so if you see something say something right thanks I am going to start with a small confession well small it's a pretty big confession actually I have created some really really ugly software in the past it was horrible and I feel extremely sorry for the people that have to maintain that software these days and if it's you I'm sorry I'll buy you a beer and the the architectural pattern that it followed looks more or less like this right the the layered architecture it's a beautiful architectural principle that really helped us in the 70s and 80s strange enough it is still a dominant architectural style today right and and not just for legacy but we see the same thing in a lot of Greenfields applications and I'm not saying this is a bad architecture I'm just saying this is a bad default in the the type of software that we need to to build today I'm going to zoom into the domain model a bit here so let's imagine we have an application and we the domain model is sort of at the foundation of it right probably we have a relational model in our database that is hopefully a one-to-one mapping so that hibernate and all that cool stuff can help us get some data out of that database and then there's a service layer that contains these services and initially in a Greenfield situation everything Maps really nicely right there's this really nice order service and inventory service and everything and then there's a bit of logic sometimes in the domain model sometimes in the service layer sometimes I don't know where nowhere and then the next service also Maps quite nicely to to one of these entities and then there's that service that maps to everything and this is a very typical thing in all of the projects that I've been involved with with that architectural style that was a long time ago I quit doing that and as a side effect you get this really nice sequel queries and this is a real one this is a query somebody actually gave me so I used to do this to present about this and I had one of my own projects sequel queries that I thought was pretty obnoxious but somebody said I've got a better one but you have to promise me that they cannot read what's in the query so I thought you know who cares projectors they have it was it a thousand twenty four by seven something pixels so that leaves about four pixels per character nobody can read it and then suddenly I was doing a presentation somewhere and they had this really high definition projector and I thought oh people can read the characters and then I started to read the characters I could still not read the query so to give you a small summary this query has 22 joins in six sub queries they are looking for somebody they're hiring just in case but give me your contact details I've got an awesome job for you can do this 24/7 optimizing this query right all right so what do we do this doesn't perform obviously so what do we do we solve that performance problem and of course this is a rather exaggerated view of reality but the thing is there if you're if you look at the the solutions quote-unquote to this problem and their locations they're in the user interface they're in the service layer and they're in the data access layer they mostly involve caches right caches are not problem solvers if you have a performance problem the cache is not going to solve that performance problem if you have a well performing application a cache can improve that right but if you look at this the problem really is in the domain model and all the solutions are in the other places so even though we think we're building this high performance I mean this is the feeling you have when you start every project right you're going to do this time we're doing it right and this could be a greenfield project or a refactoring that you're planning to do you've got this in mind but you end up with this this has all the characteristics of a high performance application except for one little thing and that's the thing we don't see right but I'm pretty sure this will not go as fast through corners as the as the other car we just saw now I like analogies but let's let's go back to software right there's a term for software where the domain model is sort of causing all sorts of trouble all over in our application and it's called the big ball of mud now here's news for you it is not mud and here's the architect proudly protecting its creation now does the term coach smell start to make sense to you so of course the big ball of mud is problematic because the only thing we can really do to it is add more mud right there's all sense of structure inside is lost it's just a big gooey mass right and if you realize or if you think about it in in a lot of legacy code the only thing that can really change is add new stuff to it because understanding what's inside is all nearly impossible so as I said you know I created ugly software and I've made all these mistakes unfortunately more than once I always say I don't I don't mind making mistakes making mistakes is cool because it gives you a learning experience but making the same mistake twice that's not cool because it means you failed to learn right so I saw this pattern in in a lot of projects that I was involved in and I decided to do something about it and I started an experiment and well if you should put your code on github or at the time it was even Google code you need a name for it well action framework was not the original name it did not have the term framework in it because it was an experiment and I got an email from a company in France saying hey we thought you would like to know that we are using your framework in production that was two news items in a single sentence oh is it a framework and uh-oh production but you know there's production and there's production right I mean sometimes you have an excel sheet and two people need to work on it so you've got something in production so I thought oh cool yeah what would what do you use it for well it's a tool that we use so I thought I excel sheet it's a tool that we use to track tools used in surgery that scared the well as far as I know nobody has died because of complications caused by whatever they call the framework but that did gave me the confidence that I could use this myself in projects maybe so we call it axon framework somewhat later and I start using this was around nine years ago right so axon has been around for for a while and it was a great learning experience to do this on an open source project now the thing that axon does oops that's a bit too enthusiastic the thing that it does is it forces you or stimulates you so to say to split the command component from the query components the convent component is responsible for handling commands which are intense to change the application state and quite typically it involves business logic to make decisions is this a legal state change is this a legal thing to do and if so what are the side effects of this change on the other side we have the query side and then that is responsible for handling requests for state you have to expose the state of your application in some way and in many applications in more ways than one and now what we can do is we can create models that focus on the specific tasks that they need to do so we get more but smaller models that are focused on that specific task and thus easier to build and maintain but it would be nice somehow if you make a change to see those projections reflect that change right and we can use events for that right we see events everywhere I mean the term event-driven micro-services and I know I said it this morning myself but it it appeared a lot of times during this conference and events are a very valuable component in our applications so essentially the command model omits events to explain or to tell the rest of the components what decisions it had made now we can accommodate in different non-functional requirements in these models we can decide oh if there's a specific part of the model that needs to handle high throughput at low latency we'll put a different effort in that model as one that has a very low throughput and where we don't really care if we even get a response right so putting that all of that in a single model is going to be problematic because it's going to be very hard to isolate some of these components and optimize right as I said there's something special about these events events retain value so most of the messages like commands and query a query you lose its value as soon as you get the response a command loses value as soon as it triggered side-effects but events describe something that happened and I'm talking about domain events here so we can store these events and capture them and then later on we can do analysis we can find out what happened a lot of our customers use this for support a customer calls we've I don't understand why the application is behaving like this or that well let's check they look at the event source and they see everything that happened eyes because you press that specific button or you closed something and therefore etc and it's remarkable how humans tend to forget their mistakes but as soon as you remind them they'll understand and know but just omitting and storing these events is not enough that is not event sourcing that is maybe an event-driven application or an event-driven architecture event sourcing is using those events as your sole source of truth the only state you have is the events and maybe some other states temporarily stored derived from those events for performance reasons right so imagine we use state storage and we we have an order and it hasn't identified in a certain States so the only thing we can now see is that somebody bought a nice chair and returned it that's the only thing we have if we had event sourced that order instead we would store everything that happened to that order over time and now we can see it was created two chairs were added one was removed the order was confirmed it wasn't shipped and then the user cancelled his order and sent the chair back now I'm not a retail expert but this might be a sign of a certain pattern right there might be something about people adding a lot of items to their shopping carts and then reducing it to 1 and then ordering that might give you an indication that hey maybe that person doesn't know if he really likes that chair he wants to see it in in real life not sure what you can do about it but that's not my problem now the whole axon way of developing software has led us to see that monoliths aren't really a bad thing sometimes especially in the context of microservices monoliths are like goo they're the devil do not build a monolith you will regret it but the monolith is not really a bad thing the big ball of mud is a bad thing and the problem is many monoliths tend to evolve into a big ball of a ball of mud because of how we maintain it but the monolith in itself is not bad I mean yes it's heavy its be harder to deploy but at least it doesn't smell there was a very interesting observation by a by Martin Fowler that almost all of the successful microservices story started with a monolith that was then taken apart and deployed as micro-services whereas most of the unsuccessful stories started with a from scratch approach to micro services and that's because micro services are really hard and they're not only hard because of technology right we need to have a certain level of maturity in our organization to be able to deal with micro services but it's also a question of where do you cut the functionality which functionality belongs to one micro service and which one belongs to another a friend of mine has a very nice approach to micro services and he calls it a noun driven design it's very easy you take your specification document and every now new C is the service and of course that's something you do not do unfortunately it is done a lot and if you look at those failing projects that is often what happens we end up with order servers inventory service customer service etc etc or everything related to an order goes to that yeah but what if we ship an order we've got shipment service and order service well fifty-fifty we roll the dice you will see so you end up with basically a distributed monolith so we believe in an evolutionary approach where instead of going directly to micro services and probably ending up with a distributed big ball of mud deployment we suggest a slightly different ropes build yourself a structured monolith evolve that into micro services by extracting components as as you move along you can extract more and more and maybe even go service all the way not caring how many instances you have running at all and we achieve that by location transparency and in Axum there are three places where that location transparency is sort of safeguarded thread is because of explicit messaging between components we use the command bus query bus and even bus to dispatch the the command queries and events messages between components that allows us to basically build an action based application scale it out and now we need to send to have something in between and last week we announced the the axon server which is which we are going to open source very soon there's a bit of work involved in that which sits in between and it doesn't only transport messages but it can also store these events for you for later use and that allows us to very dynamically evolve the application and even skill if you want to but I can talk about it but I can also show it now we only have a few minutes left so bear with me this has to be easy otherwise I'm not going to make it so let's have a look at the the application here can you read this in the back kind of ok oh I'll switch to presentation mode in a second so here's my bike aggregate so an aggregate is a consistent unit in the command model right it makes sure that all the decisions made by this bike they are atomic decisions all the state changes are atomic in this part now there's a little to do here and let's do that let's implement the right bike rent bike commands handler oops rinse bike command done accident the only thing you need to do for a command I let's create a method that accepts the type of message you want to handle annotate it with add command Handler and there you go now we need to make a decision ok we're going to rent this bike the aggregate represents a single bike that we can rent out and then return we need to make sure that the bike is available for rent otherwise we cannot rent it out so I'm going to add a little assertion this is just the spring assert we assert that it's available and we say cannot rent out our bike already rented out something like that so we checked the current state what that is the decision we need to make and now the next step is ok we need to decide on the side effects what is the side effect of this method or the side effect is that the bike was rented out right so in action we do apply new bike rented events and we mentioned the bike that was rented out now this apply method makes sure that the event sourcing handlers are invoked and this is very important when using event sourcing you need to split the decision-making from the state changes right because the only thing we have are the decisions that we have made in the past and we do not want to validate those decisions if rules change all too bad it happened in the past right so better act accordingly so when a bike is rented out we say it's not available when the bike is returned it is available again I do have another to do now when that event is published we need to update our view model and I have a extremely complex database implementation here called a concurrent hash map and it does work it doesn't really scale but you know so I'm going to create event handler for the bike provisioned events and I'm going so as soon as the bike is provisioned I'm going to add it to our database and there's a very nice sequel language called put and we add a new bike status like any event dot get location and it is available for rent all right now what can possibly go wrong if we just run this okay what's wrong here let's run this application and see what happens I love it just put it there if you know it's wrong all right let's see what happens can I so I've got my some-some postman oh dear where's my that's a provisional bike so that's a provisional bike in in Washington DC and as soon as I do that I got a UUID and then I can rent out the bike by doing an empty post request to that URL state is 200 and if I now do a bike overview I should be able to see that we have a bike that is not available in Washington DC right because we've rented it out now this this view model one of the things action allows you to do is create subscription queries in it it allows you to stay up to date on the on the state of your request so I can now take this and now we see here there is a all transit large in it there is a bike in Washington not available so let's return that bike that's returned the bike and we're returning it in Chicago I hope this is not a bicycle because that's a hell of a ride here we go 200 and here we go there's an update here so we can get automatic updates right so that's the type of query that we call subscription query and it sort of keep me up to date on the state of some objects and you get to decide what what the domain model you want to use for the initial results the current state as well as every update you want to send send later now this is really nice but this is a monolith right so let's stop this application and let's make this I'm going to switch to normal view if you don't mind let's move this to another module so I'm going if we have created a few empty springboard applications and I'm going to why don't we scale it all the way right away and create query component as well all right so now we start the bike rental application and if I start sending commands it's going to fail because there's no command handler anymore my bike aggregate all the command Haller methods that we have they're gone so I'll start that one up and start the query components as well come on all right so let's provision another bike in New York and as you can see it still works right we've moved so I'm doing my request still to the original application but my command handler is now somewhere else and I've got axonal server running in the background and it knows about these application it knows that hey but there's a command handler there so if that command is being sent I need to send it to that specific instance because it told me I've got that command Handler and we could still rent out the bike whoops all right that works and we can return it so where shall we return it there we go we're all bikes end up eventually I guess so this still works so we've we've killed our application we've we've created these microservices and they're truly micro because there's one while two classes one spring boot class and one accident class in them and and that's all we need and we can see this in action server we can see an overview of all the components that are running so we can see we have the bike rental application one instance of the command application one instance of the query application we can click on them and see some details so here we can see the types of commands that this specific instance accepts so if we want to we can copy the by class even into the other class and launch them RSR either by class into the the main application and it doesn't matter it doesn't matter if you your services don't have to be homogeneous you can have these commands Highland components everywhere alike that gives you very dynamic scalability and allows you to to evolve into the micro services architecture that you would like to you to have that's about all the time I've been I've been given for this for this session if you if you have any questions I hope we can take one or two now the gentlemen in the close to the camera yep yes okay now may elaborate on location transparency so essentially in location transparency what we mean by that is the fact the two components that communicate should not care about their respective locations they shouldn't matter whether they're in the in the same deployable unit or if they're are in different VMs or different machines different data centers different planets well theoretically it should not matter right of course it does matter in the sense of you need to transport the message from A to B but that is non-functional right for the code you're right it should not matter where these components are deployed yes sir is there anything in the framework that handles versioning of events yes so this serialization of these events will attach a we call the revision because version is always a bit annoying to use because of other contexts so we call it revisions and you can if you store the events especially I mean just imagine using look if you look at code you wrote half year ago you have this slight feeling of embarrassment right imagine seeing and having to deal with an event you wrote five years ago so there's a concept of up casters that you can build to to translate the old representation or serialized form of an event into its current form so yes there's lots of mechanisms to to help you with that question yeah so the question is if you have a domain and instead of having to go to this distribute its big ball of mud how do you separate how do you go on separating them and you mentioned the term violin context that's a very important one because abundant context is setting the area in which a certain model has value and it's important to describe the exact purpose of a model so there should not be one model for the entire domain so the canonical domain model if you ever built one run now that's fine I did it so I'm it's okay they're good for for humans to discuss a domain to get an understanding they're horrible for computers so you want to be focused they're more about more on business processes that should be your focus usually the business is already organized around some ways of doing business so we should organize the software in the same way that is a short version of a very long answer otherwise you can stick around a few if you want to the last question in the back I hope yeah yeah so the action has support for sagas and basically a saga is a stateful event handler that allows you to drive a process right so you can listen to events of different components and react accordingly and organize a process of some sorts some sort of eventually consistent transaction based transactions are typically implemented using using sagas so yes there is saga support I guess that's that's all the time we have I thank you very much and enjoy the rest of the content you
Info
Channel: SpringDeveloper
Views: 26,976
Rating: undefined out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, spring cloud, axoniq, axon framework, trifork, event sourcing, eda, event driven architecture, microservices
Id: 7e5euKxHhTE
Channel Id: undefined
Length: 31min 12sec (1872 seconds)
Published: Thu Oct 04 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.