In this video, we are going to write a book service which will be used by one of the endpoints to grab a given amount of top books. We will also be wiring up the program CS, but I have a few comments about that later. So, let’s talk about that then.
Here’s a notepad I’ve modified the original prompt to add more details on how to build the book service. So, let’s read and then post that into GPD4.
As you can see, I say top books are based on the amount of reviews and average review counts. So, the average review count multiplied by the number of single book would give a score. Based on that, the top five books would be chosen.
Then, the meta takes the top number as an integer and can be greater than or equal to one and less than or equal to five. So, between 1 and 5, then perform top book logic in a separate service called book service and return a list of books.
For reference, here’s the book domain model. I just give it the domain model. Here’s a DB set definition for the book public DB set book books. It probably could have inverted, but just for simplicity and to keep things more accurate, I specified it here. And then, inject appdb context into this service to be able to access book DB set and perform link operations with the described logic to get the top number of books.
So, let’s grab this modified prompt, bring it to GPD4, and let’s go ahead.
While this is generating, let me show you the Win Merge. What I have there is how we have been doing things. So, we essentially have the code that I’ve only written on the right side, and on the left-hand side, we post what has been generated. So, let’s grab what has been generated, just copy, bring it over, and we’re going to get rid of the using statements. I think everything else is pretty much aligned well. We can even take out the class itself, get rid of the namespaces here, so it’s even less of discrepancies. Then, let’s compare.
Right off the bat, DB context naming is different. That’s fine. The obvious differences in the async, this one is not async. I could have specified that probably, but you know, I think that’s fine. It should be a quick change if we were to port that over. So, the name is different because it’s an async, so I named it async appropriately. I’d return a list of books. It’s a task. This one is not a task because it’s not async. So, that makes sense. The logic here is correct, the type of exception that’s being returned. Argument out of range exception. I think it’s actually a better exception to use than the one I’m using, so I can change that. The error message, I can also take it from here. So, that’s fine.
But, so that’s one change that I will port over onto my change. And then, top books, this one await because this is not async. So, that’s the reason why. But otherwise, it’s using the DB context books and then it’s including the reviews. And then, in this case, it will happen in the select. So, that’s the reason why I don’t do include and then select new. So, this is going to create a book and then create a score. The score is going to be if the review count is greater than zero, so if the book has any reviews at all, then the count of it times by its average rating is what’s going to be the score. Otherwise, it’s going to be zero. And then, it’s going to order by descending and grab the score. And then, it’s going to take only the amount that’s been specified and then it’s going to select the books and return it as a list.
In here, what I do is I calculate the score, but then what I do is I get rid of any books that don’t have any reviews. So, if the review count is greater than zero, that’s fine. I will take that in. But otherwise, if it doesn’t have any reviews, I just ignore it. And then, only after that, I sort it by its score, which is average rating times review count. I take the number, select the book, and then return it as a list.
What I will do is I will still grab my code, the one that I have written, and I will add the exception type from the generator code. So, that was a good idea that I got by just looking at the generated code. So, let’s just go ahead and do that. I am going to go and create a book service. So, I’ll just grab this.
Go back to the project that we have. So far, I actually have to create a new project here, so I’ll do that.
So, here, I will just do class Library. Next, it’s going to be in the API. Okay, that’s going to be Online Book Store API. Business, so it’s like the business layer. You can call it core or anything else, maybe even services, to be honest with you. But business sounds good. You know, if we’re to have more business logic, we would put it here. So, then we just say Next. .NET 7 or whatever the highest one is in your case. Create. And I will go ahead and paste that in here.
So, let’s see if it got everything. So, we have the… Yeah, we still need to add a reference to data so we can use AppDBContext. Book is going to go from the models or come from the models, and then async. That’s it. System, we’re not using. Okay, and then I will go back to here and grab the exception because that actually was a better exception type. Invalid data or just like more specifically describing the exception versus what I had before. So, I can change that. The error message, I can also take it from here. So, that’s fine.
So, let’s actually go ahead and build it. It says one succeeded, which is great. We can actually rebuild our… Just build it again. Let’s actually go to the solution and rebuild from top level. Should say three succeeded now. Great.
So, I’m going to talk about this more in my final thoughts, but the reason why I didn’t even bother generating configuration is because configuration is going to be specific to each project. You’re going to configure the project the way you want it to be configured. That’s the bottom line. So, if you were to generate this, you would have to almost line by line in natural language describe what you want, and it would have to be very granular because in configuration, one specific change could make a huge difference. And if you don’t configure your project correctly, it could have implications such as security or performance degradation over time. So, for configurations, I would say it kind of has to be a very manual process unless at one point something better comes up. But configuration needs to be done very, very carefully. And so, if you want to generate certain pieces and generate some ideas on how to configure your specific project, okay, sounds good. But I think the rest of it should be done manually, and you really need to think through it because based on your configuration is how everything else is going to work. So, I would spend a lot of time on your configuration, and I wouldn’t let that be generated. Another point is that if you are just generating your configurations, you really need to know the domain you’re working in because even if let’s just say you’re not even a non-technical user, you’re just a Java or Python developer and you’re coming into a .NET world, you’ll need to know how .NET or in this case, ASP.NET Core Web API works in its configuration, how that works. Because you’ll need to know that in order to be able to configure it properly. If you were to generate something and just plug that in, you really don’t know what or how you’re configuring your application. That’s the main point.
So, what I’m trying to say is that configuration is very important, and I would leave that up as a manual task. And once again, I’ll talk more about this in my final thoughts. But for now, we have gotten the Program.cs wired up. We have created the book service. We’ve built everything, so everything is kind of nice and functional. And what we’re going to do next is start working on the controllers. And after that, our API should be up and ready to use.
If you learned something, like, comment, and subscribe. And I’ll see you in the next video.