Transcript from the "Generating Reducers" Lesson
>> One of the things that I want to just point out, and I feel pretty good about everything that we've accomplished up to this point. We can write home about this, but what you will notice is that these events here or these methods all, find, create, update, delete.
[00:00:34] And more importantly, if we go down into the reducer, select, load, create update, these are all part of the template, they're static. And in a lot of cases, this is fine, this is a good starting point. But when we get into or the extension of this is true Domain-Driven Design, and not to go off into something that is worth an entire workshop in and unto itself.
[00:01:15] The point of Domain-Driven Design is to establish, to work with stakeholders and domain experts, to, one, understand how the domain is modeled, how it works. And to tease out a set of semantics that you can use to create more meaningful communication with the stakeholders, domain experts, etc. And so if you pick up a book on Domain-Driven Development, invariably, probably within the first two or three chapters, you are going to run up against this concept of event storming.
[00:02:02] And so what they do or how this process works is you sit down with a domain expert and you say, all right, let's talk about how this works. What are the actors in this particular domain, snd what do they do? And your idea or the idea is to uncover the events, so events storming, that these actors within this domain, that they essentially emit or participate in.
[00:02:38] So that you can start to develop essentially these user interaction flows and you can understand how a user or an actor can interact with a system. And this is very congruent with a framework like NgRx or Redux in that they are basically event-based. And so, I know, for instance, Mike Ryan, who is one of the co-creators of NgRx, he is a huge proponent of before you write NgRx, that you take the time to understand how pieces within the application interact with each other.
[00:03:28] And this is pertinent as well for understanding control flow. And so, if you look into my StackBlitz examples, one of the last ones, so this is seven, has an event storming generator. Which is, interestingly enough, the idea that we generate a schema and we generate our events. So all I'm doing is I'm starting to break these pieces out.
[00:03:58] So in this case, we have a game and you would ask yourself, what should I be able to do with this game? Well, play a game, pause a game, stop a game, reset a game, exit a game. And so this is where when you start ,and so the initial kind of this question or this request is, how does this work or what would this look like from essentially idea conception to deployment?
[00:04:33] And how I would take this is that I would say, what are our entities? And what do they do or what can we do with them? So what is the thing and what can you do with it? Well, in this case, I have a game, and I have five events.
[00:04:56] So I should be able to play a game, reset a game, exit a game. And I've isolated these events, which, bit of surprise, all I've done is just dumped them onto the page, as well as, ta-da, naming variations. And because of that, now what I can do is instead of generating a coarse-grained template, which may be sufficient, but the very next step in my opinion would be to generate action sets for each individual event.
[00:05:45] And so when I say action sets is that you have NgRx actions, in this case. And so you have the trigger event. So if you've ever used any kind of effects or Saga or something of that nature, is that you have kind of this middleware that handles your business logic and your asynchronous operations.
[00:06:09] Is that at the end of the day, the concept is fairly simple, that you have a trigger event that kicks off this asynchronous middleware piece. And then you have a completion event, which is either going to be a success or a failure event. So with every event, you have your trigger event, so I wanna play a game, playGameSuccess, playGameFailure.
[00:06:34] Same thing here, pauseGame, pauseGameSuccess, stopGame, stopGameSuccess. So you imagine I'm gonna stop the game, there's some command, great, we've stopped the game. Cuz maybe you need to actually stop it at the server, not uncommon. But from here, you have, and I'm going to open this into a new window.
[00:06:57] I should just start doing this as a default. So notice we have trigger event, completion event. In our effects, and philosophically, or I think this is really, really close to how we would do in React, that you have your trigger event, playGame, and then you have your completion event, so playGameSuccess.
[00:07:21] It sends it on down the line, playGameFailure, then it does something else. Pause trigger event, stop trigger event, reset trigger event, perfect triad. But now, once you have a completion event, that needs to go into a reducer. And so now, I am generating kind of the trappings of reducer logic, I would put the entity stuff in here, eventually, if I were to flesh this out.
[00:07:54] But now, playGamesSuccess, playGameFailure, pauseGameSuccess, pauseGameFailure. And you'll notice here, that on the failure events, I'm simply delegating out to a generic standalone failure function. And what we can do is we can take this individual or just the reducer logic, and then we can wrap this in the full generated reducer.
[00:08:27] And so let's see what this looks like in the code. So I have generateCode, which is, it takes a generator, events, entity, and config, and big surprise, events.reduce. I'm generating, I'm sending in the event, yay, and it's all the same stuff. It's turtles all the way down every single time.
[00:09:03] Now a full reducer, what I'm doing is, I'm generating the logic, and then I'm calling ReducerGenerator.generate, and I'm passing that in to be wrapped. And maybe if I thought about this a bit more, I possibly would do something. Maybe this could be improved upon. More importantly is I think this illustrates the point.
[00:09:28] And so if I go into the generators, let's look at our reducer generator. So here, reducer logic, I'm just iterating over the events and Again, this is, at this point, when you see the shape, I'm not surprised if you're like, yeah, that again, mashed potatoes for dinner again, urgh.
[00:10:00] Because if I took out, This bit right here, And this is going to get very angry for a moment. This looks like pretty much every generator that I've written, is that it takes some stuff, it does some stuff, and then it returns a string. Even here, with the build name variations, very, very conventional.
[00:10:42] And so this is really, really important, at the risk of tipping over into tedium or like, my God, we're watching the same movie over and over, is that this is a non-trivial piece of code that we've generated. But all we've done is iterate it off of some basic stuff over and over and over until we are generating an entire, well, in this case, a couple layers of state management code in NgRx.
[00:11:18] So, you're welcome, I really believe that these are money printers. And it's not uncommon for a client or somebody to reach out and say, hey, we need to build this thing. And first of all, we need to figure out what we're building and then we need to build it quick.
[00:11:40] And so the majority of our time, the real value is figuring out what we're building, and then this part is easy, relatively so. Because once you understand the domain using Domain-Driven Design techniques, and this is like a typical road mapping discovery process, that you understand, okay, these are the actors, this is how they interact.
[00:12:04] So this is the business logic and this is the UIUX that we're gonna need to accommodate this, the underlying application structure is very, very straightforward. There's even been times where we've accomplished, we've been able to generate the entire application. And it would have actually been inappropriate for political reasons to actually just trot out what we've done, until our project champion actually was in a position to show that.
[00:12:42] And so there's times where this has worked so fast, we've actually had to actually be coy about how far we were. Because for us to be like, by the way, we know it took your team nine months to do it, but it's been nine days and we're done, it's flipped to the other side.
[00:13:02] Where we've had to actually measure our delivery so that we could protect ourstakeholders. Hopefully, that answered that question about we, from conception, how we do that, is you understand the domain, the actors, the actions, and then you can start to generate that, which is where this event generator StackBlitz came from.