Instructor: So in this video,
we're going to continue implementing the review's resource
and this time by implementing an endpoint
for getting all reviews and also for creating new reviews.
And so at this point, we're basically just reviewing stuff
that we already learned before in previous sections.
And so in this video, I have another challenge for you.
So basically, I want you to implement both these endpoints,
so one endpoint for getting all review
and one endpoint for creating new reviews all on your own.
Okay?
So create the controller file,
then in there create the controller functions,
and then also create the routes in your review routes file.
And then by the end of course, create some new reviews
and also retrieve them from the database
using get all reviews.
All right.
So please pause the video now and get to work.
All right.
And now it's my turn to actually implement this,
and I'm starting with the controller functions.
So right here we create
review Controller dot js
then of course we start by requiring the review.
So one level up, then models, then review model.
So get All Reviews, and we're using
the same name as always.
Right?
Then we already know this is going to be
an async function because we're going to be dealing
with the database here,
and also we need to wrap this entire function
into the catch Async.
So catch Async, I think that's what it's called.
Require.
All right.
And now let's simply fetch all the reviews using await,
and then just a simple find without any filter.
A status of 200 and then send back to normal JSON.
Status as success.
We also define the result property
with the reviews dot length,
and of course, then the data itself.
Give it a save here and now onto the next one.
So create Review.
All right.
And you start to seeing here that
we're building a lot of duplicate code actually.
So all of this here looks
basically exactly the same as it looks for the users,
and for the tours.
Right?
And actually we are going to fix this
a bit later in the section.
But for now, I really just want to make this work.
Okay?
So for now don't worry about writing all this
kinda duplicate looking code.
Okay.
So we call this here new Review,
and then as always we use dot create with all the data
coming in from the body.
Okay?
And so, again if there are any fields on the body
that are not in the review schema
then they will simply be ignored.
And so that's why it's safe to
actually simply do it like this
when creating a new resource.
All right?
Anyway, let's now send it back to the client as always.
So with a status of 201 for created,
and review should be the new
Review.
All right.
Actually without the colon there, semicolon, and so yeah.
These are all controllers.
Now let's move on to the route.
So review
Routes dot js.
And here of course we start
by requiring our controller,
and to the controllers and
review Controller dot js.
Next up, we need to create our router.
So express, and so of course we also need to
import express here.
So let's do that before doing anything else.
Express.
So dot Router, and I think this is how it works.
And now router
and define our route
and this again is basically route of the reviews.
Okay.
Because remember how in the next step
we are actually going to mount
this router on API slash reviews.
Okay?
So just like we did with the tours and the users.
And actually let's do that before we do anything else.
Okay?
So just to take that confusion
that you might have away.
So, let's export the router from here.
Okay?
And so now we can move over
to app dot js.
And then of course import our router here.
And require,
review routes.
Okay?
And so now we come down here
and mount this router on a new path.
And that path is going to be as I said
API slash V1 slash
reviews.
Okay.
And so again this router here
that we're specifying now is basically a middleware
that we mount upon this path.
Okay?
So whenever there is a request
with a url that starts like this
then this middleware function here
will basically be called.
And so that is then our router
and in there just the slash route,
so just the root basically will
then be this API V1 reviews.
Okay?
So just like we did it before we the other two resources.
So tour Model, that's not where we were working.
We were working in the review Routes.
Okay.
So we specified a route.
Let's now specify the method
for which we specify our function.
So we have get, and for that we used
or we actually rewrote
review Controller dot get All Reviews
Right?
And then we also have post for
create Review.
Okay?
Give it a save.
And actually we only want authenticated users
to be able to post reviews.
And also only users that are actually regular users.
So not administrators and also not tour guides.
Okay?
So how can we implement that?
Let's remember our authentication section.
So we start by requiring our auth Controller.
So again, controllers and auth Controller.
And now all we need to do
is to actually use the middleware functions
that we specified in there.
Remember.
So first, we use the protect middleware,
so auth Controller
dot protect
and this will make it so that we protect this route
to only be accessed by users who are authenticated.
Right?
And then in the next step we say
that we want to restrict this route
so we use our restrict To middleware
to only users with the role of user.
All right?
So again, we did this here before a couple of times.
And so, not really anything new at this point.
Okay.
So I think we followed all the steps.
So first off, we have a model which will allow us
to create new documents.
Then we have our Controller functions
defined in our Controller to get all reviews
and to create reviews.
Then, we used these Controller functions
or handler functions
as you can also call them,
to create some new routes.
Okay?
And so we created a route for getting reviews
and for posting reviews.
And just like before we did this
basically in a mini sub-application
which is just for reviews.
And so that's why we created our new router
which then we imported into our main application
and mounted it on this url where we want
to access everything related to reviews.
All right?
So, let's now actually go ahead and test this.
So I'm gonna go ahead, copy this,
and create a new tab here
and so here
it's reviews
and of course post.
All right.
So, what do we actually need to specify
in order to post a new review?
So we need the review itself.
Remember.
So let's say "amazing tour"
then the rating
and I'm gonna give it five here,
and then the tour and the user ID.
Okay?
And so now we need to get the ID of one of the tours.
Okay?
And so let's use the first real tour here
let's say, so let's use this sea explorer.
All right?
So,
the ID of the sea explorer
and now we of course also need
the ID of the user posting the review.
And we can get that here from
get all users.
And so actually we only have one user
which is a regular user.
So this Jonas here and so let's get this ID.
All right?
Now keep in mind that this user
actually needs to be logged in.
Okay?
And so a bit later we will then actually
automatically get the user ID from the user
that's already logged in.
Remember we can do that because the protect middleware
will put the user on the request object.
Remember that?
But for now, I wanted to keep it simple here,
and so with the current implementation
we actually need to provide the user's ID as well.
Okay?
But still we need to log in as a regular user
because we protected this route.
Remember that?
So let's just close a couple of these.
Okay?
And log in here.
And we do that as, so what hello dot Jonas at IO
so hello.
And his password is probably and I hope
it is still the same.
And actually it's not so let's try a new password
cause I remember I used that one when we changed passwords.
Still doesn't work, and so let's actually
create a new user.
Okay?
Of course we could do the reset password at this point,
but that's a bit too much work
and so I'm simply going to create a new user
so that's easier just for testing it now.
Okay?
So let's use test at Jonas dot IO
and the name here is gonna be test user.
All right.
Oh, and we already have that email address in our database
and that's strange.
We have user.
Maybe it didn't, we didn't update this properly.
Oh, but maybe it's a deleted user.
So a user that's no longer active
and is therefore not showing up here.
So let's just take a look at that in compass.
And of course when you're in development mode,
you're gonna run into these kind of issues all the time.
So here, test Jonas, and as I was saying,
it's actually one of these deleted users.
So active set to false.
So let's try that again.
So test user here simply as well.
So send it now and now we are logged in.
And so now I'm copying the ID from this new user
to create this new review.
All right?
Let's send it now,
and of course we get the you are not logged in error
because we actually didn't provide
our JSON web token.
So we need to come to authorization
then the bearer token,
and then of course this one.
So, if we try this now again,
then here we go.
Okay.
Let's create another one for another tour,
this time for,
for the next one,
so for Forrest Hiker.
So copy the ID here as well.
Yeah.
Here the user is gonna be the same, but another tour.
Let's give it a four stars.
And let's just say "loved it."
Something very simple
and okay.
Give this a save,
and I'm gonna create
a new folder here for the reviews
and of course
something went wrong here.
So where is that folder?
Mm.
It's nowhere really so let's just create it here.
And we can actually change the name up here as well.
So create
new review.
Okay.
And now we also want to get all reviews.
So we no longer need these two.
Okay and this one is really a GET,
and let's also save it in Reviews.
Get all the reviews.
And so that should be enough to get us started
and really see all our reviews.
Okay, and here we go.
Let's take a look at compass,
and to see the reviews here we need to go ahead
and reload the entire database,
but now when we come to Reviews here we indeed see
our two reviews that have been created as well.
Okay.
Now how do we make it so that
we actually see the user and the tour data here
instead of simply the IDs?
Well, of course we need to again use populate.
Right?
And so that's exactly what we're going to do
in the next video.