As we have understood from the previous lecture in this lesson,
our goal in this lesson is to
integrate the REST API server that we have already developed,
together with the access to the MongoDB database.
So, we will start with the REST API server
that we built in the very first lesson in this module,
and then having learned how to interact from
our node application to the MongoDB server using Mongoose,
we're going to be developing our REST API server further to integrate
the entire path between the client request coming into the server,
all the way to the corresponding database operation to be performed,
and then constructing and sending back the reply to that client from our server site.
To get started of course, first,
go to the confusion server folder that we have already created in
the very first exercise of this module in the REST API lesson,
and then, in the confusion folder,
we have already built up the REST API server.
Now, what we would be doing is to borrow
the models that we developed in the previous exercise,
the dishes.js file that we developed in the previous exercise,
copied over to the confusion server project,
and also install Bluebird Mongoose,
and another module called as Mongoose currency, to our project.
So, going to our node JS folder,
we first go into the node Mongoose folder,
and we see that in the models sub-folder of the node Mongoose folder,
we have the dishes.js file.
I'm just going to copy the models folder,
and then go over to the confusion server folder,
and then simply pierce the models folder in there.
So, once we do that,
then the dishes.js file which contains the schema and the model for the dishes document,
are integrated into our REST API server.
Of course, in order to make use of that,
we need to install the Mongoose node module,
and a new node module called as Mongoose currency into our project.
So, going to the terminal in the confusion server project,
make sure that your terminal or the command window is
in the confusion server project where you develop the REST API earlier,
and in this project, let's install.
So, we'll do npm install Mongoose,
and then, a new node module called as Mongoose currency.
The Mongoose currency node module,
and seen in other Schema type to our Mongoose application,
so the Mongoose itself,
has certainly already built-in Schema types.
We have seen the use of the number,
the string and the boolean, and the array.
Now, the Mongoose currency adds in support for currency.
Now, why would we need this currency support?
So that Mongoose currency module adds a new type called as the currency type,
which enables us to store a currency value.
Since our dish is going to contain a price,
that is why I'm going to be using the Mongoose currency module here.
Now, the exercise here,
we will illustrate the use of the Mongoose currency module,
you can read more details about the Mongoose currency node module also,
in the documentation of that a link to which is provided in the additional resources.
So, now that we have installed these node modules,
Mongoose and Mongoose currency,
let's go to our application and set it up to communicate with the MongoDB server.
Now, make sure that your MongoDB server is up and running.
So, here, you see that
my MongoDB server is running in another terminal tab on my computer.
If you're running it on a Windows machine,
make sure it is running in another command Window of your Windows computer.
Going to our application in the editor,
we will first start with the app.js file.
Now in the app.js file,
this is where we built up our express application earlier.
But now, this extra suck negation is not connected to the back-end MongoDB server.
We're going to be making use of the Mongoose module,
in order to establish the connection with the server.
So, going in here,
I'm going to add in the require the Mongoose module here.
So, we'll say, "Const Mongoose require Mongoose."
And then also, since we have copied over the models folder,
which contains the dishes file,
which declares the dishes schema and the model.
So, let me import the dishes.
So, we'll say, "Require.slash models dishes."
So, once we have completed that, now of course,
we need to establish the connection with the server.
So, set up
URL mongodb// localhost7017/confusion,
just like we did with the Mongoose exercise,
and then we will say,
"Const connect, Mongo's connect URL".
So, this is exactly the same code that we used in the previous exercise.
Then, let's establish the connection.
So, we will say, ''connect'' and then we'll say,
''DB do it console log.''
Saying, ''Connected correctly to the server.''
And we'll also handle the error here.
We'll just simply do a console log of the error here, that's it.
That will establish the connection to the server from our app.js file.
So, once we have established the connection to the server,
then, let's open the dishes.js file from our models.
Now, in the dishes.js file,
to make use of
the node module that we have just installed.
So, we'll say, ''Require Mongoose currency,'' and say,
''Load the type and Mongoose.''
So, what this will do is to load this new currency type into Mongoose.
Thereafter, we can say const,
currency Mongoose types currency.
That's it. So, this new type,
the currency type is added into Mongoose and that will add in a new type called
currency and then so I'm going to declare
this constant currency as the Mongoose's types currency.
So that I can make use of this in defining the schema in my application.
Now, in this case,
the common schema will remain exactly the same as before but
the dish schema as you recall from the db.json file.
When you look at the structure of a dish document,
you see that the dish document contains name and image which as you see here is a string,
a category, a label,
a price, which is a string type here.
But we will declare this as a currency type,
a feature which as you expect is a Boolean variable,
and a description which is a string and then comments
which is nothing but an array of comments type.
Now, so what we will now do is to extend the dish schema to
support all these various properties or various fields in my json document.
So we already have the name.
So we already have the description in place.
So we need to add in the next few in there we already have the comments,
the array of comments of the comment schema type there.
So we will add in the next few.
So the next one we will add in is the image type,
which would be of
the type string and
we'll say required true.
So this adds the image type.
The next one that I will add is category,
which is also the string type.
The next one is label,
which is also this string type.
Since all these are of the same type and required,
I'm just copying them in here.
Then for the label,
I would say that this is not required but
instead I can also specify a default value if I want.
So I can specify a default value like that.
Default value is an empty string.
So, if I don't specify required I can simply specify a default value here.
Now, in addition, the next field that I'm going to introduce is the price field.
The price field I will declare the type as currency.
Recall that we had declared the currency type earlier
here by first requiring
the Mongoose currency module and then declaring the currency type.
So, that is how you would use the currency type in our application.
So we'll say price type currency and
required is true and then I can also specify the minimum value which would be zero.
Then the next field is
the featured field which would be of the type Boolean,
and the default value will be false.
So, if my document is missing that,
then the default value will be added into the document here.
So notice that I have now expanded
the dish schema by adding in the image type, the category,
the label, the price and the feature to match
the structure of the dish document example that I just showed you earlier.
So now, my dishes schema is all ready to be used.
So, let's now start working on my router.
So where is the router?
You recall that the router that supports the REST API endpoints for the slash dishes,
REST API endpoint and slash dishes,
slash dish ID endpoint is in the dish router.
So, we will go to dish router.jsfile and then we will extend the dish router.js file.
So, in the dish router along with Express and bodyParser,
I'm going to now include Mongoose.
So we'll say require Mongoose and
then we will require dishes model.
Where is the dishes model?
It is in./models/dishes.
So it is in there.
So notice that we are in the router's folder,
so you need to go up one level and then go into
the model's folder and then the dishes.js file is right there.
So that is what we are importing here.
So now, I can update my dish router to be able to interact
with the MongoDB server using
Mongoose and we have already imported the dishes model into my dish router.
So, it is time for me to go and update all the methods in here.
So for the dish router,
the slash which means that the slash dishes endpoint.
I'm going to remove this all from here, instead,
I'm going to explicitly declare all the various endpoints.
To get post put and delete I will handle each one of them independently.
So in the get method,
I'm going to cut that out and then in the get method, what do I need to do?
Recall that we had defined method from Mongoose which allows us to find all the dishes.
So when you do a get operation on the slash dishes endpoint,
you're expecting all the dishes to be returned
to the client in response to the get request.
So, I'm going to go to dishes and then perform the find operation.
So now you see that from my Express server,
I am accessing my MongoDB.
So, will do a find and in the find I'm going to now handle the request.
So I can say dishes find,
since that is going to return a promise,
then I can handle that inside here.
So, I'll say dish and so if the promise resolves correctly,
I'll get it in the then and so I'll say dish and then so we'll handle res
status code is 200 and then we'll say
res set header content type.
Since we are going to be returning the value as a json,
so we'll set that to application json.
Okay, this will return an array of dishes.
So I can simply say dishes and then we'll say res.json.
So the res.json will take as an input in json string
and then send it back over to my client.
So, when you call res.json and supply the value and then it will simply
take the parameter that you give here and then send it back as a json response.
It will put this dishes into the body
of the reply message and then send it back to the server.
Now, we can handle the error
here by saying next error.
We can also do a catch error just for the sake of complete.
I am just going to put both of these into place here,
so that both will be handled as such.
So if an error is returned,
then that'll simply pass off the error to
the overall error handler for my application
and the let that worry about how to handle the error.
So we're going to be sending it over to that.
So you see how I am using the find operation and then performing the request here.
Now, for the post,
as you would have already expected,
I'm going to do dishes.create
because we're going to be creating a new dish here.
So, recall that we are already seen the dishes create
method usage earlier and remember that the body parser would have
already parsed whatever is in the body of the message and loaded it
onto the body property of the request.
So, I'm just going to take the request body and then parse it in as a parameter to my
dishes.create method and handle the return value.
So, we'll say then and this would return
a dish and we'll handle that in here.
So we'll say if the dishes return correctly and if dishes posted correctly, will say res.
Okay let's do a console.log for our own usage.
On the server-side we'll do a console.log saying "Dish Created" dish here.
Let's log that dish to the console and then we'll say these two rest status code.
We'll just copy that code and then paste it in there and in this case,
we are returning the dish here.
The dish that has come in as a parameter here and then let
the client deal with that value on the client-side,
whatever is returned in the dish.
Now, also they will add in
this here and then the catch.
So this is how we handle the post.
For the PUT, because PUT is not allowed,
so we're going to leave it as such.
For DELETE, we are going to be deleting all the dishes.
So we'll say, "Dishes.remove."
This is essentially a dangerous operation.
So you're removing all the dishes from
the server and so we will say,
"Dishes.remove then" and the "then" will get some response.
So we'll just say, "resp here" and the way we would handle
that response is simply to take that value and then return it to the client.
So we'll say, "Res.statusCode 200 content type application json," and
then we'll simply send the response back to the client and we will handle the error
just like we did earlier.
That is the DELETE operation.
So you see that now we are doing the GET,
POST, PUT and the DELETE operation.
Now we're going to be continuing the same with the /dishId end point.
So in this case,
we are specifically motif getting a specific dish.
We are going to be returning that specific dish value.
So in the GET,
what we do is we will say "Dishes.findById.
So the findById is a method that is available from mongo's as well as the MongoDB driver.
So we'll say," req.params.dishId."
Recall that we already know that the dish ID is present in the params property.
You have already learned about this earlier.
So I will say, "findById(req.params.dishId)" and
then and the else.
So I'm just going to copy that then and else from right
there and then come down to the dishRouter and
then simply paste that in here.
So we'll say, " res.statusCode200
application json.res.jsondish and then the error handling.
For the POST, obviously we're not going to be handling the post for a /dishId endpoint.
So we're going to be leaving it as such.
For PUT, we are going to be updating
a specific dish which is identified by its dish ID.
So this is where we will use dishes.findByIdAndUpdate.
So this is the method that we're going to be using,
findbyIDAndUpdate and this takes as the first parameter
req.params.dishId and the second value is
the set and the update
will be in the body of the message.
So I'm just going to retrieve that from
the req body and then also the other flag that I'm going to have.
So will say, "new: true," so that this findbyId method will return
the updated dish as a json string in the reply.
So that is what I'm going to be getting here and then when that value comes in,
I'm just going to take the dish and
then simply return the dish to the client-side.
So I'll say res.jason(dish) and then we'll handle the error correspondingly.
Finally for the DELETE.
For the DELETE again,
the corresponding method that we are going to be
using is the Mongo's method called findbyIdAndRemove.
So you can see that we have this method called
findbyIdAndRemove and this findbyIDandremove,
will take req.params.dishId because that's the dish that we are trying to remove.
Then when this is deleted,
so just like we handled this here,
so I'm just going to copy this code from the Dishes.remove.
Is the same thing that I'm going to be doing here also.
So findbyIdAndRemove and whatever response I get,
I'm going to return it to my client.
With this we have updated the dishRouter.
Let's save all the changes that we have done so
far and then we'll go and start up our server and then see what it does.
So going to the terminal or the command window, start the server.
So I'll say "npm start" and the server is now up and running.
We're going to be using the postman to communicate with this server.
So let's go to postman and then perform certain operations.
So here you see my postman up and running here.
So let me do a GET operation on the localhost:3000/dishes.
So when you do a GET operation as you see,
it'll return an empty string.
My database is now empty so I don't have anything there.
So I'm just going to be returned an empty string.
Let's post a dish.
So when you post a dish,
obviously in the body,
you will be enclosing a dish and the body will be set to be the application json type.
Now, to post a dish,
I have already given you the db.json file in the exercise resources.
So just open the db.json file and then copy the very first dish from
there and then we'll paste it in here and then post that dish.
So, let me go to the db.jason file.
Let me copy the very first dish from here.
So I am just going to copy
the entire dish all the way up to there and then I'm going to post this dish.
This contains a lot of the fields that we have here already.
Let's post this dish to the server and see what happens.
So coming back to the postman.
In here, in the form data,
in the body, let me paste the dish into place.
So, we have the full details of the dish there.
Let's POST this dish to the server.
Then, once the dish is posted to the server,
you see that the Postman has,
let me just shrink this,
and then you see at the bottom that this particular dish has been posted to the database,
to the MongoDB database by my server.
So, you see that the returned value
here shows when the dish was inserted into that server.
So, you have the createdAt and updatedAt added there.
You see that the remaining fields are all stored there.
Note particularly how the price value is being stored there.
This is how currency stores the price value.
So, when you get the return value,
you need to interpret this appropriately on your client side what that means.
Note also that the ID has been added to my dish and for each comment itself,
because each of the comments is itself is a sub-document.
You'll have the updatedAt and createdAt added,
and the ID for each of the comments also added in there automatically by my database.
There you go. So now,
this dish has been added to my database.
Let's again perform the GET operation,
and obviously at this point,
the server should return that one particular dish that has been added in.
So, it will return an array of dishes here,
so as you can see, it returns an array of dishes.
Of course, this array contains only one dish
or that particular dish has been returned here.
So far, so good.
So, let's do a PUT on the dishes and see what happens.
When you do a PUT, obviously, it says,
"PUT operation not supported on dishes", as we expect.
Let's do a DELETE.
Doing a DELETE operation,
it returns this response saying,
"N is equal to one", okay,
one meaning that it has deleted one dish.
Let's now again, perform a GET operation,
and then you would see that my dishes are empty as we expected.
So, you see that the GET, PUT, POST,
and DELETE operations are all working correctly.
Now, let me POST the dish again
to the server because I want to have one dish in the server.
So, let me POST that dish,
and you would notice that the ID has now changed.
So, let me select that ID,
and then we will do a GET with the ID in place.
When you do a GET with the ID in place,
you see that it returns that specific dish as you expect it.
Let's go to the terminal and see what is
being printed on the terminal or your command window.
So, going to the terminal or your command window,
you see that it is printing out all these things on the command window.
So, when we did the first GET operation,
it says, GET /dishes.
So, this is again,
Morgan doing this work for you, it is printing out,
tracing this information and it says dish created
and then that particular dish information has been printed,
and then it says POST /dishes, GET /dishes,
and then when you did a PUT it returned a 403
there and you again created dishes and so on.
So, you see that your server is actually doing all the work,
and these things are getting inserted into your MongoDB database as you expected.
Now, getting back to the Postman,
let's do a POST on the dishes.
Now, this is not supported on the server side,
so your server should say,
"POST operation is not supported on that particular endpoint," as you may expect it.
Let's do a PUT operation.
When you do a PUT operation,
what I am going to do in the PUT operation is that I'm going to be
replacing the label in there.
So, in my body of the message.
So, recall that if you look at the DB.json file,
the label for that would be new,
and so I'm going to change that label to hot.
Since this needs to be in Json,
so label also in quotes Json label hot,
and then let's do a PUT up on that particular endpoint.
The PUT operation was successful,
and so you see that when the PUT operation was done,
then you would notice that the label now has changed from new to hot here,
and note in particular,
createdAt value and the updatedAt value.
So, notice that this record was created
at this time point and was updated a little bit later.
So, the update was done by the PUT operation that I just
performed on that particular dish.
Let's delete the dish.
This is allowed. So, we'll delete the dish,
and then the dish will be deleted and the value will be returned.
Now, if you do a GET operation on
the dishes endpoint,you will see that this will return an empty.
So, you've just managed to delete the dish from our database.
What I'm going to do is to perform
a GET operation on a non-existent dish and see what happens.
When I perform a GET operation on non-existent dish,
it returns null because that dish doesn't exist.
So, it returns a null value saying that the dish doesn't exist.
Now, let me perform a GET operation on a non-ObjectID and see what happens.
It returns as you see.
Let me preview that.
So, it says, "Cast to ObjectID failed for value here at path."
So, I'll be obviously this is not
a valid ObjectID so I just managed to delete part of it,
and then perform the operation so it returns an error saying,
so you see there's 500 internal server error.
The server was not able to handle this and then return this value here.
So, it says, "No,
this is not allowed."
So, because that is not a valid ObjectID.
So, even errors are handled appropriately as you see here.
So, let me again, do a GET operation on the dishes,
and your server is still running,
and it will return an empty value here.
So, we have seen how by modifying
our REST API server to be able to interact with the MongoDB server.
We now have a full-fledged REST API server which is able to store,
and retrieve, and perform various operations
on the data that is stored on my MongoDB server.
With this, we complete this exercise.
So, in this exercise,
we have seen how we are able to interact with our REST API server,
and in turn, with the MongoDB server,
and then we are leveraging the MongoDB server to store and retrieve data from the server.
You're able to interact from
our Express application with the MongoDB server using Mongoose.
This is a good time for you to do a GIT commit with the message,
"Express REST API with Mongoose Part One."