How to Build a RESTful API using Node, Express, and Mongo

**Introduction to Creating a Web Application with Express and MongoDB**

In this session, we will explore how to create a web application using Express and MongoDB. The process is relatively straightforward, but it does require some understanding of the underlying technologies involved.

To start, we need to create an application that has a package.json file. This file contains metadata about our project, such as its name, version, and dependencies. Once we have created this file, we can run `npm install` to install all the dependencies required for our project.

Next, we will create an Express server. The Express server is responsible for handling incoming requests and sending responses back to the client. We will also need to configure our application to work with MongoDB. This involves setting up a connection to our database using Mongoose, which is a popular ORM (Object-Relational Mapping) tool for MongoDB.

One of the benefits of using Mongoose is that it simplifies the process of interacting with our database. With Mongoose, we can define models that represent tables in our database, and then use these models to perform CRUD (Create, Read, Update, Delete) operations on our data.

**Deploying Our Application**

Once we have created and configured our application, we need to deploy it to a cloud platform. In this case, we will be using Now.sh, which is a popular platform for deploying web applications quickly and easily.

To deploy our application, we simply need to run `now` in the terminal, and Now.sh will take care of the rest. This includes creating a URL for our application that we can use to access it from anywhere in the world.

Now.sh also provides features such as scaling and load balancing, which make it easy to handle traffic and ensure that our application is always available. Additionally, Now.sh allows us to map a domain name to our application, which gives us more control over our brand and makes it easier for users to find and access our application.

**Using Mongoose**

Mongoose provides a lot of power and flexibility when it comes to interacting with our database. One of the benefits of using Mongoose is that it allows us to define models that represent tables in our database, and then use these models to perform CRUD operations on our data.

In addition to its CRUD capabilities, Mongoose also provides features such as validation, which allows us to validate user input and ensure that our data is consistent. This can be especially useful when working with forms or other interactive elements on our application.

Mongoose also provides a lot of rich methods for handling interfaces into the database. For example, we can use the `validate` method to ensure that our data meets certain criteria before it is saved to the database. We can also use the `create` and `update` methods to perform these operations.

**Personal Experience**

As a developer, I have found Mongoose to be an extremely powerful tool for working with MongoDB. Its ability to simplify the process of interacting with the database has made it easier for me to build complex applications quickly and efficiently.

In my experience, using Mongoose has also allowed me to focus more on the logic and functionality of my application, rather than getting bogged down in the details of the underlying database implementation. This has been a huge time-saver and has enabled me to deliver high-quality applications more quickly.

I have written articles about using Mongoose with MongoDB, including an introduction to Mongoose and how to use it for MongoDB. I have also written an article about building a React boilerplate, which provides an overview of the underlying building blocks for creating web applications.

**Conclusion**

In this session, we explored how to create a web application using Express and MongoDB. We discussed the process of setting up our application, deploying it to a cloud platform, and configuring it to work with MongoDB using Mongoose.

We also talked about the benefits of using Mongoose, including its ability to simplify the process of interacting with the database and provide features such as validation and CRUD capabilities.

I hope this session was helpful in providing an overview of how to create a web application using Express and MongoDB. If you have any additional questions or would like more information on how to get started with these technologies, please don't hesitate to reach out.

"WEBVTTKind: captionsLanguage: enhello and welcome to this workshop on building a rest api with node express and well let's begin with the agenda for today we're going to start with touching upon some of the concepts related to this topic followed by the installation of the environment and we will start with setting up the application before we dive into the crux of this workshop which is to set up a express web server and then we're going to connect it to mongodb via mongoose and i have a bit of a stretch here if we have time i want to show you how to deploy this application using a service called now.sh so let's start with concepts around http rest and apis so what is http it stands for hypertext transfer protocol now hypertext is basically text that can link to other text hence the word hypertext transfer protocol because that's been transferred it's an application layer protocol it's built on top of the tcp ip protocol what that means is it's using tcp ip for communicating but then there's application layer logic on top it pretty much defines all the rules for transferring resources between a client and a server now every http request is executed independently so on the server side it does not have knowledge of any of the requests that came before it and that's what makes http stateless but here's an interesting thing it's built on top of tcp ip which is not stateless so how does that work basically when you send an http request it's issuing a connection via tcp ip to the other side it could be a server or the client and the tcp connection stays connected http will send what it needs to and then it's going to disconnect hence it's known as stateless one of the cool things about http is that you can transfer anything in the body as long as the http headers define what is being transferred so for instance if you have an image versus html file versus a javascript file embedded in your body then you need to specify the content type in the header and that's how the receiving end knows what to do with it now let's talk about rest it stands for representational state transfer it's actually an architectural pattern with design guidelines http is usually the underlying protocol when you're implementing rest but rest can be implemented on other protocols it hasn't been used as much though what http provides us is basically a set of methods that need to be used explicitly by the rest pattern every restful resource has a unique id which makes it interesting because you can reference different things over the internet via specific url now client state is not persisted between requests so that's what rest basically states that we should be doing however that state can be passed along to the server via some attributes that help the server decide how to process that request rest also states that the application should define a caching policy for responses what that means is it allows the client to make a decision on the received content and they can decide to either keep it in their cache and serve it from there for subsequent requests so that it improves the application performance it also dictates that there should be separation of concerns between the clients and servers what that means is the client does not care about what is the memory usage on the server or what the setup is of the hardware and things like that and vice versa that's also a layered system so the client doesn't really know if it's talking directly to the host server or if there are other intermediate servers such as proxy servers or edge cache servers and things like that now let's talk about what an api is it stands for an application programming interface basically you have functions that are defined on the server side and the api tells you what is supported from the server and where the request should be made so essentially it's going to tell you what the the pattern of the urls are that you're going to call in use to call into the server pretty much it's telling you what the format of the request and response is now there's no standard way of writing apis and that's what makes it somewhat powerful but at the same time it's a bit scary because you know every system will vary so much and so that's where rest comes in it provides us with guidelines on how these apis should be constructed you're going to hear about something called a crud operation over and over when you're using rest and all that stands for is it's an acronym for creating reading updating and deleting records so essentially when you're making a call over an api you're performing one of those four operations anyway let's get started with the installation i had a note about this in the workshop description so hopefully you are all set up with this but i quickly want to touch upon what this entails so we need an ide where we're going to write code you need node.js installed usually npm is part of the node.js installation so you should be good there we're going to use an instance of a database in the cloud via mlab.com and then one of the things i mentioned forgot to mention was that we need a rest client i'll get into the details there something like insomnia or postman and then finally robo3t which allows us to look at the data in so as for the ide you have three different options vs code atom and webstorm that i would recommend but there are a ton of ideas out there you want to find something that's going to help you with the language and the framework that you're working with and all three of these are very powerful and customizable as far as node.js is concerned you can get any latest version of node.js and we should be good that should have the latest package manager there is a subtle difference so if you have version 5 you don't need to use the save command because it automatically saves everything in the package when we install any of the packages and then as far as coding today we're going to use the natively supported es6 and 7 that's available in node that way we don't have to set up babel or any other transpilers if you can go to node.green you'll notice that it lists out all the features that are supported by node and this gives you a good idea of which version supports what feature in es6 and 7. sorry we're trying to figure out the video here and some reason it's not running just give me a moment here um i'm not sure what's going on there leanna anyway let's continue for now so mongodb can be installed locally or you can get an instance via the mlab cloud and at the same time if you are a fan of docker you can use docker to deploy it somewhere or or install it locally as well we're going to use mlab for this workshop because it allows us to easily deploy the application and not worry about a installation during deployment as far as the rest line goes we're gonna use it to test the api that we build and i prefer insomnia because it's pretty lightweight but postman is also very powerful now i got a question here about if i have any experience with webstorm and what do i think of it so i've used several ides over the years years actually 20 some years and i really love webstorm because it allows you to do things that most of the other ids require you to configure it from scratch like vs code for instance there's one subtle aspect of vs code that i dislike compared to webstorm and that is you cannot get multiple console windows in a tabular view they have sort of a drop down and so you can quickly switch between those windows and i'm sure there's a plug-in out there but i haven't found that yet as far as sorry there's another question here which says things like mlab seem way more popular in node world do you have any thoughts over why this is the case compared to other ecosystems i believe is an integral component of most node applications mainly because you're coding in javascript all the way from the browser to the back end and it lends itself very well to as well because you're storing javascript objects or json and then that what that means is you don't have to go through conversions uh for your data compared to other databases now using m-lab specifically they have a very good interface and they provide you with a free starter database that you can uh get everything up and running within a minute literally so it's naturally the preferred option because it saves you a lot of time from having to configure it getting back to this if you guys can download insomnia or postman you should be able to follow along with testing the api now as far as getting started we need to set up the application first so that we can start to code the apis so we're going to start with creating a project folder and then you will open up your ide either whatever it is you're using in that project folder and then we'll start to construct other subfolders and files there so what i'm going to do is i have a slide outlining what we're going to accomplish and so i will keep switching between the slide and webstorm as we complete these tasks so in this case we are initializing our node and then creating a very very basic hello world script actually and we're going to set up some startup scripts that allow us to run our application and then we'll build from there so here is my webstorm instance i have a folder that's created here what i'm going to do is in the console at the bottom here i'm not sure if i can increase the font in the console but i will in the code what i'm going to type is npm init and i just want to make sure i'm in the correct folder here i am okay so i will type an npm init and then i will provide an option optional parameter called dash y which stands for simply don't ask me any questions just generate the the package.json file this is what npm minute will do is it'll create a package.json file under your folder and it has a few attributes there that define what this project is going to contain especially if you were turning it into a package that you wanted other people to consume that's where some of these attributes come into the picture so in addition it also allows you to set up some scripts that you can run as npm commands and we'll get to that in a bit so let's start out by creating a folder under a root and call it src which stands for source now under the source folder we're going to create another file a javascript file and we're going to call it index dot js usually in webstorm and i think most ides if you leave out the extension it'll automatically create it and let us simply type in a console.log statement here and we will call it hello world i'm going to save this file and then go down to the console and i can run it by typing in node and then pointing to the file so it's under the source folder slash index.js and there you go you will see print hello world so pretty much it has executed this file that we created very simple now let's make this a little more uh let's add a helpful command to to our package.json so that we don't have to keep pointing to the file and typing in node uh source index so what i'm going to do is modify the scripts section of package.json i'm going to add a command called start and what we're going to put in there is the exact same command that we typed at the bottom of the window here and this runs relative to the project root i'm going to save that i will clear my console and i'm going to run npm start notice that it tried to run it ran our command here and then you'll see the output at the bottom so start and test are two commands that you can run via an npm without an intermediate keyword called run so normally most of the commands require you to type in npm run and then the name of the command so npm run start works as well except for node made it a little easier sorry npm made it a little easier by allowing us to just do npm start very well i'm going to switch back to our presentation window here all right so hopefully everyone's caught on to that next let's get started with express express is an npm package and it is basically a lightweight web server what that means is it's taken all the node.js http classes and added a layer on top of it so that it can communicate or so that it allows you to communicate via restful endpoints let's start out by installing the express dependency and then we're going to reference the library and create a very basic express application so going back to the console here i'm going to type in npm install express and if you're using npm version 5 and above it automatically saves it to your package.json so look in my package.json here and you'll notice that there's a dependencies section that showed up and what this means is that when the project is running it's going to have express available to it next we're going to switch over to the index.js and you can get rid of the console log here let's start out by referencing the express library so we're going to type in let express equals to require express next we want to create an application so we're going to call it app equals express and you can open and close brackets and that creates an express application so one of the things we want to do now is have this express application serve some content so let's start out by serving some static files so i'm going to create a folder under under the root and i will call it public this is where we're going to store static resources like html files your images javascript css and things like that so let's create an html file here i'm going to call it index.html let's give it a title and then in the body we'll put in some text save the file and go back to index.js so the way you can serve static content in express is via a function called express dot static so i'm going to tell express to use this specific static file handler this is also known as a middleware and it's built into express so what i can do here is express dot static and then i will pass in the name of the folder that i want to serve content from and that's public this is relative to the root of the project and finally we want express to listen to to a port on the machine so we're going to do something like this actually let's create a variable here and i'll tell you in a moment why so let's call it constant port and we can read this port value from the the environment variable it's something that's defined on the command line before you start the project and or if that's missing we can substitute 3000 for it so i'm going to do process dot env which is environment dot port and then if that does not exist we're going to default to 3000 so i will substitute this 3000 here with the value port and then let's simply output a message that says server i'm going to use these backticks here so i can introduce a variable in there and let's call the server has started on the port that it's actually running on so that way we know where the server is running oops i missed the end there all right so we're going to go back and run the server here again by calling node i'm sorry oh we have the script commands we're going to do npm start and there you go you see that a message that says server has started and notice that the program is still running that's because the the server is running and it's not going to release control until we stop it and the way to stop it is to push control c anyway let's switch over to a browser window and what i'm going to do is try to oops sorry that's 3000 and so there you go you'll see the message that we typed into the html file so this is very simple it allows you to actually put any file in the public folder and you can serve it through through a url here so essentially what this is doing is defaulting to index.html the file that we created so if i type this path it still loads the same content alright so now i'm going to switch back to our slides here and so we've accomplished these things here let's move on to the next which is actually i had a slide here for serving static content so where essentially we created a public folder under root and html file and we configured express to serve that static content now let's get on to something more interesting we're going to create our first api endpoint and api endpoints are usually set up with http verbs so you may have heard about something called a get request and what that's essentially doing is making a call to the server as with the get keyword and the server is responding with some content we'll also talk about a couple of other attributes in that request called request parameters and query parameters so let's head over to webstorm again and what i'm going to do is create a folder under source called routes and then let's create a file called person.js we're going to create what's called a route in express they're basically you can consider them as mini applications and there are advantages to it and i will talk about it in a bit so essentially we want to start out by referencing express here followed by a router from that express instance and then towards the bottom of the file we're going to export that router what that allows us to do is now imported in the index.js file now let's go ahead and add sorry the the route we were talking about earlier and i'm going to call it person so we're making a call to get a person object here and usually a route has a callback method that gets called when you when you make that request so in this case it's going to have two parameters a request and response and then we're going to do something with it so let's do something very simple here express makes things easier for us some of these things you see here are things we would have to code normally and and in this case it allows us to do something very simple like send a message here so let's call this you have requested a person essentially this is a route that we've created that can be accessed via localhost colon 3000 slash person and that's what it's going to respond with now before we go back to the browser and try this we want to go into the index file and then reference that file that we just created so let's call it person route equals require oops and we're going to go into the routes folder slash person you don't need to specify the js extension and then finally we're going to tell express to register this route oops person route all right now notice that we have to go down here now and and stop the server and restart it because it's not going to pick up the changes that we just made automatically anyway so i just restarted the server here we're going to go to the browser again and call that route we just created so localhost 3000 slash person and there you go that's how simple it is to create an api endpoint of course this is a very basic version of that now before we continue i want to do a couple of things here i want to show you how to use this tool called insomnia or you may have installed something called postman so essentially this allows us to test the apis that we are creating so let's go ahead and create a request here i'm going to call it get person and it's a get request you can change this later on so if you get the wrong thing there it's okay you can go up here and change it to a different kind of request one of the things i forgot to mention was that crud operations map to four requests you have the create which happens on a post the read which happens on a get the update happens on put and delete happens on delete so we have a question here when would changes be picked up automatically and when do you need to restart the server coming from rails world wondering about how things are different so we need to set up a a command and a reference library that will monitor our project for changes so we'll do this right after the the insomnia piece we're looking at but the the changes are picked up based off the files that are monitored any sort of a change in that file once it's saved will restart the server is insomnia better than postmen so i i started out using postman and i haven't touched it in a while so i don't recall exactly but from what i remember post insomnia was a lot easier to work with it was much more intuitive in many ways compared to postman i think postman might have improved they do have a lot of advanced features too that i don't think insomnia does but for our purposes here the insomnia works just fine this is actually what i use on a daily basis i haven't gone back to postman in a few years now so we wanted to talk about uh accessing the person route so what i'm gonna do is put in the url for our server and then in this case we're going to call person and then i can either enter or click send here and there you go this allows us to define all the different routes that we've created and test them out over here one of the things that postman lets you do is generate test cases from these routes and and they have additional tooling there so i would definitely encourage everyone to check out both these tools i think postman is definitely valuable sometimes i find it a bit too bloated but they're they're both very similar so in this case i think what uh rest api i'm sorry what get person we allows us to do here in insomnia is also generate some code that we can then test out through node or any other project so i'm going to click on that real quick and then notice that it has a bunch of languages here and so essentially you can pick something so let's say we were doing this in node.js then i have the option of choosing which type of library that it's using to make that request and i generally would choose request because it's the shortest piece of code here and it's essentially sending some attributes here and then making that request to the endpoint and i can copy this and then paste it in my test file and then sort of go on from there all right so that's that let's go back to webstorm and we're going to now talk about setting up a script that allows us to monitor for changes so we don't have to restart the server so the first thing we will do is let's stop the server here we're going to install something called nodemon now there is an alias for install i could just use i instead of install and nodemon is what i want to install now prior to npm5 you had to specify things like save which would save it as a dependency in packet json however in this case because we're using the latest node version npm version we don't need to do that but nodemon is something we're going to run during development only so we would specify either save dev or there's a shortcut for or a short for it which is dash d they both do the same thing so what that's going to do is create a dev dependencies section here in package.json and those dependencies are only available during development time so basically if you were to deploy this through a ci system like circle ci it's going to do npm install when it downloads the project and all that is going to do is install dev dependencies all right so we have nodemon created here um what we're going to do is learn how to use it actually let's just put it in a let's create a command here so we're going to call it start watch and all we have to do is nodemon and point it to a specific folder here actually we can just do the file in this case and so we can run it with npm run remember we need run this time because it's not the start or test command and then that's going to monitor this specific file for changes you can also specify folders to be monitored and things like that and it's going to internally run the startup file and monitor a set of folders these are things you can look up in the documentation as you get acquainted with these uh various libraries all right so let's go back to the slides again sorry this requires me to switch things around a bit so we we talked about a get request next let's focus on a couple other attributes that can be passed through so i'm going to go back to webstorm here into the person.js file so we're going to create a couple more routes around person itself so what i'm going to do is copy and paste this down here and one of the things that we want to be able to do is let's say pass in an additional sort of subroute that can be mapped to a variable so let's call it name and we need to specify a colon before it so express knows that it needs to map that to a variable and this these variables here are available through the request object in a property called params so let's just print that out here i'm going to put a comma there we can do request dot params dot name i'm going to oops sorry i thought this was console.log i'm going to change this to a template so i'm going to do the backticks that allows me to treat this as a variable in my state uh string here and i will close it with the back deck so that basically is the same as doing uh you have requested a person plus uh space plus this all right so let's save this and notice that our server automatically restarted so we're going to go to insomnia and i'm going to create another route here i'm going to duplicate this by right clicking and picking duplicate and then let's call this get person by name and all i have to do in the route here now when as i switch between these it's choosing the right so it's showing you the output for whatever stored there so when i when i make uh changes to get person by name it's not going to affect person so i can go ahead and do that here and let's call it uh let's give it a name here and then i'm going to click send and so it's simply responding back with the parameter that we passed in all right the other thing we can do is so this here is a params object or property on the request object what i also want to do is allow us to pass in a query string which is a query string is basically a query property on the request object all right so the way to accomplish that is simply by checking the query object here so let's let's say we look for request dot query dot let's call it name as well so that's what we're going to pass in then we will do something there else we're going to handle it like we were originally so in this case i'm going to copy this thing over here again from line 16 to line 7 and i'm going to replace params with query that's the only difference really so what this allows me to do is basically pass call something like uh localhost 3000 slash person with what's called a query string so anything after the question mark is basically a part of the query string and it's a key value pair so i could essentially add additional key values here by adding an ampersand so let's say name uh in age equals 20. so this you know we're not doing anything interesting right now we're simply echoing whatever is passed in but this is what that allows and in case of params this allows us to do something like this localhost 3000 slash person slash name so that's the difference here between the two this is part of the route and that is part of the query string all right so i'm going to save this and let's go back to insomnia and in the get person piece i guess we can duplicate this as well again and then i'll call it get person by query string and so all i have to do here now is specify the name and click send there you go so we have three ways of accomplishing the same thing or i'm sorry two ways here by specifying a parameter so this by query string and by uh params so i'm going to rename this just to make it clear so there get person by params all right okay so hopefully this is clear enough so far moving on so we talked about middleware and we set up a middleware earlier called static which is part of express now middleware are simply functions that are executed back to back or serially in the request pipeline so when a request comes in there are a bunch of functions think of it as an array of functions and they execute from the index 0 all the way to the end and each one calls when it's done calls into the next function it has the ability to also modify the request and response objects and pass in additional details downstream or it can also decide to respond and and not call into other functions downstream because maybe uh the incoming request was meant to be handled by that function so i think i covered through all these things here and yeah so let's go ahead and look at some code and see how to do that so the easiest middleware for us to set up is to log every request that comes in so we're going to accomplish that by going into index.js and note that the order in which these handlers are added matters because that's how these middleware functions are pushed onto the the array and executed in that same order so it's possible that um person route sort of is the function that is supposed to serve the request and it ends up ending the resp the the chain of uh functions that are called so we we want to actually print out the incoming request as the first thing so that we can catch everything that comes in so we do that by calling app.use and we're going to set up a a function right in place and middleware functions take three parameters you have the request in response just like the other routes that we created but there's also something called next which is a reference to the next function in the pipeline and in this case let's just console.log a few things here i'm going to use the backticks again let's uh put in a variable here and i'm going to create a new date object and i'm going to call tostring on it which will print a long version of the date and time i believe and then we're going to also let's say uh list out the url that was requested which is under the original url attribute of the request object and we can in the future we'll modify this after a few more changes so i i saved this and what i'm going to do oh the thing i forgot here is that we need to call next after we're done otherwise it's going to break the chain of functions that are called in in that pipeline and essentially if i wanted to just respond from here i would do something like respond.response.com is one way to sort of respond back and then not call next and that will break the pipeline however if i don't respond to it and i don't call next then the user is going to be waiting for that request until it times out so we have to make sure that we call next here and remove the response then all right so what's going to happen here is basically we're gonna see things printed out here uh sorry i'm just taking a look at what's going on here that's probably from what we had up there i'm going to clear my console and let's go ahead and make a request in insomnia so i'm just going to call the same route again and go back to webstorm and notice that there is a a line that's been output here which prints the the the long form of the date time and the the url that was requested so there you go i mean this is a very powerful concept because now you can inject functions that do things for every route in the system and you can choose to ignore it and not do anything and then just pass the control along to the next function in the pipeline all right so going back to our slides here so another thing we can do with these middleware is handle uh 404 and 500 errors and other errors and things like that and so let's let's go through how that's done uh we're going to respond back for 404 let's say with some content initially a string and then we can i can also show you how to to respond with a specific file all right so for a 404 handler all you need to do is add a uh middleware function towards the end of the chain so the express.static is the last thing we have in our chain at the moment and so i'm going to add a middleware function here that's going to take the same request response and next parameters and essentially what this is is is is a handler for the 80404 uh not found or resource not found and what we're going to do here is respond with a status code that says 404 and we're going to send a message it says we think you are lost all right so let's go ahead and test that all we have to do is let's go to chrome in this case and let's let's just put in anything any random string here and hit enter and there you go what happened here was basically there were no middleware functions to handle that request sorry i i missed a question here the question is anecdotally is using the id's terminal slower than running terminal as a separate app so i i don't think so it really comes down to what you are most comfortable with and most efficient with i always shoot to sort of improve my my sort of agility and so depends on you know various factors and in this case it's easier for me to stay within the context of the ide so that i see things that are happening right there because i could have a build process i could have a a test process and then various things right there and i wouldn't have to switch between windows but essentially that's something you could do as well i do use a separate terminal window when i'm using uh vs code because i don't like the integrated terminal there so there is no sort of right answer here it's really your preference i don't think either of them are slow all right so we we handle 404 now we're going to handle error 500 and what that means is we're going to add another handler here so handler for error 500 and so we're going to do app.use now the only difference here is that this takes an error object so it has four parameters compared to the three that we've been using so far and essentially we're going to let's say we're going to print out the arrow to the console so there is a property called stack and then we're going to let's do something different here we're going to go to public the public folder and create a file here and let's call that file 500.html and so we'll simply print something went wrong here all right i'm going to save that file close it and then we want to serve this file as the response instead of some text message so one of the things i need is to reference the path module oops and then i hope you saw that and then go down here and we need to use the send file method that express provides us and we're going to path.join a couple of things one is the root of the folder which is referenced to withdraw underscore underscore door name and i'm sorry that is where the project is running from so the main index file is under source routes and so we're going to go up to um i'm sorry it's not source routes it's on the source so we're going to go up to public which is one folder above and then we're going to um serve 500.html i think i got that right yeah so essentially indexes here the dot dot will tell it to go up to the root and then we're going down to public in 500 html and we're combining that path and then express will look at look up the file reading the contents and send those out with setting the right headers and things like that all right so i saved that and now let's say we did the only way for us to to trigger that is through an error so what i'm going to do is let's go back to the routes file and we're going to create a route here that's going to generate an error for us so i'm going to call it slash person slash error and we're going to do request response so in this handler all we're going to do is throw a new error so what's that what's going to happen is anytime we call this endpoint it's going to trigger some exception and since it's not handled it's going to end up in this part in the 500 error handler all right so i'm gonna save that and then go back to our browser here and then slash person slash error so there you go um i think that's what i printed here uh oh we're not uh responding with that specific error i think uh oh i see what's going on here sorry uh let's let's call this something else i'm just going to call this slash error for now because it's uh conflicting with the other routes here my apologies so that saved it i'm going to go back and we're simply going to type in slash error and so there you go there it's going through the error but it doesn't seem to find the file we're looking for uh so i believe i did something wrong here all right let's go take a look at what's going on here so in send file uh i'm joining their name dot dot slash oh i made a mistake here i need dot dot slash public slide 500 html so let's retry that so going back here to the browser i'm going to refresh that and there you go it's serving the content from that file specifically that we created so we created that method so i could demonstrate how error 500 would work because it only gets triggered when there's an error all right so back to this the slides here and so we've dealt with error pages now let's make this a little more interesting we have an instance of mongodb that we created in m-lab i'm assuming everyone's created that if not you can try that out later but do in order to connect to to mongodb we're going to use something called mongoose which is an orm or an odm it's basically an object data mapper so it allows us to define a model in our application and then store that as is in the database and that's one of the advantages of mongodb because you can store json documents directly without having to define relationships between tables and things like that so there are pros and cons to it but i've been able to build most applications without sql databases in the past few years mainly because you're able to scale your application in many ways it's it may not be the most efficient database out there but it certainly simplifies your development process significantly anyway so let's get connected mongoose connected we're going to do something similar to what we did with uh express so we're going to install the dependency and we're going to reference it and then we're going to focus on creating a crowd api so essentially we're going to define a model uh in mongoose and then we're going to perform the crud operations on that model via the restful endpoints that we create so let's get back into the code all right so i'm going to so notice when we ran into that error it also ended up printing the stack to the console because if this line 24 here i'm going to stop the server clear the console i'm going to npm install mongoose all right and what we're going to do is create a folder on the source called models and on the models let's go ahead and create a model called let's make it a bit different from person let's call it customer so i'm going to create a javascript file and i will call it customer.model.js i usually follow this pattern for naming conventions i separate multiple words with a period and i always keep them lowercase that way it makes it very simple across larger teams so you don't have to think about how to name files and stuff like that all right so let's go ahead and construct this model here so the first thing we want to do is reference mongoose we already installed it so that should be available there and then we're going to we're going to connect to the database in this file itself but ideally it's something that you can take out of this file and have a separate database.js file which will do the connection to the database when the application starts but in the uh essence of time i'm just going to do it here so let's set up some properties for the the database so in my case i have this written down here i'm just going to copy and paste it essentially i have four attributes here pointing to my database server the name of the database the username and password and this is my instance in mlab and so if you go to your database instance in mlab it should give you an option to see all these attributes and the connection string so the next thing i want to do is connect mongoose to the database and this is something we want to do only once at the beginning of the program so i'm going to use backtakes and here's the connection string you will get this from mlab as well but it's it's it's fairly straightforward so you go start with mongodb colon slash and then we're going to specify the user colon password at server slash database so that would be server slash oops database all right so that should generate the uri for connecting to the database and finally let's create so mongoose has two main components to it the first is a schema and the second is called a model which is simply a higher order function that wraps around the schema really it provides you with additional methods that you can use to make database queries and things like that so let's define a customer schema next and the way you do that is by creating a new instance of mongoose.schema and let me sorry uh if you were not able to read this there you go so within the the customer schema that we're defining uh let's create a couple of attributes there we're gonna create an attribute called name and we're going to tell it that the type is string and then the next thing is let's create something called email let's uh instead of assigning it directly to string i'm going to show you a couple other things you can do here so we can also assign a an object as a value there and define additional properties on there so we're going to tell it that the type here is a string and then it's a required property and that it has to be unique that way we don't end up with duplicates and this validation is actually done on the application layer itself so database is not doing the validation there that's the advantage of using mongoose because is chemo-less and unless you explicitly configure some rules in mongodb it does not do any validation all right so now we have the customer schema we're going to create a model and export it at the same time so we're going to do module.exports equals mongoose dot model and then the first um attribute is going to be the name of the model and then followed by the reference to the schema object okay so let's do a quick recap here we referenced mongoose i defined some attributes some variables here that help us construct the database connection string and then we're connecting to the database and we're defining a customer schema we have two attributes in there name which is a simple string and the email attribute has additional properties on it which sorry i missed a d here so it's supposed to be required so essentially we're telling it that it needs to be unique and it must be present and then finally we export it as a mongoose model all right so i'm going to save this and we're going to create a route that's going to expose crowd operations and we're going to reference this customer model and then make some entries in the database and retrieve those and things like that so i'm going to go into the routes folder and then create a javascript file called um let's just call it customer.js and i'm going to switch to person quickly here essentially this is what we want to do we're just going to have to type it sort of all over again but let's do it from scratch so we're going to start out with referencing the customer model so let's do like customer model equals require and it's one folder above slash models slash customer dot model and then we also want to reference express oops and then we want to reference create the router instance from that express reference all right so let's let's create a route that will allow us to create a new customer so here we will create a new customer and we're going to create what's called a post method and notice that the the type of uh operation you're trying to define the verb itself is available as a method in express so on post we're going to call it slash customer so what this will allow us to do is call into localhost 3000 slash customer and we're going to make a post request to it and then there's a handler with request response that we're going to deal with here uh so one of the things we need to do is when we're passing in the data for creating the customer object we have we're going to pass it in the body as a json object now express does not know how to handle that by default so we need to tell it what to do with it so essentially we're going to go back to index.js and there is a a package we need to install for it called body parser and so let's go into the console and we're going to do npm install body dash part parser and what that's going to do is essentially look at the incoming request and if it is if the content type of that request is application slash json basically that that means that the the data in the body is a json string the in that case the body parser will will take that string convert it to json and write or create a property in the request object called body and then set the value there so essentially it's doing the work for us to parse that piece out so let's see how that works here so we're going to reference body parser and we're going to let's do this as the first thing coming in uh mainly because then we can print whatever is being sent in our logger there all right so we're going to do app.use and in this case we wanted to use the json module so it's essentially taking in any incoming json string and creating an attribute called body so essentially what that lets us do is i can also we can also print the body if any that's converted by this body parser all right so i'm going to save that and then go back to our customer js file so what happens here is that now we have access to request.body before adding the body parser that didn't exist so we would have to look at the raw data and then the content type and then you know if it was json and all that stuff then we'd have to kind of extract the right pieces and and end up constructing that so body parts has taken care of that for us that's the power of express it has so many different kinds of plugins and middleware that most of your application can be composed of these middleware libraries and you can of course write your own in certain cases so in in this case what we want to do is let's make sure that request.body exists so we're going to first check for that and remove that comment and essentially oops if it does not exist we want to return a response with a status code of 400 which means it's a bad request and send a string with that response and let's say we tell it that request the body is missing so the the recipient the caller sort of knows what's wrong exactly here now in terms of the status messages there's obviously a package out there i think it's called http status which has a bunch of these status codes defined as enumerations so you could refer to it by the text name itself instead of the number and i would recommend using that in a real world project now if the body is present then now we want to create an instance of the customer model and save it to the database so let's do that here with um referencing the customer model and uh request so we're going to pass in whatever oops was part of the request body and construct that model there essentially what we're going to pass here is something like this let let's say user equal to uh we need a name you know so this is first name last name whatever and then email you know email gmail.com the incoming object is going to be something like this so that's what we're going to pass through over here and we'll get to how to send that as well in insomnia all right so the next thing i want to do is save that model and essentially that will communicate from mongoose to the driver which is going to then talk to database and tell it to take these details the the the request.body object and validate it via the customer model and save it to the database so we're going to use promises here to sort of follow up on this request so after we save we're going to call then and then is going to i believe respond with the document that it saved and so what we're going to do is if we weren't able to save the document or it's an array of documents i believe or if document.length is zero then we want to respond with an error so let's say it's an internal server error and we're going to uh send that document we should be null in this case or an empty array and if that's not the case then we want to respond with a status code of 201 which stands for resource was created now this is sort of optional in a way you could have responded with 200 as well but that that's where sort of rest sort of defines the guidelines you know for how things should be constructed that's up to you as the programmer as the developer to to figure out to design the system and and figure out what these response codes will be and then you need to document it as part of your api that people will use to access your your uh restful api so here i'm going to respond back with the document that we just created and then finally we can also catch any exceptions and so if there were any errors those will be caught here and so we'll sort of do the same thing as above respond with an error code there and then instead of send we're going to call jason which is going to take in the error object and and transform it and send it over instead of a specific message this kind of gives us more details now it's up to you how you want to respond you know in your projects and stuff all right so that should complete the customer creation process i'm assuming we've done everything right here let's uh run the project here via npm run start watch all right so it's up and running we're going to switch over to insomnia and we're going to create a new request i'm going to call it post customer and i accidentally set it to get here but we're going to switch that over to a post and then i'm going to call into our endpoint here customer and let's see what happens if i click send so we get an error there and guess what we forgot to add this to the routes here so we need to reference that i'm going to get rid of the spaces here so that these are sort of organized nicely so we're going to reference the let's do it right by this other route here we're going to call it customer route equals require dot slash routes slash customer and then we're going to tell it to use the rod here as well so we it's going to register that and you need to be careful about the order as well essentially you could mess things up by having an incorrect order where something might be returning earlier than you expected to anyway so i views i think this so sometimes uh nodemon will crash and it may not restart so at that point what you can do is in your console you can type in rs which tells it to restart and what's happening over here line 16 it does not like this because i think i missed something here in customer gs yep so we're not um i believe we're not exporting that router so that's what we want to do here so module dot exports equals router there you go now it's going to okay so server started now so a couple of things we had missed one was to export the module and the other was to actually import it and then tell express to to register those routes so let's go back to insomnia and okay so we're going to click send here again so notice earlier it said we think you are lost that's because it did not recognize that route and it and the 404 handler the the resource not found handler kicked in and you can see here the error code that was sent back so let's click send here again now i get an internal server error and it's giving us some details here so we had responded with the entire error object we could have simply responded with let's say the message here but in our case we were showing the uh we were returning everything so we know what's going on here so let's uh change things around here in this post request so the body part i'm going to click on the drop down here is going to be of type json and then in there we're going to pass in an object which has name let's call it thomas anderson and then we have an email now if i omitted the email it would still complain about it too because it's going to validate on the server side so let's call it honest.gmail.com and essentially i can when i click send here it says 201 created and it's going to be responding with what create created internally it's generating an id for it as well and it also tracks the version as you update the object all right so that was it and for creating the the entry in the database let's verify by going to robo3t now assuming you've connected everything here we're going to have a collection called customers express will i'm sorry mongoose will pluralize model names so customer ends up becoming customers i'm going to double click this and that opens a new tab there and there you go it's going to show you a record that was created so we had added these entries in there when we posted to the route so there you go that was that simple i'm sure you may not remember a few things at this point but that is okay you know a little bit of practice and then looking through documentation and other tutorials will definitely help you understand this better so let's go back to the customer route i'm going to uh go to the post here and so we were ensuring that a body was present we could have also sort uh checked for other attributes being present so as part of body we could have checked something like if not request.body.email right and then i could have done something here and responded however the customer model is actually validating some of that for us so if things were missing here that the customer model expected like email for instance then this catch block would be triggered and we would still get an error so that's one of the advantages of using mongoose anyway so let's quickly add a couple other methods here so we're going to next add the ability to retrieve uh this data so we're going to create an endpoint called customer uh to get the customer we're going to have the same format here again request response and one of the things we're going to do here is we're expecting an email so we're going to look up the customer via email so we're going to create we're going to actually use the customer model directly and the model gives us a few methods on it that allow us to search through a query through the content in this case so we're going to call a method called find one and mongoose has a very rich api it has a ton of functions that definitely are way out of scope for for this workshop but i would encourage you to look at their documentation there are also lots of interesting articles out there that'll highlight some of those but anyway in this case we're going to use find one and find one takes an object with attributes as the query parameter so in this case we're going to pass in the email which we're expecting via query.email for instance and then of course we want to make sure that it exists up here so we're going to check for request of query.email if that's not present we're going to respond with oops return respond with a status code of 400 resource i'm sorry uh 400 isn't there um and we're going to tell it that it it's missing url parameters so let's do send missing url parameter email that's required so that's going to exit out of there if not we should also have our document available on on the then method that gets called and what we can do is respond to the request with that document if there is an error we want to handle that here in the catch block and essentially respond back with the status code of 500 with this error object and that should return the model there i'm going to quickly add a couple of these other methods since we're almost out of time here so the the other is put that allows us to update the existing customer and all these have a similar format what i'm going to do is i will copy some of these elements here um and then just paste it there essentially i could uh i could use some of this or use some of that so we have request response and in this body here uh we're going to actually need the email piece as well so we're going to check that there is a an email present in the query if not we're going to call a method on the model called find one and update and essentially it's going to query based of this and then it takes another parameter which is your body in this case so let's call into that that would be request.body and oops buddy and then you know you can pass an options object in this case the options basically one of the options we're going to pass it is to return the newly created or updated object otherwise it returns the same it would return the same request body that you sent in but since we want to make sure that the change actually went through uh we want to do that set that attribute i have a typo here so i'm going to change that to status and then so this was your post request this is your get request and then this is your update request so the you and the crud and uh customer sorry i have a few typos here all right so that that that will update the the existing object via a match on the email and then finally we want to be able to delete so that would be router.delete and again very similar to this i'm just going to copy paste that part of the code as well so essentially you're calling into customer we're going to make sure that email exists and then there is a method called find one and remove which will take in your email and then we we don't need the request body and the new pieces from uh above that we copied and everything else here stays the same again um all right so i think that that covers the basic crud operations and let's go into uh insomnia and test it so let's go down let's make sure the terminal is still okay the project is still working fine i'm going to switch over to insomnia and then i'm going to duplicate this and call it put customer and essentially this method should be put and we're expecting a query string called email so we're going to pass an email equals thomas gmail.com and then we're going to send in the body here let's call it thomas updated anderson and we're going to click send here and there you go it responded with an ok and if you notice the the object that it responded with is the the newly created object and i think i made a mistake earlier when i mentioned that it responds with request our body what i meant to say was a response with the original object that it it finds and not the updated object so let's duplicate this again and there is we want to get customer in this case and we're going to call that get here and essentially want to get this by again via email so let's call this thomas gmail.com and then we don't need a json body here so we're going to delete that and you can leave that as is and then if we click send here it's going to retrieve whatever was sent in and finally i'm going to duplicate that again and call this delete customer and so change that again to delete and essentially the query string stays the same i should be able to hit send and then it says okay it's responding with what was deleted let's say if i were to click send again it's going to respond with a null because that object has been deleted already so let's verify that by going into robo3t so here i can either if you're in windows you can do control r on a mac it's command r and if i refresh it you'll notice that the record has disappeared now so most of those other methods were very similar in terms of the the restful uh setup as well as uh you know the attributes that were coming in and things that we were modifying and stuff like that so let's do a quick recap here we created a customer model which is part of the customer model js file uh you're familiar with this by now and so we reference that in customer js that's our route and essentially we're creating a route here the first piece is a create operation that's handled via the post verb and it's calling into customer we're expecting a body to be passed in we added the reference to a body parser middleware for express which actually gives us that data that's passed in the body attribute this was just an example here that we could check for an email to exist on that body as well there's obviously a lot of error handling that you can do to make this more robust and essentially the object coming in will look something like this that we're simply passing through to the customer model so we create a new instance of the customer model with that incoming json object and we call save on that model and then basically uh there are two uh methods here on the uh sorry uh this is using promises so promises have then and catch and so we're handling uh you know different error conditions and then what not here so this is pretty straightforward here i think the important piece is how to create that route and how to respond you want to make sure you're passing back the right error codes and things like that or status codes and things like that get request was very similar you know you change the verb here the method name the maps to get um similar things here just the method on your customer model changes so essentially that was like the the only big change between all the other methods on the route so you have get and on update you have find one update and for delete you have find one and remove so i think that that about wraps this up i think that there was a lot of content that we crammed into this hour and a half and sorry if someone says as a pure database person your brain hurts i apologize it's it's a lot of moving pieces here and if you don't get it it's okay don't feel bad it took me a long time to really understand this and master it these things take time just because of you know changing apis and and uh also the variety of functions that they expose so i want to do something real quick here before we end so i'm going to um clear my console here and now we have our application here we have a package.json that defines the project and and the scripts and things like that there is a service called now.sh that essentially allows you to make to deploy your node.js applications real quick and so i will let you explore this but what i'm going to do is simply deploy this to the cloud now and so what i need to do is go into my application folder and i type in now i have the now client installed via npm as a global and they have all the instructions here on on this site but i simply want to show you how easy it is for us to get this up and running in the cloud since i'm using the free version it's asking me a question stating that my application will be public and so essentially what it's doing is it's it's zipping up the application it's making sure that there's a package json that exists it will um upload that to the server side and then it's unzipping it and it is running the npm install command which ends up setting up all the dependencies that we require for the project and here you see it it's done it's giving you a status about what's going on so it um did a bunch of things here uh it's telling you which version of node it's using there is an actual endpoint that it created for us and it's copied into the clipboard it synced all the 10 files it's initializing its build process it ran npm install package.lock.json is something new with npm5 it allows you to replicate the exact versions of libraries that you used and then i guess it was waiting to so internally it's running the npm start command i think one of the things that i missed here in package.js and i want to quickly add is we want to set the the the process environment variable and essentially in index yes we were doing this here for port so we want to make sure we're setting port and it's as easy as going in here and setting port equal to whatever value that we would need but anyway i i think this should be deployed already i think it's copied but i'm going to make sure i copy it again and then we're going to go to the browser and let's put this in there let's see if that works there you go so we quickly got our application up and running in the cloud and since we were using mlab you know it's connected to the database we didn't have to worry about uploading the database or installing a database and things like that of course you would need to to uh have a config file that then looks at the type of environment you're running in development staging test production and then use the appropriate values from there to connect to the appropriate databases but here you go you can actually do this very quickly and play with it once you have your application up and running there's a question here that says do you usually need to use mongoose to access a mongodb and the answer is no you don't that the new mongodb driver is definitely a lot more powerful lately where it allows you to do validations as well you can define a lot of those things several people prefer that approach i personally have been using mongoose for a while so i stick with it because i'm familiar with the api and it provides us with a lot of rich methods to to handle these these uh interfaces into the database and i can also abstract my models out and add specific methods on it to do more complex operations and so it sort of provided a very good plug-in model for that and so yeah the answer is no you don't have to use mongoose but it just simplifies a lot of the process there i did write a couple of articles that might be useful one of them was introduction to mongoose i don't know if i can introduction to mongoose there this one specifically walks you through you know how to use mongoose for mongodb and and check it out see what do you think of it there's also another one i have called building your uh how to build your own react boilerplate this kind of introduces react into the mix but it also walks you through some of these basic building blocks for creating you know express servers and things like that the idea was that most people start out with using some existing boilerplate like create react app for instance but they don't understand the underlying building blocks and that was the idea here to break it down into individual pieces so you understand what's going on now this one of course uses uh webpack version three so i do plan on updating it with version four which is a lot easier uh in case you're you're planning on reading this anyway um i think that about wraps it up i apologize for going 10 minutes over here i think yeah that was it if you have any additional questions please feel free to reach out directly to me or on dev2 you can follow me on twitter at the outlander and i hope this was worth your time i hope you get to play with this further and and make sure you explore all the apis look up the documentation for express for mongoose check out now.sh which will allow you to deploy your application very quickly compared to you know aws and even heroku is pretty fast but now just takes it to a whole new level where all you type is now and it gives you this url with your application and you can map a domain name to it directly and scale very easily and and i have used a ton of cloud providers and and i absolutely love now and would highly recommend it alrighty thank you so much i'm going to pause this session here and hope to hear from you soon byehello and welcome to this workshop on building a rest api with node express and well let's begin with the agenda for today we're going to start with touching upon some of the concepts related to this topic followed by the installation of the environment and we will start with setting up the application before we dive into the crux of this workshop which is to set up a express web server and then we're going to connect it to mongodb via mongoose and i have a bit of a stretch here if we have time i want to show you how to deploy this application using a service called now.sh so let's start with concepts around http rest and apis so what is http it stands for hypertext transfer protocol now hypertext is basically text that can link to other text hence the word hypertext transfer protocol because that's been transferred it's an application layer protocol it's built on top of the tcp ip protocol what that means is it's using tcp ip for communicating but then there's application layer logic on top it pretty much defines all the rules for transferring resources between a client and a server now every http request is executed independently so on the server side it does not have knowledge of any of the requests that came before it and that's what makes http stateless but here's an interesting thing it's built on top of tcp ip which is not stateless so how does that work basically when you send an http request it's issuing a connection via tcp ip to the other side it could be a server or the client and the tcp connection stays connected http will send what it needs to and then it's going to disconnect hence it's known as stateless one of the cool things about http is that you can transfer anything in the body as long as the http headers define what is being transferred so for instance if you have an image versus html file versus a javascript file embedded in your body then you need to specify the content type in the header and that's how the receiving end knows what to do with it now let's talk about rest it stands for representational state transfer it's actually an architectural pattern with design guidelines http is usually the underlying protocol when you're implementing rest but rest can be implemented on other protocols it hasn't been used as much though what http provides us is basically a set of methods that need to be used explicitly by the rest pattern every restful resource has a unique id which makes it interesting because you can reference different things over the internet via specific url now client state is not persisted between requests so that's what rest basically states that we should be doing however that state can be passed along to the server via some attributes that help the server decide how to process that request rest also states that the application should define a caching policy for responses what that means is it allows the client to make a decision on the received content and they can decide to either keep it in their cache and serve it from there for subsequent requests so that it improves the application performance it also dictates that there should be separation of concerns between the clients and servers what that means is the client does not care about what is the memory usage on the server or what the setup is of the hardware and things like that and vice versa that's also a layered system so the client doesn't really know if it's talking directly to the host server or if there are other intermediate servers such as proxy servers or edge cache servers and things like that now let's talk about what an api is it stands for an application programming interface basically you have functions that are defined on the server side and the api tells you what is supported from the server and where the request should be made so essentially it's going to tell you what the the pattern of the urls are that you're going to call in use to call into the server pretty much it's telling you what the format of the request and response is now there's no standard way of writing apis and that's what makes it somewhat powerful but at the same time it's a bit scary because you know every system will vary so much and so that's where rest comes in it provides us with guidelines on how these apis should be constructed you're going to hear about something called a crud operation over and over when you're using rest and all that stands for is it's an acronym for creating reading updating and deleting records so essentially when you're making a call over an api you're performing one of those four operations anyway let's get started with the installation i had a note about this in the workshop description so hopefully you are all set up with this but i quickly want to touch upon what this entails so we need an ide where we're going to write code you need node.js installed usually npm is part of the node.js installation so you should be good there we're going to use an instance of a database in the cloud via mlab.com and then one of the things i mentioned forgot to mention was that we need a rest client i'll get into the details there something like insomnia or postman and then finally robo3t which allows us to look at the data in so as for the ide you have three different options vs code atom and webstorm that i would recommend but there are a ton of ideas out there you want to find something that's going to help you with the language and the framework that you're working with and all three of these are very powerful and customizable as far as node.js is concerned you can get any latest version of node.js and we should be good that should have the latest package manager there is a subtle difference so if you have version 5 you don't need to use the save command because it automatically saves everything in the package when we install any of the packages and then as far as coding today we're going to use the natively supported es6 and 7 that's available in node that way we don't have to set up babel or any other transpilers if you can go to node.green you'll notice that it lists out all the features that are supported by node and this gives you a good idea of which version supports what feature in es6 and 7. sorry we're trying to figure out the video here and some reason it's not running just give me a moment here um i'm not sure what's going on there leanna anyway let's continue for now so mongodb can be installed locally or you can get an instance via the mlab cloud and at the same time if you are a fan of docker you can use docker to deploy it somewhere or or install it locally as well we're going to use mlab for this workshop because it allows us to easily deploy the application and not worry about a installation during deployment as far as the rest line goes we're gonna use it to test the api that we build and i prefer insomnia because it's pretty lightweight but postman is also very powerful now i got a question here about if i have any experience with webstorm and what do i think of it so i've used several ides over the years years actually 20 some years and i really love webstorm because it allows you to do things that most of the other ids require you to configure it from scratch like vs code for instance there's one subtle aspect of vs code that i dislike compared to webstorm and that is you cannot get multiple console windows in a tabular view they have sort of a drop down and so you can quickly switch between those windows and i'm sure there's a plug-in out there but i haven't found that yet as far as sorry there's another question here which says things like mlab seem way more popular in node world do you have any thoughts over why this is the case compared to other ecosystems i believe is an integral component of most node applications mainly because you're coding in javascript all the way from the browser to the back end and it lends itself very well to as well because you're storing javascript objects or json and then that what that means is you don't have to go through conversions uh for your data compared to other databases now using m-lab specifically they have a very good interface and they provide you with a free starter database that you can uh get everything up and running within a minute literally so it's naturally the preferred option because it saves you a lot of time from having to configure it getting back to this if you guys can download insomnia or postman you should be able to follow along with testing the api now as far as getting started we need to set up the application first so that we can start to code the apis so we're going to start with creating a project folder and then you will open up your ide either whatever it is you're using in that project folder and then we'll start to construct other subfolders and files there so what i'm going to do is i have a slide outlining what we're going to accomplish and so i will keep switching between the slide and webstorm as we complete these tasks so in this case we are initializing our node and then creating a very very basic hello world script actually and we're going to set up some startup scripts that allow us to run our application and then we'll build from there so here is my webstorm instance i have a folder that's created here what i'm going to do is in the console at the bottom here i'm not sure if i can increase the font in the console but i will in the code what i'm going to type is npm init and i just want to make sure i'm in the correct folder here i am okay so i will type an npm init and then i will provide an option optional parameter called dash y which stands for simply don't ask me any questions just generate the the package.json file this is what npm minute will do is it'll create a package.json file under your folder and it has a few attributes there that define what this project is going to contain especially if you were turning it into a package that you wanted other people to consume that's where some of these attributes come into the picture so in addition it also allows you to set up some scripts that you can run as npm commands and we'll get to that in a bit so let's start out by creating a folder under a root and call it src which stands for source now under the source folder we're going to create another file a javascript file and we're going to call it index dot js usually in webstorm and i think most ides if you leave out the extension it'll automatically create it and let us simply type in a console.log statement here and we will call it hello world i'm going to save this file and then go down to the console and i can run it by typing in node and then pointing to the file so it's under the source folder slash index.js and there you go you will see print hello world so pretty much it has executed this file that we created very simple now let's make this a little more uh let's add a helpful command to to our package.json so that we don't have to keep pointing to the file and typing in node uh source index so what i'm going to do is modify the scripts section of package.json i'm going to add a command called start and what we're going to put in there is the exact same command that we typed at the bottom of the window here and this runs relative to the project root i'm going to save that i will clear my console and i'm going to run npm start notice that it tried to run it ran our command here and then you'll see the output at the bottom so start and test are two commands that you can run via an npm without an intermediate keyword called run so normally most of the commands require you to type in npm run and then the name of the command so npm run start works as well except for node made it a little easier sorry npm made it a little easier by allowing us to just do npm start very well i'm going to switch back to our presentation window here all right so hopefully everyone's caught on to that next let's get started with express express is an npm package and it is basically a lightweight web server what that means is it's taken all the node.js http classes and added a layer on top of it so that it can communicate or so that it allows you to communicate via restful endpoints let's start out by installing the express dependency and then we're going to reference the library and create a very basic express application so going back to the console here i'm going to type in npm install express and if you're using npm version 5 and above it automatically saves it to your package.json so look in my package.json here and you'll notice that there's a dependencies section that showed up and what this means is that when the project is running it's going to have express available to it next we're going to switch over to the index.js and you can get rid of the console log here let's start out by referencing the express library so we're going to type in let express equals to require express next we want to create an application so we're going to call it app equals express and you can open and close brackets and that creates an express application so one of the things we want to do now is have this express application serve some content so let's start out by serving some static files so i'm going to create a folder under under the root and i will call it public this is where we're going to store static resources like html files your images javascript css and things like that so let's create an html file here i'm going to call it index.html let's give it a title and then in the body we'll put in some text save the file and go back to index.js so the way you can serve static content in express is via a function called express dot static so i'm going to tell express to use this specific static file handler this is also known as a middleware and it's built into express so what i can do here is express dot static and then i will pass in the name of the folder that i want to serve content from and that's public this is relative to the root of the project and finally we want express to listen to to a port on the machine so we're going to do something like this actually let's create a variable here and i'll tell you in a moment why so let's call it constant port and we can read this port value from the the environment variable it's something that's defined on the command line before you start the project and or if that's missing we can substitute 3000 for it so i'm going to do process dot env which is environment dot port and then if that does not exist we're going to default to 3000 so i will substitute this 3000 here with the value port and then let's simply output a message that says server i'm going to use these backticks here so i can introduce a variable in there and let's call the server has started on the port that it's actually running on so that way we know where the server is running oops i missed the end there all right so we're going to go back and run the server here again by calling node i'm sorry oh we have the script commands we're going to do npm start and there you go you see that a message that says server has started and notice that the program is still running that's because the the server is running and it's not going to release control until we stop it and the way to stop it is to push control c anyway let's switch over to a browser window and what i'm going to do is try to oops sorry that's 3000 and so there you go you'll see the message that we typed into the html file so this is very simple it allows you to actually put any file in the public folder and you can serve it through through a url here so essentially what this is doing is defaulting to index.html the file that we created so if i type this path it still loads the same content alright so now i'm going to switch back to our slides here and so we've accomplished these things here let's move on to the next which is actually i had a slide here for serving static content so where essentially we created a public folder under root and html file and we configured express to serve that static content now let's get on to something more interesting we're going to create our first api endpoint and api endpoints are usually set up with http verbs so you may have heard about something called a get request and what that's essentially doing is making a call to the server as with the get keyword and the server is responding with some content we'll also talk about a couple of other attributes in that request called request parameters and query parameters so let's head over to webstorm again and what i'm going to do is create a folder under source called routes and then let's create a file called person.js we're going to create what's called a route in express they're basically you can consider them as mini applications and there are advantages to it and i will talk about it in a bit so essentially we want to start out by referencing express here followed by a router from that express instance and then towards the bottom of the file we're going to export that router what that allows us to do is now imported in the index.js file now let's go ahead and add sorry the the route we were talking about earlier and i'm going to call it person so we're making a call to get a person object here and usually a route has a callback method that gets called when you when you make that request so in this case it's going to have two parameters a request and response and then we're going to do something with it so let's do something very simple here express makes things easier for us some of these things you see here are things we would have to code normally and and in this case it allows us to do something very simple like send a message here so let's call this you have requested a person essentially this is a route that we've created that can be accessed via localhost colon 3000 slash person and that's what it's going to respond with now before we go back to the browser and try this we want to go into the index file and then reference that file that we just created so let's call it person route equals require oops and we're going to go into the routes folder slash person you don't need to specify the js extension and then finally we're going to tell express to register this route oops person route all right now notice that we have to go down here now and and stop the server and restart it because it's not going to pick up the changes that we just made automatically anyway so i just restarted the server here we're going to go to the browser again and call that route we just created so localhost 3000 slash person and there you go that's how simple it is to create an api endpoint of course this is a very basic version of that now before we continue i want to do a couple of things here i want to show you how to use this tool called insomnia or you may have installed something called postman so essentially this allows us to test the apis that we are creating so let's go ahead and create a request here i'm going to call it get person and it's a get request you can change this later on so if you get the wrong thing there it's okay you can go up here and change it to a different kind of request one of the things i forgot to mention was that crud operations map to four requests you have the create which happens on a post the read which happens on a get the update happens on put and delete happens on delete so we have a question here when would changes be picked up automatically and when do you need to restart the server coming from rails world wondering about how things are different so we need to set up a a command and a reference library that will monitor our project for changes so we'll do this right after the the insomnia piece we're looking at but the the changes are picked up based off the files that are monitored any sort of a change in that file once it's saved will restart the server is insomnia better than postmen so i i started out using postman and i haven't touched it in a while so i don't recall exactly but from what i remember post insomnia was a lot easier to work with it was much more intuitive in many ways compared to postman i think postman might have improved they do have a lot of advanced features too that i don't think insomnia does but for our purposes here the insomnia works just fine this is actually what i use on a daily basis i haven't gone back to postman in a few years now so we wanted to talk about uh accessing the person route so what i'm gonna do is put in the url for our server and then in this case we're going to call person and then i can either enter or click send here and there you go this allows us to define all the different routes that we've created and test them out over here one of the things that postman lets you do is generate test cases from these routes and and they have additional tooling there so i would definitely encourage everyone to check out both these tools i think postman is definitely valuable sometimes i find it a bit too bloated but they're they're both very similar so in this case i think what uh rest api i'm sorry what get person we allows us to do here in insomnia is also generate some code that we can then test out through node or any other project so i'm going to click on that real quick and then notice that it has a bunch of languages here and so essentially you can pick something so let's say we were doing this in node.js then i have the option of choosing which type of library that it's using to make that request and i generally would choose request because it's the shortest piece of code here and it's essentially sending some attributes here and then making that request to the endpoint and i can copy this and then paste it in my test file and then sort of go on from there all right so that's that let's go back to webstorm and we're going to now talk about setting up a script that allows us to monitor for changes so we don't have to restart the server so the first thing we will do is let's stop the server here we're going to install something called nodemon now there is an alias for install i could just use i instead of install and nodemon is what i want to install now prior to npm5 you had to specify things like save which would save it as a dependency in packet json however in this case because we're using the latest node version npm version we don't need to do that but nodemon is something we're going to run during development only so we would specify either save dev or there's a shortcut for or a short for it which is dash d they both do the same thing so what that's going to do is create a dev dependencies section here in package.json and those dependencies are only available during development time so basically if you were to deploy this through a ci system like circle ci it's going to do npm install when it downloads the project and all that is going to do is install dev dependencies all right so we have nodemon created here um what we're going to do is learn how to use it actually let's just put it in a let's create a command here so we're going to call it start watch and all we have to do is nodemon and point it to a specific folder here actually we can just do the file in this case and so we can run it with npm run remember we need run this time because it's not the start or test command and then that's going to monitor this specific file for changes you can also specify folders to be monitored and things like that and it's going to internally run the startup file and monitor a set of folders these are things you can look up in the documentation as you get acquainted with these uh various libraries all right so let's go back to the slides again sorry this requires me to switch things around a bit so we we talked about a get request next let's focus on a couple other attributes that can be passed through so i'm going to go back to webstorm here into the person.js file so we're going to create a couple more routes around person itself so what i'm going to do is copy and paste this down here and one of the things that we want to be able to do is let's say pass in an additional sort of subroute that can be mapped to a variable so let's call it name and we need to specify a colon before it so express knows that it needs to map that to a variable and this these variables here are available through the request object in a property called params so let's just print that out here i'm going to put a comma there we can do request dot params dot name i'm going to oops sorry i thought this was console.log i'm going to change this to a template so i'm going to do the backticks that allows me to treat this as a variable in my state uh string here and i will close it with the back deck so that basically is the same as doing uh you have requested a person plus uh space plus this all right so let's save this and notice that our server automatically restarted so we're going to go to insomnia and i'm going to create another route here i'm going to duplicate this by right clicking and picking duplicate and then let's call this get person by name and all i have to do in the route here now when as i switch between these it's choosing the right so it's showing you the output for whatever stored there so when i when i make uh changes to get person by name it's not going to affect person so i can go ahead and do that here and let's call it uh let's give it a name here and then i'm going to click send and so it's simply responding back with the parameter that we passed in all right the other thing we can do is so this here is a params object or property on the request object what i also want to do is allow us to pass in a query string which is a query string is basically a query property on the request object all right so the way to accomplish that is simply by checking the query object here so let's let's say we look for request dot query dot let's call it name as well so that's what we're going to pass in then we will do something there else we're going to handle it like we were originally so in this case i'm going to copy this thing over here again from line 16 to line 7 and i'm going to replace params with query that's the only difference really so what this allows me to do is basically pass call something like uh localhost 3000 slash person with what's called a query string so anything after the question mark is basically a part of the query string and it's a key value pair so i could essentially add additional key values here by adding an ampersand so let's say name uh in age equals 20. so this you know we're not doing anything interesting right now we're simply echoing whatever is passed in but this is what that allows and in case of params this allows us to do something like this localhost 3000 slash person slash name so that's the difference here between the two this is part of the route and that is part of the query string all right so i'm going to save this and let's go back to insomnia and in the get person piece i guess we can duplicate this as well again and then i'll call it get person by query string and so all i have to do here now is specify the name and click send there you go so we have three ways of accomplishing the same thing or i'm sorry two ways here by specifying a parameter so this by query string and by uh params so i'm going to rename this just to make it clear so there get person by params all right okay so hopefully this is clear enough so far moving on so we talked about middleware and we set up a middleware earlier called static which is part of express now middleware are simply functions that are executed back to back or serially in the request pipeline so when a request comes in there are a bunch of functions think of it as an array of functions and they execute from the index 0 all the way to the end and each one calls when it's done calls into the next function it has the ability to also modify the request and response objects and pass in additional details downstream or it can also decide to respond and and not call into other functions downstream because maybe uh the incoming request was meant to be handled by that function so i think i covered through all these things here and yeah so let's go ahead and look at some code and see how to do that so the easiest middleware for us to set up is to log every request that comes in so we're going to accomplish that by going into index.js and note that the order in which these handlers are added matters because that's how these middleware functions are pushed onto the the array and executed in that same order so it's possible that um person route sort of is the function that is supposed to serve the request and it ends up ending the resp the the chain of uh functions that are called so we we want to actually print out the incoming request as the first thing so that we can catch everything that comes in so we do that by calling app.use and we're going to set up a a function right in place and middleware functions take three parameters you have the request in response just like the other routes that we created but there's also something called next which is a reference to the next function in the pipeline and in this case let's just console.log a few things here i'm going to use the backticks again let's uh put in a variable here and i'm going to create a new date object and i'm going to call tostring on it which will print a long version of the date and time i believe and then we're going to also let's say uh list out the url that was requested which is under the original url attribute of the request object and we can in the future we'll modify this after a few more changes so i i saved this and what i'm going to do oh the thing i forgot here is that we need to call next after we're done otherwise it's going to break the chain of functions that are called in in that pipeline and essentially if i wanted to just respond from here i would do something like respond.response.com is one way to sort of respond back and then not call next and that will break the pipeline however if i don't respond to it and i don't call next then the user is going to be waiting for that request until it times out so we have to make sure that we call next here and remove the response then all right so what's going to happen here is basically we're gonna see things printed out here uh sorry i'm just taking a look at what's going on here that's probably from what we had up there i'm going to clear my console and let's go ahead and make a request in insomnia so i'm just going to call the same route again and go back to webstorm and notice that there is a a line that's been output here which prints the the the long form of the date time and the the url that was requested so there you go i mean this is a very powerful concept because now you can inject functions that do things for every route in the system and you can choose to ignore it and not do anything and then just pass the control along to the next function in the pipeline all right so going back to our slides here so another thing we can do with these middleware is handle uh 404 and 500 errors and other errors and things like that and so let's let's go through how that's done uh we're going to respond back for 404 let's say with some content initially a string and then we can i can also show you how to to respond with a specific file all right so for a 404 handler all you need to do is add a uh middleware function towards the end of the chain so the express.static is the last thing we have in our chain at the moment and so i'm going to add a middleware function here that's going to take the same request response and next parameters and essentially what this is is is is a handler for the 80404 uh not found or resource not found and what we're going to do here is respond with a status code that says 404 and we're going to send a message it says we think you are lost all right so let's go ahead and test that all we have to do is let's go to chrome in this case and let's let's just put in anything any random string here and hit enter and there you go what happened here was basically there were no middleware functions to handle that request sorry i i missed a question here the question is anecdotally is using the id's terminal slower than running terminal as a separate app so i i don't think so it really comes down to what you are most comfortable with and most efficient with i always shoot to sort of improve my my sort of agility and so depends on you know various factors and in this case it's easier for me to stay within the context of the ide so that i see things that are happening right there because i could have a build process i could have a a test process and then various things right there and i wouldn't have to switch between windows but essentially that's something you could do as well i do use a separate terminal window when i'm using uh vs code because i don't like the integrated terminal there so there is no sort of right answer here it's really your preference i don't think either of them are slow all right so we we handle 404 now we're going to handle error 500 and what that means is we're going to add another handler here so handler for error 500 and so we're going to do app.use now the only difference here is that this takes an error object so it has four parameters compared to the three that we've been using so far and essentially we're going to let's say we're going to print out the arrow to the console so there is a property called stack and then we're going to let's do something different here we're going to go to public the public folder and create a file here and let's call that file 500.html and so we'll simply print something went wrong here all right i'm going to save that file close it and then we want to serve this file as the response instead of some text message so one of the things i need is to reference the path module oops and then i hope you saw that and then go down here and we need to use the send file method that express provides us and we're going to path.join a couple of things one is the root of the folder which is referenced to withdraw underscore underscore door name and i'm sorry that is where the project is running from so the main index file is under source routes and so we're going to go up to um i'm sorry it's not source routes it's on the source so we're going to go up to public which is one folder above and then we're going to um serve 500.html i think i got that right yeah so essentially indexes here the dot dot will tell it to go up to the root and then we're going down to public in 500 html and we're combining that path and then express will look at look up the file reading the contents and send those out with setting the right headers and things like that all right so i saved that and now let's say we did the only way for us to to trigger that is through an error so what i'm going to do is let's go back to the routes file and we're going to create a route here that's going to generate an error for us so i'm going to call it slash person slash error and we're going to do request response so in this handler all we're going to do is throw a new error so what's that what's going to happen is anytime we call this endpoint it's going to trigger some exception and since it's not handled it's going to end up in this part in the 500 error handler all right so i'm gonna save that and then go back to our browser here and then slash person slash error so there you go um i think that's what i printed here uh oh we're not uh responding with that specific error i think uh oh i see what's going on here sorry uh let's let's call this something else i'm just going to call this slash error for now because it's uh conflicting with the other routes here my apologies so that saved it i'm going to go back and we're simply going to type in slash error and so there you go there it's going through the error but it doesn't seem to find the file we're looking for uh so i believe i did something wrong here all right let's go take a look at what's going on here so in send file uh i'm joining their name dot dot slash oh i made a mistake here i need dot dot slash public slide 500 html so let's retry that so going back here to the browser i'm going to refresh that and there you go it's serving the content from that file specifically that we created so we created that method so i could demonstrate how error 500 would work because it only gets triggered when there's an error all right so back to this the slides here and so we've dealt with error pages now let's make this a little more interesting we have an instance of mongodb that we created in m-lab i'm assuming everyone's created that if not you can try that out later but do in order to connect to to mongodb we're going to use something called mongoose which is an orm or an odm it's basically an object data mapper so it allows us to define a model in our application and then store that as is in the database and that's one of the advantages of mongodb because you can store json documents directly without having to define relationships between tables and things like that so there are pros and cons to it but i've been able to build most applications without sql databases in the past few years mainly because you're able to scale your application in many ways it's it may not be the most efficient database out there but it certainly simplifies your development process significantly anyway so let's get connected mongoose connected we're going to do something similar to what we did with uh express so we're going to install the dependency and we're going to reference it and then we're going to focus on creating a crowd api so essentially we're going to define a model uh in mongoose and then we're going to perform the crud operations on that model via the restful endpoints that we create so let's get back into the code all right so i'm going to so notice when we ran into that error it also ended up printing the stack to the console because if this line 24 here i'm going to stop the server clear the console i'm going to npm install mongoose all right and what we're going to do is create a folder on the source called models and on the models let's go ahead and create a model called let's make it a bit different from person let's call it customer so i'm going to create a javascript file and i will call it customer.model.js i usually follow this pattern for naming conventions i separate multiple words with a period and i always keep them lowercase that way it makes it very simple across larger teams so you don't have to think about how to name files and stuff like that all right so let's go ahead and construct this model here so the first thing we want to do is reference mongoose we already installed it so that should be available there and then we're going to we're going to connect to the database in this file itself but ideally it's something that you can take out of this file and have a separate database.js file which will do the connection to the database when the application starts but in the uh essence of time i'm just going to do it here so let's set up some properties for the the database so in my case i have this written down here i'm just going to copy and paste it essentially i have four attributes here pointing to my database server the name of the database the username and password and this is my instance in mlab and so if you go to your database instance in mlab it should give you an option to see all these attributes and the connection string so the next thing i want to do is connect mongoose to the database and this is something we want to do only once at the beginning of the program so i'm going to use backtakes and here's the connection string you will get this from mlab as well but it's it's it's fairly straightforward so you go start with mongodb colon slash and then we're going to specify the user colon password at server slash database so that would be server slash oops database all right so that should generate the uri for connecting to the database and finally let's create so mongoose has two main components to it the first is a schema and the second is called a model which is simply a higher order function that wraps around the schema really it provides you with additional methods that you can use to make database queries and things like that so let's define a customer schema next and the way you do that is by creating a new instance of mongoose.schema and let me sorry uh if you were not able to read this there you go so within the the customer schema that we're defining uh let's create a couple of attributes there we're gonna create an attribute called name and we're going to tell it that the type is string and then the next thing is let's create something called email let's uh instead of assigning it directly to string i'm going to show you a couple other things you can do here so we can also assign a an object as a value there and define additional properties on there so we're going to tell it that the type here is a string and then it's a required property and that it has to be unique that way we don't end up with duplicates and this validation is actually done on the application layer itself so database is not doing the validation there that's the advantage of using mongoose because is chemo-less and unless you explicitly configure some rules in mongodb it does not do any validation all right so now we have the customer schema we're going to create a model and export it at the same time so we're going to do module.exports equals mongoose dot model and then the first um attribute is going to be the name of the model and then followed by the reference to the schema object okay so let's do a quick recap here we referenced mongoose i defined some attributes some variables here that help us construct the database connection string and then we're connecting to the database and we're defining a customer schema we have two attributes in there name which is a simple string and the email attribute has additional properties on it which sorry i missed a d here so it's supposed to be required so essentially we're telling it that it needs to be unique and it must be present and then finally we export it as a mongoose model all right so i'm going to save this and we're going to create a route that's going to expose crowd operations and we're going to reference this customer model and then make some entries in the database and retrieve those and things like that so i'm going to go into the routes folder and then create a javascript file called um let's just call it customer.js and i'm going to switch to person quickly here essentially this is what we want to do we're just going to have to type it sort of all over again but let's do it from scratch so we're going to start out with referencing the customer model so let's do like customer model equals require and it's one folder above slash models slash customer dot model and then we also want to reference express oops and then we want to reference create the router instance from that express reference all right so let's let's create a route that will allow us to create a new customer so here we will create a new customer and we're going to create what's called a post method and notice that the the type of uh operation you're trying to define the verb itself is available as a method in express so on post we're going to call it slash customer so what this will allow us to do is call into localhost 3000 slash customer and we're going to make a post request to it and then there's a handler with request response that we're going to deal with here uh so one of the things we need to do is when we're passing in the data for creating the customer object we have we're going to pass it in the body as a json object now express does not know how to handle that by default so we need to tell it what to do with it so essentially we're going to go back to index.js and there is a a package we need to install for it called body parser and so let's go into the console and we're going to do npm install body dash part parser and what that's going to do is essentially look at the incoming request and if it is if the content type of that request is application slash json basically that that means that the the data in the body is a json string the in that case the body parser will will take that string convert it to json and write or create a property in the request object called body and then set the value there so essentially it's doing the work for us to parse that piece out so let's see how that works here so we're going to reference body parser and we're going to let's do this as the first thing coming in uh mainly because then we can print whatever is being sent in our logger there all right so we're going to do app.use and in this case we wanted to use the json module so it's essentially taking in any incoming json string and creating an attribute called body so essentially what that lets us do is i can also we can also print the body if any that's converted by this body parser all right so i'm going to save that and then go back to our customer js file so what happens here is that now we have access to request.body before adding the body parser that didn't exist so we would have to look at the raw data and then the content type and then you know if it was json and all that stuff then we'd have to kind of extract the right pieces and and end up constructing that so body parts has taken care of that for us that's the power of express it has so many different kinds of plugins and middleware that most of your application can be composed of these middleware libraries and you can of course write your own in certain cases so in in this case what we want to do is let's make sure that request.body exists so we're going to first check for that and remove that comment and essentially oops if it does not exist we want to return a response with a status code of 400 which means it's a bad request and send a string with that response and let's say we tell it that request the body is missing so the the recipient the caller sort of knows what's wrong exactly here now in terms of the status messages there's obviously a package out there i think it's called http status which has a bunch of these status codes defined as enumerations so you could refer to it by the text name itself instead of the number and i would recommend using that in a real world project now if the body is present then now we want to create an instance of the customer model and save it to the database so let's do that here with um referencing the customer model and uh request so we're going to pass in whatever oops was part of the request body and construct that model there essentially what we're going to pass here is something like this let let's say user equal to uh we need a name you know so this is first name last name whatever and then email you know email gmail.com the incoming object is going to be something like this so that's what we're going to pass through over here and we'll get to how to send that as well in insomnia all right so the next thing i want to do is save that model and essentially that will communicate from mongoose to the driver which is going to then talk to database and tell it to take these details the the the request.body object and validate it via the customer model and save it to the database so we're going to use promises here to sort of follow up on this request so after we save we're going to call then and then is going to i believe respond with the document that it saved and so what we're going to do is if we weren't able to save the document or it's an array of documents i believe or if document.length is zero then we want to respond with an error so let's say it's an internal server error and we're going to uh send that document we should be null in this case or an empty array and if that's not the case then we want to respond with a status code of 201 which stands for resource was created now this is sort of optional in a way you could have responded with 200 as well but that that's where sort of rest sort of defines the guidelines you know for how things should be constructed that's up to you as the programmer as the developer to to figure out to design the system and and figure out what these response codes will be and then you need to document it as part of your api that people will use to access your your uh restful api so here i'm going to respond back with the document that we just created and then finally we can also catch any exceptions and so if there were any errors those will be caught here and so we'll sort of do the same thing as above respond with an error code there and then instead of send we're going to call jason which is going to take in the error object and and transform it and send it over instead of a specific message this kind of gives us more details now it's up to you how you want to respond you know in your projects and stuff all right so that should complete the customer creation process i'm assuming we've done everything right here let's uh run the project here via npm run start watch all right so it's up and running we're going to switch over to insomnia and we're going to create a new request i'm going to call it post customer and i accidentally set it to get here but we're going to switch that over to a post and then i'm going to call into our endpoint here customer and let's see what happens if i click send so we get an error there and guess what we forgot to add this to the routes here so we need to reference that i'm going to get rid of the spaces here so that these are sort of organized nicely so we're going to reference the let's do it right by this other route here we're going to call it customer route equals require dot slash routes slash customer and then we're going to tell it to use the rod here as well so we it's going to register that and you need to be careful about the order as well essentially you could mess things up by having an incorrect order where something might be returning earlier than you expected to anyway so i views i think this so sometimes uh nodemon will crash and it may not restart so at that point what you can do is in your console you can type in rs which tells it to restart and what's happening over here line 16 it does not like this because i think i missed something here in customer gs yep so we're not um i believe we're not exporting that router so that's what we want to do here so module dot exports equals router there you go now it's going to okay so server started now so a couple of things we had missed one was to export the module and the other was to actually import it and then tell express to to register those routes so let's go back to insomnia and okay so we're going to click send here again so notice earlier it said we think you are lost that's because it did not recognize that route and it and the 404 handler the the resource not found handler kicked in and you can see here the error code that was sent back so let's click send here again now i get an internal server error and it's giving us some details here so we had responded with the entire error object we could have simply responded with let's say the message here but in our case we were showing the uh we were returning everything so we know what's going on here so let's uh change things around here in this post request so the body part i'm going to click on the drop down here is going to be of type json and then in there we're going to pass in an object which has name let's call it thomas anderson and then we have an email now if i omitted the email it would still complain about it too because it's going to validate on the server side so let's call it honest.gmail.com and essentially i can when i click send here it says 201 created and it's going to be responding with what create created internally it's generating an id for it as well and it also tracks the version as you update the object all right so that was it and for creating the the entry in the database let's verify by going to robo3t now assuming you've connected everything here we're going to have a collection called customers express will i'm sorry mongoose will pluralize model names so customer ends up becoming customers i'm going to double click this and that opens a new tab there and there you go it's going to show you a record that was created so we had added these entries in there when we posted to the route so there you go that was that simple i'm sure you may not remember a few things at this point but that is okay you know a little bit of practice and then looking through documentation and other tutorials will definitely help you understand this better so let's go back to the customer route i'm going to uh go to the post here and so we were ensuring that a body was present we could have also sort uh checked for other attributes being present so as part of body we could have checked something like if not request.body.email right and then i could have done something here and responded however the customer model is actually validating some of that for us so if things were missing here that the customer model expected like email for instance then this catch block would be triggered and we would still get an error so that's one of the advantages of using mongoose anyway so let's quickly add a couple other methods here so we're going to next add the ability to retrieve uh this data so we're going to create an endpoint called customer uh to get the customer we're going to have the same format here again request response and one of the things we're going to do here is we're expecting an email so we're going to look up the customer via email so we're going to create we're going to actually use the customer model directly and the model gives us a few methods on it that allow us to search through a query through the content in this case so we're going to call a method called find one and mongoose has a very rich api it has a ton of functions that definitely are way out of scope for for this workshop but i would encourage you to look at their documentation there are also lots of interesting articles out there that'll highlight some of those but anyway in this case we're going to use find one and find one takes an object with attributes as the query parameter so in this case we're going to pass in the email which we're expecting via query.email for instance and then of course we want to make sure that it exists up here so we're going to check for request of query.email if that's not present we're going to respond with oops return respond with a status code of 400 resource i'm sorry uh 400 isn't there um and we're going to tell it that it it's missing url parameters so let's do send missing url parameter email that's required so that's going to exit out of there if not we should also have our document available on on the then method that gets called and what we can do is respond to the request with that document if there is an error we want to handle that here in the catch block and essentially respond back with the status code of 500 with this error object and that should return the model there i'm going to quickly add a couple of these other methods since we're almost out of time here so the the other is put that allows us to update the existing customer and all these have a similar format what i'm going to do is i will copy some of these elements here um and then just paste it there essentially i could uh i could use some of this or use some of that so we have request response and in this body here uh we're going to actually need the email piece as well so we're going to check that there is a an email present in the query if not we're going to call a method on the model called find one and update and essentially it's going to query based of this and then it takes another parameter which is your body in this case so let's call into that that would be request.body and oops buddy and then you know you can pass an options object in this case the options basically one of the options we're going to pass it is to return the newly created or updated object otherwise it returns the same it would return the same request body that you sent in but since we want to make sure that the change actually went through uh we want to do that set that attribute i have a typo here so i'm going to change that to status and then so this was your post request this is your get request and then this is your update request so the you and the crud and uh customer sorry i have a few typos here all right so that that that will update the the existing object via a match on the email and then finally we want to be able to delete so that would be router.delete and again very similar to this i'm just going to copy paste that part of the code as well so essentially you're calling into customer we're going to make sure that email exists and then there is a method called find one and remove which will take in your email and then we we don't need the request body and the new pieces from uh above that we copied and everything else here stays the same again um all right so i think that that covers the basic crud operations and let's go into uh insomnia and test it so let's go down let's make sure the terminal is still okay the project is still working fine i'm going to switch over to insomnia and then i'm going to duplicate this and call it put customer and essentially this method should be put and we're expecting a query string called email so we're going to pass an email equals thomas gmail.com and then we're going to send in the body here let's call it thomas updated anderson and we're going to click send here and there you go it responded with an ok and if you notice the the object that it responded with is the the newly created object and i think i made a mistake earlier when i mentioned that it responds with request our body what i meant to say was a response with the original object that it it finds and not the updated object so let's duplicate this again and there is we want to get customer in this case and we're going to call that get here and essentially want to get this by again via email so let's call this thomas gmail.com and then we don't need a json body here so we're going to delete that and you can leave that as is and then if we click send here it's going to retrieve whatever was sent in and finally i'm going to duplicate that again and call this delete customer and so change that again to delete and essentially the query string stays the same i should be able to hit send and then it says okay it's responding with what was deleted let's say if i were to click send again it's going to respond with a null because that object has been deleted already so let's verify that by going into robo3t so here i can either if you're in windows you can do control r on a mac it's command r and if i refresh it you'll notice that the record has disappeared now so most of those other methods were very similar in terms of the the restful uh setup as well as uh you know the attributes that were coming in and things that we were modifying and stuff like that so let's do a quick recap here we created a customer model which is part of the customer model js file uh you're familiar with this by now and so we reference that in customer js that's our route and essentially we're creating a route here the first piece is a create operation that's handled via the post verb and it's calling into customer we're expecting a body to be passed in we added the reference to a body parser middleware for express which actually gives us that data that's passed in the body attribute this was just an example here that we could check for an email to exist on that body as well there's obviously a lot of error handling that you can do to make this more robust and essentially the object coming in will look something like this that we're simply passing through to the customer model so we create a new instance of the customer model with that incoming json object and we call save on that model and then basically uh there are two uh methods here on the uh sorry uh this is using promises so promises have then and catch and so we're handling uh you know different error conditions and then what not here so this is pretty straightforward here i think the important piece is how to create that route and how to respond you want to make sure you're passing back the right error codes and things like that or status codes and things like that get request was very similar you know you change the verb here the method name the maps to get um similar things here just the method on your customer model changes so essentially that was like the the only big change between all the other methods on the route so you have get and on update you have find one update and for delete you have find one and remove so i think that that about wraps this up i think that there was a lot of content that we crammed into this hour and a half and sorry if someone says as a pure database person your brain hurts i apologize it's it's a lot of moving pieces here and if you don't get it it's okay don't feel bad it took me a long time to really understand this and master it these things take time just because of you know changing apis and and uh also the variety of functions that they expose so i want to do something real quick here before we end so i'm going to um clear my console here and now we have our application here we have a package.json that defines the project and and the scripts and things like that there is a service called now.sh that essentially allows you to make to deploy your node.js applications real quick and so i will let you explore this but what i'm going to do is simply deploy this to the cloud now and so what i need to do is go into my application folder and i type in now i have the now client installed via npm as a global and they have all the instructions here on on this site but i simply want to show you how easy it is for us to get this up and running in the cloud since i'm using the free version it's asking me a question stating that my application will be public and so essentially what it's doing is it's it's zipping up the application it's making sure that there's a package json that exists it will um upload that to the server side and then it's unzipping it and it is running the npm install command which ends up setting up all the dependencies that we require for the project and here you see it it's done it's giving you a status about what's going on so it um did a bunch of things here uh it's telling you which version of node it's using there is an actual endpoint that it created for us and it's copied into the clipboard it synced all the 10 files it's initializing its build process it ran npm install package.lock.json is something new with npm5 it allows you to replicate the exact versions of libraries that you used and then i guess it was waiting to so internally it's running the npm start command i think one of the things that i missed here in package.js and i want to quickly add is we want to set the the the process environment variable and essentially in index yes we were doing this here for port so we want to make sure we're setting port and it's as easy as going in here and setting port equal to whatever value that we would need but anyway i i think this should be deployed already i think it's copied but i'm going to make sure i copy it again and then we're going to go to the browser and let's put this in there let's see if that works there you go so we quickly got our application up and running in the cloud and since we were using mlab you know it's connected to the database we didn't have to worry about uploading the database or installing a database and things like that of course you would need to to uh have a config file that then looks at the type of environment you're running in development staging test production and then use the appropriate values from there to connect to the appropriate databases but here you go you can actually do this very quickly and play with it once you have your application up and running there's a question here that says do you usually need to use mongoose to access a mongodb and the answer is no you don't that the new mongodb driver is definitely a lot more powerful lately where it allows you to do validations as well you can define a lot of those things several people prefer that approach i personally have been using mongoose for a while so i stick with it because i'm familiar with the api and it provides us with a lot of rich methods to to handle these these uh interfaces into the database and i can also abstract my models out and add specific methods on it to do more complex operations and so it sort of provided a very good plug-in model for that and so yeah the answer is no you don't have to use mongoose but it just simplifies a lot of the process there i did write a couple of articles that might be useful one of them was introduction to mongoose i don't know if i can introduction to mongoose there this one specifically walks you through you know how to use mongoose for mongodb and and check it out see what do you think of it there's also another one i have called building your uh how to build your own react boilerplate this kind of introduces react into the mix but it also walks you through some of these basic building blocks for creating you know express servers and things like that the idea was that most people start out with using some existing boilerplate like create react app for instance but they don't understand the underlying building blocks and that was the idea here to break it down into individual pieces so you understand what's going on now this one of course uses uh webpack version three so i do plan on updating it with version four which is a lot easier uh in case you're you're planning on reading this anyway um i think that about wraps it up i apologize for going 10 minutes over here i think yeah that was it if you have any additional questions please feel free to reach out directly to me or on dev2 you can follow me on twitter at the outlander and i hope this was worth your time i hope you get to play with this further and and make sure you explore all the apis look up the documentation for express for mongoose check out now.sh which will allow you to deploy your application very quickly compared to you know aws and even heroku is pretty fast but now just takes it to a whole new level where all you type is now and it gives you this url with your application and you can map a domain name to it directly and scale very easily and and i have used a ton of cloud providers and and i absolutely love now and would highly recommend it alrighty thank you so much i'm going to pause this session here and hope to hear from you soon bye\n"