From the course: Creating Spring Boot Microservices
Declaring a new RestController - Spring Boot Tutorial
From the course: Creating Spring Boot Microservices
Declaring a new RestController
- So, Explore California wants to add new features. They would like to allow their travelers to rate tours and publish the average score for a tour. They met with our business analyst and myself to describe the new functionality. Then the business analyst translated Explore California's requests into new requirements and four use cases that we'll look at now. The first use case is rate a tour. For a traveler who's participated in a tour, I would like to submit a one to five star score and a comment up to 255 characters and I have a personal customer identifier. This is not an identifier that our company maintains. The customer maintains those IDs. The second use case is, as a traveler who's previously rated a tour, I would like to modify the score or the comment using my personal identifier. The third use case is, as a potential traveler, I would like to view all ratings for a tour. I would like to view all the scores and comments for a tour, and I don't need a personal customer identifier for this use case. And the last new use case is, as a traveler, I would like to view the average score for each tour. I do not need an ID for that use case. And finally, I have some non-functional system requirements. As a front end developer who would be coding this website, I expect that the API to return a 201 when a new rating has been successfully created in the database, and I expect the API to return a 400 when a request body is not valid. I got a jumpstart on the code for these use cases. Let me show you my approach. I started looking at the nouns of the use cases, and obviously a big one that jumped out to me was tour rating. And so I have an entity tour rating that will map to a tour_rating database table. And I have a generated identifier that's of type integer. I saw that a tour rating would be associated with a particular tour, so I have a many to one annotation saying that a tour could have many tour ratings. There's a customer identifier that's an integer, a score, and a comment. Next, I have a tour rating repository in the repo folder. I do not want this repository to be exposed to spring data rest, so I set exported equals false in the repository rest resource annotation. And then I have two methods for the tour rating repository. Find by tour ID, and that will return a list of tour ratings, and find by tour ID and customer ID, and that would return one unique tour rating if it is found. Next, I have tour rating service, whereas the business logic interacting between tour ratings and tours. So I want to create a new tour rating. And so here I have the method create new with all the attributes passed in. The unique identifier will be generated, so a tour ID, customer ID score, and comment is passed in. I have this method that's a private method called Verify Tour, and what this will do is if a tour ID is passed in, we want to verify that that really is a tour, so we're going to invoke the tour repository find by ID method, and if it's not found, then a no such element exception will be thrown and it's saying that tour does not exist. So if the tour doesn't exist, a exception would be thrown and we would not even create that tour. Another one is lookup ratings by ID. So this is the unique ID in the database. Next is look up all tour ratings. Every tour rating you can possibly find. Next is lookup ratings for a tour ID. So passing in just the tour ID and we're going to invoke that find by tour ID method using verify tour again. If that tour ID is invalid, that no such element exception is going to be thrown. Update will be, we want to modify a tour rating. So first we want to look up the tour rating by the tour ID and the customer ID, and if, let's see, verify tour rating. That also, if it's not found, no such element exception will be thrown. And we're going to modify the comment and the score. We look it up, set the comment that's passed in and the score, and then save it. And then this is the case where they might update either one or the other. They could update the score or the comment, and so an optional is passed in for each of those, and so after verifying that the tour exists for that tour ID and customer ID, and if we have a tour rating, if that score is present in the optional, then we will set the score. If the comment is present, we'll set the comment and then do the save. Here we are deleting a tour rating, first looking up the tour rating by tour ID and customer ID, and then delete it. Get the average score from a tour rating. We're going to find the tour by ID verifying that its tour exists. And then now we have this list of ratings. We're going to stream it and map it to an integer of the score, and then using streams, get the average, and if the average is present that it had ratings on there, then it would return the average as a double. Otherwise, a null would be returned. And then lastly, the jumpstart that I got on this is in, I created the controller, and here is the rest controller. There's no method yet. All we've declared is this @RestController. We have our request mapping as /tours/ they have to provide the tour ID and then ratings, and then all of our endpoints will be off of that base URI.
Contents
-
-
-
-
-
-
-
(Locked)
Choosing the right framework3m 31s
-
Declaring a new RestController6m 29s
-
(Locked)
Create the RestController HTTP POST endpoint7m 31s
-
(Locked)
Create the RestController HTTP GET endpoint3m 23s
-
(Locked)
Create the RestController HTTP PUT, PATCH, and DELETE endpoints3m 34s
-
(Locked)
Challenge: Add a PATCH endpoint1m 6s
-
(Locked)
Solution: Add a PATCH endpoint1m 20s
-
(Locked)
-
-
-
-
-