NOW THAT YOU HAVE THE REST API and points for creating resources we're going to focus on the rest api
endpoints for reading resources.
As we explored earlier in the little visualization there are gonna be two.
One that allows us to get back a list of multiple items and one that allows us to target a specific
item by its unique identifier.
Let's go ahead and kick things off with the two routes for users in this video.
That is your challenge for the next video.
You'll be doing the same thing for tasks down below.
Now let's get started by setting up the root handler for fetching multiple users app.
Get to set up the GET request then the path forward slash users.
After that we have the callback function where we get access to the request and to the response from
here.
We're going to go ahead and actually use Mongoose to fetch all of the users from the database.
Now Mongoose provides us with a series of methods similar to those we saw with the Mongo D.B. native
driver.
Let's take a quick moment to explore where we can find these before we use our first one over in Google
Chrome.
I'll be navigating over to my Mongoose tab and then the documentation under guides we're looking for
these queries guide.
This contains a list of all of the methods we have access to directly on the model so directly on uppercase
U user or uppercase t task.
Here I have methods for some of the other CRUD operations we already know how to create right here.
I have find methods for the reading operations I have to update methods for updating one or many.
And I have methods for deleting one or many documents so we'll be using these in order to achieve our
goal.
Now when it comes to fetching multiple we use the find method and the find method accepts a query an
object just like we saw with the native driver.
So over here what am I going to do.
Well for users what I'll be doing is calling user dot.
Fine.
Now find accepts as its first argument an object where we could refine our search criteria.
For example we could try to find users where name equals Andrew similar to what we did with the Mongo
DB.
Native driver in this case we don't want to do any searching.
So we're gonna go ahead and leave it as an empty object.
This is going to fetch all users stored in the database.
Now we get access to those via the promise that find returns the promise will be fulfilled with the
users.
If things go well or it'll be rejected with an error if things go wrong right here that means we set
up a call to dot then and we go ahead and provide our callback function.
If this function runs that means things went well and we'll have access to the users right here users
if things go poorly we will set up the catch call.
This is going to get access to the error and we'll be able to go ahead and respond appropriately.
Let's go ahead and talk about the success case if we are able to query for the users.
What do we want to do.
Well we want to go ahead and send them back.
So what I'll do is use response dot send to provide that array of users as the response.
Now before we worry about handling any errors let's go ahead and make sure this is at least working.
What I'm going to do is head over to postmen and we're going to create a new request in that task app
collection right here.
Let's go ahead and add a request.
I'll pick a name for it.
I can call this one something like read users.
I will save it and we'll go ahead and set up the details by clicking on it.
So right here we have read to users and we're going to leave this as a get request.
Then we'll provide the U.R.L. that would be local host port three thousand forward slash users.
Now we already have a root handler for forward slash users but that was a post request that is completely
different from the one we're using here with the get request.
Now if I go ahead and fire this off I would expect to see an array of users coming back and that is
exactly what I have right here.
I have all of my users showing up as expected I have my Andrew's and my one Andrew meet.
Now one thing we want to make sure we do as we build out our various requests is save them up above
I can see that all of them have this little circle meaning that changes have been made to the request
that haven't been saved.
Right here we can click the save button for each.
Or we can use command s on a Mac.
That would be control s on other operating systems.
So make sure you do save your requests so we can easily access them in the future and we run them actually
as we ran them before.
Now back in Visual Studio code we can make sure that we do do something when we can't connect to the
database and actually get the users.
In this case I'll be using response dot status to set up a five one hundred status code right here.
Five hundred which is an internal server error.
So in this case we would see this run if something like the database connection was lost right here.
Well then use dot send and we actually don't need to send anything back.
We can just send back the response with the status code letting them know that the service is currently
down.
Now let's move on and to these second get handler.
We're going to set up for users.
This one is going to allow us to fetch an individual user by I.D. so we'll still be using app dot get
but the path is going to look a bit different path.
We'll start off.
Much the same way it'll start off with forward slash users and forward slash.
But then what comes after that forward slash is going to be dynamic it's going to be the idea of the
particular user you're trying to fetch and that's obviously going to change as you make requests to
this end point one time it might be something like a e.
Another time the I.D. might be twelve.
So what we want to do is capture whatever value is put right here after this second forward slash and
get access to it in the root handler so we can fetch the user correctly.
To do that express it gives us access to something called Route parameters.
These are parts of the you are that are used to capture dynamic values.
And it looks a little bit like this after the forward slash we add a colon followed by a name we can
pick whatever name we like.
I'm going to use I.D..
So essentially we're saying someone's going to make a get request to forward slash users forward slash
something when that happens.
I want this root handler to run the one I'm setting up right now and I want to be able to access the
dynamic value they provided inside of here.
And that's exactly what we're gonna be able to do.
Request gives us access to request dot parents.
This contains all of the route parameters that we're provided in this case it is an object with a single
property I.D. and the value for I.D. is whatever was put inside of the U.R.L. let's mess around with
this.
What I'm gonna do is ramp the request dot parameter in a console dot log call so I can print those out
and I'm not even going to send back a response.
Now obviously that's not what we want in the long term but for this little demonstration it's OK if
you request times out because no response is ever set.
Let's save the file to restart the server and test things out from postmen right here.
I'll be adding a new request and we can call this something like read user singular.
I'm going to go ahead and save that and we'll set up the correct you are.
I'll click the request in the collections list over here that is local host colon.
Three thousand forward slash users forward slash some value.
This could be anything as an example.
Let's just enter a bunch of random numbers inside of here.
You don't have to match up with mine exactly.
We're going to click send.
And down below we're gonna see the loading screen forever because we never send back a response.
But over inside a visual studio code down below I can see what's stored on that RAM's object right here.
I have I.D. and it is the idea value I typed as part of the U.R.L..
So now that we know how we can extract that value we'll be able to actually fetch the user if any and
get that sent back right here.
Let's go ahead and start that process.
I'm going to create a new concept.
I'm going to call this underscore I.D. and then I'm going to get its value from request dot per Ms.
Dot right here I.D. which matches up with what we had up above and what we were seeing when we logged
out the parameter object down below.
The next thing we want to do is use another one of those query methods to actually fetch the user over
in the Mongoose documentation.
There are two main ways we can fetch a single item.
We have find one and we have a find by I.D. so I could use find one if I'm trying to find a user buy
something else like maybe their email address I can use find by I.D. if I'm trying to find them by their
I.D. which is exactly what we're trying to do here.
So with find one we provide an object with our search criteria with find my I.D. We just provide the
I.D. right here for us.
That would be user dot find by I.D. and we provide the I.D. which we just grabbed up above.
Now we can set up our promise methods we have our then call if we did indeed get the user back right
here we're gonna have access to that user as the argument and then down below we'll also set up a call
to catch if we were not able to complete that query successfully.
And right here if that's the case we'll have access to the error.
Now what exactly do we want to do inside of our first callback function when the promise is fulfilled.
It's important to remember once again that a mongo DV query is not considered a failure if we don't
get any results back when we're looking for something that's considered a success.
Mongo DB was able to find everything you asked for and get it back to you correctly even if it was nothing
because there was no matches.
That means this first function is going to run but we might not always have a user.
There's a chance that we weren't able to find a user with that I.D. In which case we would have no value
here.
So we'll use a little bit of conditional logic to once again keep things nice and organized.
If there is no user we'll go ahead and run some code I'm using return to stop the function execution
though I could always use an else clause to do something similar and right here.
What are we going to do.
We're going to send back a forum for saying the user was not found.
So that would be response dot status sending an equal to 4 0 for then dot send.
Perfect.
Now if our actual catch function runs we'll do something similar to what we did up above response dot
status.
Five hundred and using send to send that back.
Now the only thing left to do is send back the response when things go well and that's going to happen
right here in this case we want to make sure to send that data back.
So right here what I'll do is use response dot send to send back the individual user.
Now in this case I'm not explicitly changing the status code which means the status will be two hundred
and that's perfectly fine for our endpoints that involve fetching a resource.
Now let's go ahead and actually test this out over inside of postmen.
We're going to fire off the exact same request we had before.
This is gonna be seen as the I.D. and we're not going to find any record with that I.D..
And down below we get a 4 0 4 as expected.
Now let's use a valid I.D. and see what we get back for that over in my read user's request I have a
few different ideas showing up I'm going to go ahead and grab just one of them then I'll go over to
read user I'll swap out that portion of the U.R.L. with the I.D. I just copied it to the clipboard.
I'm gonna fire that off and this time around I get a status code of two hundred and I actually get my
user object down below which is fantastic.
So now we have our resource creation endpoints for fetching all items or fetching a single item by its
I.D..
Now one thing you'll notice about the code down below is that I never convert my string I.D. into an
object idea like we had to do with the Mongo D.B. native driver when finding documents Mongoose does
many nice things for us.
And one nice thing it does is that it automatically converts those string ideas into object I.D. to
make sure everything works correctly.
So that's not the main reason we're using mongoose.
The main reason is to create those models and structure our data in a nice way.
But this is definitely a nice little advantage now that's what we're going to stop for this one in the
next video.
It's up to you to set up two end points for fetching tasks.
I'm excited to get to that.
So let's jump right into the next one.