 So Proof Micro and FPP, this is more. My name is Sascha Odyvapolec and I'm the maintainer of the Proof Components. The Proof Components are a bunch of components for CQRS and event sourcing and PHP. And we also support a bunch of web frameworks and any other library that is using the PSR containers. And we have a great website. You can check it out and see what else is available there. But today I want to focus more on Proof Micro. And Proof Micro is for functional event source microservices. So you can do more event sourcing and less OOP, MVC, DIC, modules, bundles, and all the other stuff that distracts you from your real work that you want to do. Sorry I have to look up here because I don't see it on my screen in the notebook. So if you don't know what event sourcing is, to quote Martin Fowler here, event sourcing ensures that all application changes are stored as a sequence of events. So what does it mean? On the left side, you can see a very short event log, like to do was posted, deadline was added, marked as done, and reopened. And on the other side, you can see a more relational way of doing this, for example, in an SQL table. And the main difference here is in an SQL table, you would probably update the status column and set it to done or back to open once you have some state changes. And with event sourcing, you keep your event log. So these events are immutable. You don't change them. You don't delete them. And you have a complete history of everything that has ever happened in your system. Whereas if you're doing a more cradish application, you overwrite your state and you lost your previous state. So that's the main difference. So basically how a system works is you've got commands coming into your system. And each command can issue one or more events. And these events are then persisted into some kind of event store database. So one question that usually comes up very often is how can a query an event store effectively? Like, I want to have a list of all users who are from Singapore. Actually, within event stream, you can do this in an efficient manner. You would have to loop through all the events and check if I have something like city equals to Singapore. Then I can mark this event to loop further. And maybe there's another change later on. So querying an event stream is very inefficient. So we need to do something about it and create something new. And what helps us here is this so-called CQRS pattern. And what it actually does is you can see the best way if you look at what you're doing right now, probably, if you're doing a more cradish application. You have a model sitting on top of your database. And you have all your queries and commands coming into your system, altering the state of your model or querying this model for whatever reason you want to display. And this is basically what most people do when they are doing software. If you're doing CQRS, things are looking very different. You have a right model sitting on top of a right database. And there you send all your commands. And then you have a red model sitting on top of your red database where you do all the querying. The nice thing is that you can now scale them independently. See, for example, your right model gets slow, and you need more hardware resources. Then you can spit on more instances and make the right model faster the same way as you can increase the performance on the red side. So you can really scale them independently. And you can also have like 20 different red models for the same right model. So when your right model is like an event source system, an event source system, and you're storing your event streams, then your event store is your right model is basically only a log of all events that ever happened. And on the red side, you could use the MongoDB, MySQL, Postgres, Elasticsearch, and combine all these things together to query the stuff that you need effectively. And you also don't need to do normalization of data. You can just put all the data together that you need, and you don't need to create red models in a way that you would query usually because you don't need any joints. You don't need them anymore. And what we have missing here is the mechanism that brings the red model in sync with the right model. And this is what we call a projection, when we are doing event sourcing, gets the stream of events and processes them to generate a red model. And the nice thing here about it is, again, you can throw away your red model completely once you're unsatisfied. Maybe you started out with some SQL database, and later on you decide that maybe it's better to do MongoDB. Then you can just throw away your red model because you have your events already in place. They are immutable, they never change, so you can create a new red model very easy. So if you're interested in projections, you can check out the documentation for proof event store, and you will find lots of more information about it. So why would you want to do this? This is a pretty standard question. And imagine you have an online shop with a cart, and you have probably events, something like this, cart created, item added, another item added, and an item was removed, and then shipping information was added. So something like this maybe should look like your online shopping cart. And then there is a more structural view of an order which could look something like this. You have a purchase order, some bunch of line items, and shipping information. And next thing is, some business guy comes in and asks you, I want all the items that were removed from the shopping cart five minutes prior to checkout because maybe the user is still interested in those items and we want to do product recommendation based on this information. If you're doing a cruddish application and you overwrite your state all the time, you don't have this information. So basically what you want to do is you start writing a new feature. And well, we have now nearly October, so we start writing it, we do testing QA, maybe we get it deployed in January. And yeah, let's be conservative, we're slow. In January we have this new feature online. And if you want to look at the product recommendations, what does it tell you? We have no product recommendations. Why? Because we don't have collected any data so far. So we need to collect this data again and maybe the real product recommendation engine is working February, March, we don't know. But if you're doing event sourcing, you have all the events there in place. So I can generate this report right away for you and I can generate this report even for last year and the year before for you, even when you didn't have this question for me. So basically it's like you can add features in the past to your system. On the pro side for event sourcing, it's an append only way of storing data. So this is very, very fast. All your events are immutable and for the red models you don't need any joints if you're doing SQL queries. And you get a complete history of everything that ever happened into your system basically for free. It has a few downsides but the most downside only is that it's overkill if you're doing very simple applications. Other than that, usually CQRS and event sourcing work for most of the domains. So let's come to Proof Micro and Funkey. So Proof Micro uses Funkey and the Proof Event Store whereas Funkey is a very small library for functional programming and PHP. I know if you guys know real functional programming languages like Scala or Haskell or List, you're probably not happy with the way that you can do functional programming in PHP but it's still pretty good and I think you can do some reasonable results with it. So before I can show you what the real functional approach is that I came up with at the Proof Team is I want to show you the OO approach first so you can see a difference. So imagine you have some aggregate root. We call it to do. If you don't know what an aggregate root is, if you're not familiar with DDD terms, just think of it as an entity for now. And we have one method here, mark is done. And it's pretty simple. We just check if the state is already done. In this case, we throw an exception. We could also just return early. And if all is fine, we can record that a new event happened. The new event is then that a to do was marked as done and we give some additional information like the ID of this to do. And other than that, you're probably interested what does this record that method do. Basically it receives a domain event, increases the version of the aggregate root, puts the newly recorded in an event into a property and then it applies the event to the aggregate root. So the apply method is basically the same method structure. So you get again a domain event. And what you have inside is basically a big switch statement for all the events that you're interested in. And you do your updates on the state according to your events that come in. So if you have an event like to do was marked as done, I just update the status to done. So next thing, you need some kind of mechanism that calls these mark as done method for you. So you probably come up with some command handler like this, mark to do as done handler. In the property, you have a to do collection that you have to fill with a constructor and you have a public function invoke, which receives the mark to do as done command. Internally what you do is we just fetch the to do from the collection by its ID, then we can execute the mark as done method and save the to do back. So that's pretty simple, but as you notice maybe, the real part of this code that does actually something is the invoke method. All the rest is only boilerplate. Code that you need to write in order to make this thing work. And if you see the ratio between boilerplate and actual code, it's already like 50-50. So you have 50% boilerplate added on top of the code that you actually need to do. And it gets even worse because your application doesn't know how to use such a handler. So you come up with some factory. If you're using the I containers that have a factory-based approach, it may look something similar to like this. If you're more used to symphony, you have basically the same concept, but it's an XML configuration. So it doesn't change the fact you have to put additional boilerplate into your code in order to wire things together. And next comes a to-do controller. And the controller is pretty straight forward. And for this example, we just create the command from the request, dispatch it on the command bus, which will then route this command to the appropriate handler. And when everything works fine, we can return a empty response. So that's the OO approach, basically. And it requires you to add a lot of boilerplate on top of your code. So we want to get rid of it, and that's why we try to introduce a functional approach on how to do these things. Before I can come to this, I want to explain you the main difference here. I use an API getaway. This can be engineX, can also be traffic, which is much more powerful for this use case. But I think most of you maybe already knew engineX and how it works. So we use it for an example right now. And you have a write service written in PHP and the events that are emitted are stored to some kind of event store database. All the routing can be done by engineX, so we don't need any PHP frameworks for routing here. So this again saves us some work. So if you're doing functional programming, you need to compose a lot of things, put some functions together and create new functions out of it. And so this is the basic pipe that we are using. It has several steps and the first step is we want to handle a command. Then we want to enrich it with some metadata. For example, the IP address of the user who issued this command or the ID of the logged in user and so on. So we can enrich events with some kind of metadata. And then we want to persist it into our events store and maybe even publish it to some kind of message bus, rabbitMQ, whatever. And then we want to attempt this pipe and then attempt this either a success or a failure. And what you see here is funky code. So this is from the funky functional library for PHP. It's really awesome. If you didn't check it out, you can, I can really recommend it. It's really good. We can use this pipe now like this. We can just execute the function, put our command in there and that's it. So it's very easy. You don't need to take care of so much things and this one will handle the command. It will enrich it with any metadata you want. It will persist it and it will publish it on any message bus that you configure it. So let's do it in the real world. What we are interested here in is the handle command function, of course. The rest is basically stuff from Proof Micro, especially the persist events function. So you don't have to take care about this one, but the handle command is something that you have to write obviously. Before I can explain you what handle command does and how it looks like, let me introduce you to Gregory Young. He's the author of the original event store and a pretty famous programmer and I invited him to our issue tracker and I asked him how can we handle stuff here from event sourcing and then functional approach and this was basically his answer. A command handler is a function which receives state and command and produces events and you can see it's a little bit more than that, but you don't want to or you don't need to put, try to wrap your head around this. It looks more complicated than it really is at the end and that's why I show you now the real world example so you can see it from a practical standpoint. So we have our mark to do as done function and it receives a callable and a command. The callable when I execute it, this is the first thing that I do here in this function is I receive state and what it does internally, it will do a left fold on the history with a match function and which can produce you this current state of the application. So you can wrap your state like this and you don't have to take care about what's happening internally, that's part of Proof Micro. And after the fact, after that, you have basically the same code like we had in the command handler, except that we return here an array of events. In this case, it's just one. And of course we need an apply method again and the apply method is done to calculate states for us. We can, you receive in the current state when it's now, we just initialize it with some empty array for now and you have a bunch of messages like these are events that happened in your system that you want to handle. You can loop through them, you have your same switch statement like before and the OO approach, you update the status and then you can return the state. So that's your basic apply function. And can you see the difference already? Because we are done. So you don't need any factories, you don't need any DI containers, you don't need any command handlers, you don't need any controllers, you don't need any routers. And it's much, much less boilerplate to write so you can be more effective on your real work. So I want to talk a little bit about FPP as well. FPP is a very small library that I wrote. It's called FPP for functional PHP preprocessor but actually it's only an immutable data type generator. The name is stuck so we used it again. To show you why it's useful, imagine you have a user class with the first name and the last name and both of them are strings. So it looks fine so far. The only problem that I have with this is there's a small chance you mix up the order. So you give the last name as first argument and the first name as second argument and PHP will not complain because you gave the right type. And things will get even worse if you put more arguments inside. So now you have a bunch of strings and if you mess up the order now, my first name is maybe Singapore. So that's not something that you want so we want to have more type safety. We can add this by having value objects for everything. So a value object for first name, a value object for last name, one for address and so on. But this again leads to a much boilerplate to write. When you started with a simple string, you could just code right away. If you need now complete value objects for everything in your system, you spend a lot of time writing this boilerplate. So you want to get rid of it again and this is the FPP way of doing this. We can simply define a namespace where the stuff should be happening and you can create a new data type first name and the first name equals to a string. This is actually only a shortcut for a more longer version of the code but I think it's very powerful and you can add additional derivings inside. Deriving is, I think the closest thing that you have in PHP is a trait. So you can mix in additional features that you want to have. In this case, I want to have the equals feature to check if a first name is equal to another first name. And you can have also more complex data types as well. For example, the address. And now it's of course not a string constructor. The address has its own constructor named address and there you can reuse your street, city, zip code, country and so on. And we put some additional derivings in there to array from array and equals. Yeah, so you can imagine already what this to array from array does. You can do the same with the person and you can also generate your commands that you want to use for the system and you can even generate your domain events. So this saves you a lot of boilerplate because this is very, very short syntax. If you need more complicated examples, you can have multiple constructors as well and you can add conditions to your system. So you can check for example, if the first name is empty, you want to throw an exception with a decent error message so you can ensure that there's no invalid first name object passing around in your system. So you can generate this FPP code very simple with the FPP script and you can give the definitions file or you can give a complete directory where it should scan for FPP files. And these are the stats for the FPP code that I just showed you. That's only a couple lines of FPP but a huge amount of lines of PHP. I couldn't even put the generated PHP code until the slides because it's just too much to show you but you see the big difference and additionally, all the FPP code is like when it generates the PHP code, you're fine. So you don't need to write a bunch of unit tests additionally so you can save a lot of time. The reason why ProofMicro and FPP work so well together that's because ProofMicro uses a functional approach and functional programming comes with immutable data types and FPP can generate you these immutable data types very quickly for the PHP data to use. So what's next? You could use stuff like AMPHP or ReactPHP together with AMP, with ProofMicro to create asynchronous applications with non-blocking IO. So that's really fast then or you can combine it even with an expressive and swool and if you're doing that, you get response times for about one millisecond for a request. And what I've seen so far, this is basically the fastest thing you can get on PHP. It's really, really fast. And if you're interested in more about these whole topics, you can check out the homepage getproof.org and you can check the Professor Do Example application which is CQRS and Event Sourcing in Action. Where it has the basic to-do example that I just showed you but it's written in an OO style and not functional so it's not ProofMicro but you can get your hands dirty a little about event sourcing CQRS and projections and how all this stuff works together. And you can check out our community in the Github chat. There are about 100 people there. They are answering all the questions. I'm also there when I have time and you can ask there anything you want about DDD, about event sourcing, about CQRS. There are good people there and they are very nice and want to help you with all your questions you have. If you need some literature, I can recommend the Blue Book Domain Driven Design and of course the Red Book Implementing Domain Driven Design. Basically that's it. If you have any other questions, you can come to me anytime. Questions? Any questions? I don't know a lot about event stores, how they're used in the real world but what about metadata for these events? How much, I mean can you recreate everything from the event store? Say like if you're uploading in your shopping cart for example you might upload a picture of the item in the shopping cart. Would the actual JPEG file end up in the event store as well? You could do it, you could do it but I would recommend you to do this. And when you're handling uploaded data I would recommend store your data somewhere first. Could be on the file system wherever and then you could store only the path to the file in your event store. You would need to version it or something I suppose, because I mean they could modify that image. So you'd have to have, if you wanna be able to recreate you have to have all the versions of that particular image as well. Yeah that depends on how you handle your storage of course. If you're doing event sourcing and you want to be strict then you would deny in your system any changes or deletions of actual files. Even if this increases your storage that you need for the system just to make sure that you can recreate the original state that you're required. Okay I'm just thinking of how I would do this in the Etsy world because there's so many things that people do to their images to just slightly tweak them and everything is in the event of they crop it slightly, they can do all these things and I mean if I have to record every single event the amount of storage I would need and the amount of items in my event store would be in the billions. I mean elastic search would blow up on me I think. Yeah I've seen some event store databases that take already some terabytes. So that's not unusual. I'm just wondering how practical it is for a large busy site to do this. Yeah you don't have to do everything in event sourcing so you can't have some for example the image part of your application or the part that handles file uploads. You can do this in a more cruddish way. You probably also don't need the complete audit log of this but if you're doing an online shop for example you want the complete history of everything that ever happened in your system. For example the example with the item was removed is something in the end that can be important to your business so you don't want to mess with this and delete your state. So all the parts where you can benefit from it you can do it event sourced and say if there are some parts where it's easier or more convenient to do it in a more cruddish way then you're fine to do it. Welcome. Yeah. I have just a short comment on Rasmus's question. What you're not trying to store is the picture but the changes. So if you're cropping a thousand by thousand image to a 500 by 500 you just say what you're doing not the result of it. So you don't have to save every version of an edited image just have the changes done there. That's the idea of end sourcing not the read side not the result. No more questions. Well you can hit me up. I'm still around at the conference so you can come to me anytime and we can discuss further. Thank you very much.