
Lesson Description
The "Modeling the Server Side of Plant" Lesson is part of the full, Domain Modeling for Humans and AI course featured in this preview video. Here's what you'd learn in this lesson:
Mike adds a garden bed entity to the server-side model, sets up relationships, and includes width and height. He creates and saves a bed, resolves property errors, updates routing, and handles type issues, showing the iterative process of expanding the app.
Transcript from the "Modeling the Server Side of Plant" Lesson
[00:00:00]
>> Mike North: And we've already got plant in there. So let's take a look at what plant is. It's another metadata schema wrapped thing. Ultimately it comes down to this class where we have plantingDistance already. And let's see if we can sort of work our way up from building some of these server side models and see how far we can get.
[00:00:21]
Let's get to a point where we've persisted some records and we can see we can console log a data structure out. So a lot is already here wired up for us, but we're gonna have to add some more interesting data as we choose to tackle more. So I'm gonna focus back in on server and in my entities folder.
[00:00:42]
We've got garden, and it's just got a name and description. So we're gonna need a garden bed, or we called it just a bed. Bed in this bounded context means garden bed. And then we'll call this a, well, we already have plant, but let's get garden bed implemented.
[00:01:03]
So let's use garden as a starting point. And we're just gonna say bed. And this is us just customizing the name of the database table. You don't have to do that. And we'll change the id prefix to bed. And now we want to establish a relationship. And this is ManyToOne.
[00:01:34]
And this is gonna be Garden, picking the entity here, not the thing from the types package. It's definitely assigned and it's gonna need the inverse relationship. So we'll have to set that up over here. And here we'll have OneToMany. There's bed. And this is how to get from bed to garden,
>> Mike North: And resolve the import.
[00:02:10]
Let's see. We just return the type there. We don't invoke a constructor with parentheses. Right, now we can finish the other side. So the factory is garden, not invoking it. And then this is garden and the opposite side of that relationship. So great, we've got this set up.
[00:02:40]
Let's go back to our domain model here. We need a width and a height. So let's implement that, Column.
>> Mike North: Let's keep it simple. We've got a width, we've got a height,
>> Mike North: And plant has a position. Plant has a relationship with the seed packet. Let's see if we can just get garden beds rendering on the screen.
[00:03:28]
Remember we got that workspace with zones and that's an array. Right now it's hard coded to an empty array and then each zone has placements of items within the zone. But let's see if we can just get zones rendering on the screen and then we'll loop back and get those plant tiles come through.
[00:03:49]
So to make this work, we're going to have to go to the domain service, right? That's always the source of truth for producing gardens, producing whatever the entity is. So we'll go into our services > garden-service.
>> Mike North: Great, we getAllGardens. So this will work. Once we have gardens in our database, this will return them.
[00:04:24]
We've got getGardenByID. And then we've got createExampleGarden. And I can see here, well, using the garden repo, we've got this assertion against the deep partial of the type. So we get nice field level errors that pop up instead of the whole shape turning into red squiggles if something's wrong.
[00:04:51]
And then we save it. And presumably this is what's passed up into the UI. And createExampleGarden is called when the app boots. This is sort of just getting us our starting point. And now we have a beds array that we could create. Or let's start our server or resume it..
[00:05:15]
Actually let's restart it and see if there are errors. We should be good. What's going on? I know what's going on. Entity metadata for garden beds not found. This means go into your data source and add these new concepts, bed, and import it like that, save. And there we go, look at all the plants servers running on localhost 3000.
[00:05:44]
So now our data source knows about the concept of bed and we're setting this up now. We haven't really done anything that makes this any different. Beds would have been an empty array either way. But at least we're sort of exercising that field. Great, so after we create the garden and save it,
>> Mike North: Let's create some beds.
[00:06:15]
And we need a bed repo,
>> Mike North: Just like that. And we can say bedRepo.create({} satisfies DeepPartial<bed>). And then,
>> Mike North: We'll call this bed1. bedRepo.save(bed1). And that should save the bed. Now if I hit Save, we're gonna see a bunch of errors because we have not given the bed what it needs.
[00:07:12]
There's a lot we need to define there. Let's see what the error says. Okay, it needs a width and it needs a height. So let's make this a 6 by 6.
>> Mike North: All right, and, it also should be associated with a garden.
>> Mike North: Use a little shorthand there.
[00:07:40]
Great, and let's see what the API looks like when we hit it now.
>> Mike North: Sorry.
>> Mike North: Interesting, so we're still not quite there yet. Let's follow this through from our domain service into the routing layer. So that's gonna be in our application > gardens-router. Look at this, nothing here, right?
[00:08:20]
So this is where we need to say,
>> Mike North: Actually,
>> Mike North: Did we model bed yet in our types package? I think we did. Down here, types > src. We may not have exported them yet. There's the garden type.
>> Mike North: Yeah, I don't see a bed here yet, so we'll need to wire that up.
[00:08:55]
But for now, let's see if we can just thread something through as just a very generic zone, like an array of zones. So that means we're gonna say gardens, or no, it's garden.beds map. And this returns Zone. So we don't need this anymore.
>> Mike North: And this will be a bed, bed.id, oops,
>> Mike North: width, height.
[00:09:54]
>> Mike North: All right, and what are we missing? We need name, description, and placements.
>> Mike North: Leave that empty. Placements, let's leave it empty as well. Again, our goal is come up for air here after we've introduced this concept of a bed. Now, what's going on here? Types of property zone are incompatible.
[00:10:31]
Placements are incompatible.
>> Mike North: Well, we can, let's see. satisfies DeepPartial. We're just trying to get an error message that's more local.
>> Mike North: Great, okay, so it's tracking us down to zones. item.metadata are incompatible between these types. So let's see if we can add some metadata here.
>> Mike North: No, that's not gonna make it happy.
[00:11:12]
So what we can do instead is say,
>> Mike North: Can we cast it like that?
>> Mike North: Type of property placements are incompatible.
>> Mike North: We're gonna cast our way out of this for now.
>> Mike North: Type unknown. Interesting, so it's on the item metadata, so it's really opinionated about this. What if we get rid of it?
[00:11:57]
Nope.
>> Mike North: Yeah, that's fine.
>> Mike North: Is it still gonna yell at me about placements?
>> Mike North: It's the planting distance. It needs a planting distance on the items. So let's just create a very generic placement object here.
>> Mike North: id: '1', position: x: 1, y: 0,
>> Mike North: And metadata.
>> Mike North: Well, we can remove the metadata for now if it's too much in our way here.
[00:13:12]
>> Mike North: It needs an item and a source id. Sorry, that's it. And this is gonna be our bed id. But let's see if we can leave it as empty here and the item.
>> Mike North: Okay, let's see what's coming through now. Nope, cannot read properties of undefined reading map.
[00:14:10]
garden ,beds. So let's serialize this.
>> Mike North: Let's just print it to the console.
>> Mike North: See what we get.
>> Mike North: So there's our garden. beds is still undefined, interesting. I'm gonna check our database to see if we've actually got a garden bed in there. We do. The garden id should be set.
[00:14:45]
Starts with 03. Yep, that's correct. The relationships, we need to traverse the relationship here. So we're saying getAllGardens, and here we go.
>> Mike North: Now it'll fetch the beds.
>> Mike North: And our API should return something more interesting now. Yep, so there we go. We have a zone. We have a placement in there with x and y.
[00:15:18]
And let's see how our UI responds to this. Yep, I expect it's still gonna need a little bit more because we've very much fudged this placements object. So we're gonna need to keep carrying this through and do these plants.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops