NodeJs: The Complete Practical Learning [2024] | Alex Bakker | Skillshare
Search

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

NodeJs: The Complete Practical Learning [2024]

teacher avatar Alex Bakker, Web, A.I. and Mobile Development

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      Intro

      2:16

    • 2.

      Overview to our RESTful API

      3:26

    • 3.

      Installing nodejs

      1:55

    • 4.

      Installing postman

      1:50

    • 5.

      Configure MongoDB Atlas

      1:57

    • 6.

      Preparing the API Server

      2:44

    • 7.

      Creating the Backend Server with Express

      6:38

    • 8.

      Reading Environment Variables

      4:59

    • 9.

      Create First API Call & Parsing Json Data

      6:47

    • 10.

      Logging API Requests

      2:38

    • 11.

      Installing Mongoose and Connect to MondoDB Database

      10:02

    • 12.

      Using MongoDB Atlas

      3:19

    • 13.

      Read Write Data to Database Using API

      14:31

    • 14.

      Analysing the E Shop Database

      5:40

    • 15.

      Create Backend API Routes & Schemas

      9:48

    • 16.

      Enabling CORS & Why Do We Need It

      3:15

    • 17.

      Products & Categoris

      2:44

    • 18.

      Products Model Schema

      6:12

    • 19.

      Categories Model & Scheme

      1:13

    • 20.

      Add and Delete Categories

      12:39

    • 21.

      Get Categories and Category Details

      2:48

    • 22.

      Update Category

      4:09

    • 23.

      Post a New Product REST API

      5:55

    • 24.

      Get a Product & List of Products REST API

      3:47

    • 25.

      Show Category details in the Product Populate

      3:01

    • 26.

      Update a Product REST API

      3:17

    • 27.

      Delete a Product REST API

      3:45

    • 28.

      Get Products Count for Statistics Purposes

      3:43

    • 29.

      Get Featured Products REST API

      5:18

    • 30.

      Filtering and Getting Products by Category

      6:54

    • 31.

      Changing "_id" key to "id" - more frontend friendly

      2:05

    • 32.

      Introduction

      2:22

    • 33.

      Users Model & Schema

      2:01

    • 34.

      Register a New User REST API

      5:18

    • 35.

      Hashing the User Password

      2:57

    • 36.

      Get User and List of Users Excluding Password

      2:56

    • 37.

      Login a User REST API & Creating a Token

      11:25

    • 38.

      Protecting the API and Authentication JWT Middleware

      6:07

    • 39.

      Authentication Error Handling

      5:07

    • 40.

      Excluding REST API Routes From Authentication

      6:48

    • 41.

      Add More Secret User Information to Token

      2:38

    • 42.

      Users & Admins

      6:46

    • 43.

      Get User Count REST API

      2:16

    • 44.

      Orders

      1:53

    • 45.

      Orders & Order Items Model & Scheme

      5:00

    • 46.

      Array of Refs Example of Link Order to Order Items to Products

      1:12

    • 47.

      New Order & Create Order Items on Posting New Order

      11:42

    • 48.

      Get Order Detail and Populate Products in Order Items and User Data

      8:10

    • 49.

      Update Order Status REST API

      4:29

    • 50.

      Calculating Total Price of one Order with Mongoose

      7:01

    • 51.

      Get Total E Shop Sales using $sum

      6:42

    • 52.

      Get User Orders

      3:25

    • 53.

      Product Image & Gallery Upload

      2:22

    • 54.

      Configure Server Side Upload

      11:24

    • 55.

      Testing Image Upload with Postman

      4:55

    • 56.

      Validating Uploaded File Types

      6:16

    • 57.

      Image Upload With Product Post Request

      1:10

    • 58.

      Image Upload With Product PUT Request

      3:19

    • 59.

      Product Gallery Multiple Images Upload

      7:17

    • 60.

      Excluding Uploads Folder From Authentication

      2:57

    • 61.

      Installing Heroku and Prepare Git

      8:24

    • 62.

      Optional Creating Production Database

      3:59

    • 63.

      Setting Development and Product Environment Variables

      6:17

    • 64.

      Deploy the App and Test It

      12:02

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

246

Students

--

Projects

About This Class

What is Node.js?

Node.js, or Node, is a runtime environment for executing JavaScript code outside of a browser. It is ideal for building highly-scalable, data-intensive backend services (APIs) that power your client’s apps (web or mobile apps).

Why Should learn Node?

Node is great for prototyping and agile development as well as building super fast and highly scalable apps; Companies like Uber and PayPal use Node in production to build applications because it requires fewer people and less code. Plus, Node has the largest ecosystem of open-source library, so you don’t have to build everything from scratch.

You learn in this course how to use mongoDb without any installing extra tools, MongoDB is now on cloud, so you will store your database in safe place!

This is not a reading documentation course. You have here a real-world project to learn from, and you will see the exact place of every feature of every technology used in this course.

What you’ll get when you sign up for this course:

  • 5 hours of HD videos, complete with exercises and solutions

  • A real-world project: you'll build the back-end for a E-Shop, not a dummy to-do app!

  • No more wasted time on lengthy courses or out-of-date tutorials

  • Up-to-date and practical information and solutions (no fluff!)

  • The opportunity to learn at your own pace - lifetime access - so take your time if you prefer

  • Expert tips to become a Node rockstar

  • The best practices and common pitfalls to avoid

  • Watch on any device

  • Certificate of completion to present to your employer

 

You’ll learn to:

  • Confidently build RESTful services (APIs) using Node.js, Express.js, and MongoDB Atlas

  • Employ the best practices for Node.js

  • Avoid common mistakes

 

What we’ll cover:

  • Node module system

  • Node Package Manager (NPM)

  • Asynchronous JavaScript

  • Useful ES6+ features

  • Implementing CRUD operations

  • Storing complex data in MongoDB

  • Data Validation

  • Authentication and authorization

  • User Roles

  • Handling and logging errors the right way

  • soon : Deployment

Note:

This course is including the building of the Backend API and all operations on the database, we are not doing frontend here

Checkout my other courses to connect this API's and build frontend of the E-Shop with frontend technologies

This course is for you if:

You’re a back-end developer and want to add new technology to your stack.

You’re a front-end developer and want to transition to full-stack development.

You’ve tried other Node.js tutorials and found them to be too slow, out-of-date, and boring!

Having Node.js on your resume helps you find more jobs and make more money.

And not only this, you will have optional tasks to do and we can review them for you! Just pick up one task from the board and create the pull request to get the review, to be like in a real world experience!

Meet Your Teacher

Teacher Profile Image

Alex Bakker

Web, A.I. and Mobile Development

Teacher
Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. Intro: Welcome to NodeJS web API course. In this course, you will learn by doing. We will put in front of you the most practical experience which you need to build web APIs. Because nowadays, if you want to gain an experience, you have to do it not only reading a documentation or following some theoretical course. That's why we build this course, which will be E-sharp Web API. We will cover all the information which is needed to create a webshop API. Api means application programming interface, or in other words, the interface which will bring for me that, uh, from the database to the user interface. And it will be located in a web server where our NodeJS application will be hosted. Every API is secure. So we will learn in this course how to authenticate to this APIs and secure them. We will create all the APIs which are needed for the e-shop, like the product and categories and users and users logins and authentication and user registration. And of course, the orders which the users will place, we will not forget also the file upload and the multiple file uploads. Because we will need that for our product images and product gallery, we will use the best tool for building our API. And as a back-end developer, you will see how to test your APIs because some tools can provide us full functionality without depending on the front end and waiting for it to be done. We will use also the right editors and the best extensions to speed up our productivity. And not only that, you will see also how this course is interactive. So we will ask you to solve a task and we will review them for you. I hope you will enjoy this course and I am looking forward to work all of us together to build the best API for an e-shop. 2. Overview to our RESTful API: Let's take a look to our RESTful API to see how to exchange data between the client and the server. What is the architecture of RESTful API? We have the client and we have a server, and they are exchanging data through HTTP protocol. This is the basic concept of RESTful API. There are also include operations to create data, read data, update data, and delete them. Its operations can be done through HTTP protocol. There are specific methods of HTTP protocol which doing these operations, which we are calling operations at first, what is the difference between RESTful API and the front end route? The RESTful API is bringing data. The front end drought is showing the data or rendering a specific page. When you open your browser and put RESTful API link, if you have access to get these data, then you will get a string which consists of JSON or XML file. Http protocol is able to render a page with HTML CSS and bring your data. So HTTP methods in general, they are GET, post, PUT, and delete, which are the crude operations. But in HTTP methods, they are called like this. So I am sending a request to the database or to the back-end in general to get through rest API some data. For example, getting a product list through the API, it will give me array of list of products. Getting a single product, bypassing the ID of this product, it will give me JSON file with all detail of the product. When I want to update a product, I send a PUT request with the idea for the product and also attaching the new data. And the response will be the same product, but with a different data. And deleting a product is just passing the ID of the product with delete request. Creating a product, need to post a new product. So I am using the main route of the API of the products and then I am passing any new data, the data which for example, name of your product and the image, and that is ponds, will be a new ID with the new name of the product and of course, the image. Those are our API requests to get the data or post or delete or update data in the server. And I am using api slash v1, which is meaning the version one. So when you want to update your API in the future, you add a new version. So they users are still able to use the older versions of your API. The same thing for orders and the users. So in this case, you have all the same sequence, but you just need to plan your data, right? Creating a web server with NodeJS is very simple. Let's see that in the next lecture. 3. Installing nodejs: To start development, always we need the package management. The package management comes with NodeJS application. So to install it just plays in Google NodeJS and go to Download. And you will see the download for all operating systems. For example, I have here for Windows and also I have for Mac OS. There are two types like LTS, which is recommended for most users, and the current, which is the latest features. Better to get always a stable version, which is recommended for most users. Here, you can choose your installation based on your operating system. And it will be simply an application, like as any application you can install. So after that, you can download this application and run it. And it will be like any normal application installation. So to be sure, after that you finish all of these steps. You need to run some MPM comments. So to run mpm commands, we can use Visual Studio Code. After opening the Visual Studio code, you will see here the latest projects you have. But for example, we need to open the terminal of Visual Studio code. So I will go here and say Control and J. And then I will have the terminal opened. And in terminal, we can, for example, place a comment NodeJS. So we can say, for example, NPM version. And we would get the full detail virgin about the installed Node.js. After that, we will be able to use NodeJS package management, where there are many libraries we can use in our application and developments. 4. Installing postman: When we are creating APIs, we need to test them. You can test your APIs with a front end application like React or Angular or Vue js. But we are going in this course to start with the backend first. So the best way to do that and test the APIs is installing a tool called Postman. Let's go to Google. You go to the download Postman. And here you will find based on your operating system. So here you will choose download the application. And after it gets downloaded, it will be a normal setup like any application. After opening the downloaded file, you will get notification if you are using Mac OS. And it will ask you to move this application to application folder. And after that, you will see this application is located in your application folder. The same thing for Windows. It's normal installing like any small application. After opening the application, you will be able to test APIs. Let's test one. When you go to Google and type JSON placeholder, you will see the first link is some fake APIs. So you can test a GET requests or post requests. So let's try this one. It says here. As a GET request, I go to the Postman and then I open a new tab with the GET request and place the link which I copied from JSON placeholder and press Send, I will get a response. This response comes as a JSON. And in the same way, we are going to build our APIs. 5. Configure MongoDB Atlas: For our e-shop, we need to have a database. And the database, we don't need to install any software. We will use MongoDB, Atlas. Mongodb offering now an online database storage, which means that the database is already in the Cloud. What we need to do just to go to the URL which I attached with this lecture and create an account here and sign up and then look into your account. After logging, you will see this screen that you need to create a project. So first of all, you need to create a project for our e-shop. So you go here and say, I want a project which is, for example, each hub. And I click Next. And then creating the project. After that, the project requires a cluster. So we need to build a cluster where we offer our database. So here, there are shared clusters, which is for free. You can use it and choose the closest server to your country. For example, I will use this one, the default one. And then after creating the cluster, we are ready to create our database. The database in MongoDB called collection. So you need to go to the collections and create a new one based on your need. We have already one which we created for the course in the project 0. Here there are collections at I created multiple databases. So your part is just to create an account and create cluster and create your own collection, which we will use in the course. We will see later how to make the connection between our back-end code and the MongoDB in the Cloud. 6. Preparing the API Server: Now the things start to be hard. No, no am just giving. In this module, we will see how to work with the product itself and its categories, of course, in the back-end part. So the main steps for creating our product now, to import all the data of the product to the front end. What it means that we want to create an API to retrieve all the product data to our front end. So we needed somehow as a JSON, this also including creating the product and updating it and deleting it. So we are going first to create the product and categories schemas in the database in the application level. Also, we will start as simple as possible. So categories is the easiest thing we can do now. So we will do the rest API for categories. And we will continue to post a new product to the database through the rest API. And then we will get list of the products. And after that we will get a product detail by ID. And then we will see how to connect the products with category. For example, when I am getting a product, I will see how to get the category details inside the product. After that, we need to update our product. So sometimes we need to update the price, or we want to update their image, or we want to update the name of the product. Deleting a product. Sometimes when I don't have the product, I deleted it from my store. And then we want to do some statistics like getting products counts, how much products I have in my store. For example, I want to see only the featured products. Because if you remember, we have is featured flag. We you know, what products are featured so we can take them and display them in the homepage only. And then it's very important that we have a filtering. So we need to filter their products based on categories. So I won't only for example, something for health. So I get the products which are there categories is health. That's it for now. I hope you will enjoy this module. It will be a little bit detailed, but after that, you will be able to create the orders and the users, as we see in the next modules. 7. Creating the Backend Server with Express: Let's start to create our back-end server, or let's say our web server, where we will call our APIs to the client. After we have opened our Visual Studio Code to the folder back end folder, as we structured it before, we run a command npm init in MPM in it, it will ask us for a package name. I put e-shop, a virgin. I press Enter description, let's say some back end for the e-shop for example. And then the entry point like where the application will start, I put app.js and then some, another comment. We keep pressing Enter and then it will ask us everything is okay. We press Enter. Then we will see a package Jason is created. So let's create now our file up js, where we will start our entry point of our application. So I will put here, for example, console.log, Hello World. And then it will print Hello World when I am running this application. But how we will run this application, I advise to use a library called NADH Monde, which is a utility that will monitor for any changes of our source code when we press Control S or save this application JS, it will restart the application again automatically. So after we install this library, we see it is in independency in a package JSON as a custom script, we can add it here, like it's a comment to start the application using Node monitor. So I can say start node monitor or node moan. App dot JS. In this case, I will have the application started with the entry point file app.js. Let's try it now. Let's save ab.js and then write npm start. And after I started the application, I will see Hello World. And the application is still running. So it's detecting any change I do in the application. So I say helloworld with the change was exclamation mark, and I see it's changed. Let's change the world E-sharp. We will see hello e-shop. That's great. So till now we have only a running application, but we don't have any server yet. So to create a web server, let's install Express, which is a famous library from Node.JS to host a server. So after doing this installation, I will see it also in dependencies. But let's remove this console log and it create a constant, call it express and call the library express using the keyword require express. It will call it automatically from node modules. And let's create a constant which is called app. And this app with call a function called Express, which we mentioned or defined before. This web server requires listening to a specific port. So I say up that listen. And I specify, for example, 3 thousand as a port. And there is a callback. Callback will give us, we all will be executed when there is successful creation of the server. So in the callback, I can print any message in the console. For example, I will say the server is started now or the server is running now on the link local host with 3000 port. So now let's run the application again. I will say npm start. And we will get some error because I am running the server already. So let's start it off and I run it again. I will see local host or the server is running on localhost 3000. When I open the browser and visit this URL, localhost 3000, let's see what we will have. I put it here and I see that come up, get, cannot get because I didn't specify any initial route for the application. We create. Now the initial route or the root, we can say app dot get. We will see Express is providing us with all HTTP requests. For example, PUT, delete, and also post. So forget. It will accept two parameters. The first one is the route itself. For example, I will say the initial route or the root. So in this case, I will ask for a callback. The callback will have the response which I will send to the client when he will call this route. So I say in the callback response, dot sand, for example, let's say a message, we can call it hello or API, not Hello World. So now we have this API. Let's save, and now we can run the application again on the browser. The application will call a getMethod and we will get as a response, this hello API. So as a recap, we saw how we created our own server or web server with express. And we were watching our changes with node Monitor and how we call this application get to initialize a route. And we run the server under a specific port we saw before. We need to have an API and a version in the URL of that out. So let's see how we can create that with environment variables in the next lecture. 8. Reading Environment Variables: Okay, so let's start with environment variables. Environment variables normally are used as a public variable, which are used among the application. So for example, I want a public variable for API URL. So this API URL, which will be prefixed for every route which I use for my application or for my API. So as we saw before that every API we had, it's prefixed with something like slash, api slash version one. And this mean that every API in my application will have this URL. And then API version one. And then I say, for example, products. And then I can post, delete or create some data to this API. So now let's see how we can read this prefix. So I don't want to repeat in my API is always the string. So I can fix it in some constant which is readable from everywhere. And then I can pass it to the mike, to my strings routes, and then it would be readable in that route. So to do that, first, normally, in not the Node.JS, normally we have an environment variable called dot n or environment file. And what example I pass a variable name which I want it, any name you can, for example, API URL. And then I can say the string which I want to pass, which is api slash v1. And in this case, I will have this API URL is defined everywhere in the application. But first, how we can read this variable from this file in our application, there is a library, we can install it from MPM packages. And it's called dot-dot EMF. So we can't say npm install dot EMF. And this library normally is available always. And we can use it in the application JS in the route in the root, No problem. So we can say define or we can say require this library. So does't EMF slash conflict. And normally this should be in a string. So when I say require this library, then I will be able to use some specific constant to get these values from the M file. So I will go here and define a constant. Let's call it for example, API. And then we can say process dot, dot, then the name of the variable which I created here. So I can say API on the score URL. So let's save everything. And now let's try to print this variable to see if it's really reading from this file or not. So let's do it on start when we started the server. So I will say console.log, the API for constant. So then I will start my server, mpm start. And here it is, we have now defined already. So in every route I have, I can define or pass this API variable plus the route which I want, for example, products. So in this case, I will have the prefixed API version one plus products. We will see that more in detail in the next lectures to see how to create the route and how to build it and how to call it. The most important thing you need to know now that we can create the public variables in this file and read them anywhere in the application. So in this case, I want to store, for example, the database string or connection string. I can store it here in this file and also, for example, some secret for authentication, I can also store it here. And when I want to deploy the application to the production server, I'm going to change these variables. So we will have also another file, for example dot EMF, but for production server, we will see that of course in the lecture where we will deploy the Node.JS application. So now let's move to the next lecture where we will create the real API and how we will send JSON data through it because we need JSON data for our e-shop to exchange with the front end the information about the products and the order and et cetera. 9. Create First API Call & Parsing Json Data: Now we are going to see how to exchange data between front-end and the back-end. We saw previously how to exchange data with the front end with the GET request. So we send Hello API. But what we did is only exchanging a string, which is hello API. So we need to exchange JSON data. For example, the product is an object, consists of ID, name, image, and the price. So now let's simulate the products API. So at first, Let's have the nice prefix as before. So I am going to use the back ticks, which are very helpful to combine between constants and strings without using this plus. So now, let's remove this part and create a backticks. And with a sign dollar and curved brackets. I will make API. And then let's say products. Let's remove this part from here. And also this one. And I'm going to create a constant. Let's say product. And this product is object, contains ID, let's say one, and name, let's say hair, dresser. And image with, for example, some URL. So you have option here to select double quotations or single quotation. But with JavaScript, It's better to use always single quotations in that response. Let's send this product to the front end. And we will run the application. Now we have the application running. Let's go to Postman. Postman is application as we talked before and we saw how to install it. So I can't call APIs like with GET methods, post, PUT, etc. So let's have here our API 3000 and then api slash version one slash products. And I click Send. Then that is pons is the object which I created already. So we assume that we are building this object by getting the data of the product in the database or from the database, and then send them to the front end with a getMethod. So what if the user or the admin of the application of the issue up, we'll send, or, for example, create a new product. So the new product need a data which will be sent from the front end. So now let's change this muscle method from get to post. What example I will copy it and say post. The post requests need also data. This data will come from the front end. So how I get this data from the front end, it's very simple by using request dot body. So after posting the data of the body, I am going to send them back to the front end. So let's create a constant, let's say new product. And this new product will be request dot body. So let's make it like this. Console. Log the new product. So we go to Postman. Postman we change this method from get to post. And the body of the request will be, for example, at JSON row, which is JSON. And then I can pass, for example, this object. And when I click Send, we see that we return one. And in the console log I got undefined. So the problem is that the body is not parsed well. So we need something called a middleware. The middleware is a function that has control of request and the response of any API. So when the front ends and JSON object, we need the back-end to understand that this is adjacent. So please analyze it and use it in the back-end. So to do that, we need just to use one thing from express JS. So we need to use that JSON. So the Express will accept JSON data. And the thing is very simple. As I told you previously, we need to have a middleware. And this middleware can be done by using app use. And then we say Express dot JSON. And this method, we'll make our data be understandable by Express, which are sent from the front end. And we can type here like middleware. And in the future, we will see that we will put all middleware. In this section. Previously, there was used something called bodyParser, and this body-parser got duplicated. So now on we are using Express JSON. So if you see in the next lectures that we are using bodyParser, just replace it with expressed or JSON. So in this way, you guarantee that your application will run in the right way. So now we are able to make a get and also post of the data. I will, for example, change here hairdresser to and send it. And I will get back the hairdresser two. So now our API is ready. We are now starting to build this API structure for orders for products and 40 users, as we talked before in the previous section. In the next lecture, we will see how to log these APIs events. For example, when someone post data or good data, we will lock them in the console of our application. 10. Logging API Requests: It's very helpful fault that the developer to know what is going on on his server. So we can know and log the HTTP requests which are coming from the front end, like posts, get or put or delete. To do that, there is very good library called Morgan, so we can use it to log our HTTP requests which are coming from the front end. So let's install this library. I stop the server, say m, Pm install Morgan. And after installing this library, we can call it also with require. So cost Morgan. Require. Morgan. We said that this library is a middleware library, so we have to put it in app dot use Morgan. And there is some default options, which is called Tiny. This is good in case to display the log requests in a specific format. For example, let's run the server again. Mpm start. So we have here that a server is running with Postman. Let's do some requests. For example, I am going to send the post again. Okay, back to the application or to the code. We will see that we got a post request on the API and with their specific status number. Let's make a GET. Also. Here is a get, Send and back to the application. And I see that I logged also, they GET requests. There are many options for this library, so you can format your logs as you want. But we are not going to do that. We are going to use only tiny. And of course you can say with this logs on some files, all of this is, is displayed here in the documentation of this library. Now we were using only a fake data of the product. Let's start to bind this data to the database. So let's in the next lecture to do the connection to the MongoDB using Atlas. 11. Installing Mongoose and Connect to MondoDB Database: Previously we saw how to fake a data of the product to store them and display them in our application. Now what we need is to store the data in the database. And in this course we are using MongoDB. And as we saw before, we don't need to install any special software for MongoDB. We just need to log into the cloud of MongoDB. And then we create our database and connect our application to that database in the Cloud. So first of all, how we can connect our application to the database on the cloud. So first we need to install a library called Mongoose. Mongoose is responsible for all operation of MongoDB database in the application or a Node.js application. So let's install this library which is called Mongoose. I will type here npm install mongoose. And as every library we need to create a constant. Let's call it mongoose. And this Mongo's, we can say it's require Mongols. We can assume that this thing here is like import. So we are importing every library and store it in a constant. Normally, we add the connection to the database before starting the server. So here I will say Mongoose, dot connect and disconnect. It's asking for URIs. Uris or connection string. I can get it from MongoDB Cloud. We saw previously how to connect to cloud of MongoDB and create our application and clusters and our project. And we saw that we have multiple collections, or we can say databases. And those databases, we will have access to them through our application. So let's see how we can connect to those databases in clusters. If I go back to clusters, I see here a button that says Connect. When I say connect, I can use multiple options from MongoDB. For example, what we need is connect your application. So we need to use a connection string to get it from here and paste it in our connection method with from Mongoose. So by clicking on this option, we will get a connection string. Let's copy it and have it in our application. So I bring quotations here and copy this connection string. But we can't see it says this connection strings should contain a username and password and database name. But from where I can't get this information's simply in MongoDB Cloud. We can use a specific users to connect to these databases. We just need to go to database access and create a new user. And this user we can connect To database in the Cloud. So let's click here, add a new database user. And let's give it a username, E sharp user and the password, you have freedom to select any password. For example, I put from one to seven. He said that password is provided is very weak. So let's add some letters to it. And then it successfully added the user. Going back to our connection string, we need to replace this data here. So first, I will put here the username, E-sharp user, and the password which I had before, and the database name. Okay, we don't have that the base yet. So let's add one. We go back to the clusters. And then we can see here our collections. And in this list of collections I have previously, I can create a new database. So I am going to give it a name E-sharp, that the base and the same name for the collection. Back took that connection string. We can add now a database name. So now we have the full connection string. We talked before about environment variables. So let's store this string in the environment variables, so I copy it. And then I create, for example, a variable, call it connection string. And then I give it this value, which is the string which I got from the database cloud. And here I just say process dot environment variable, dot, connection, string. So now how we can check that we are connected to the database or not. If we check this method Connect, we will notice that it's returning a promise. The promise normally is getting executed and it's returning two methods. One is then when its successes and one with the error when it's fail. So here I will put then. And then if I arrow function and I console log some message, that database connection is ready. And when it fail on catch. And it's also arrow method. We can say console log the error. Let's try to start our server. So now npm start. And we see that there are some notifications saying that deprecation warning. It's saying that current URL string parser is deprecated. So we need to use some specific variable. So we need to use a specific option as a true to make this deprecation disappear. But how we can use it, we see this connect method has another parameter called options. So with this options is an object where I can pass the options which I want. So let's copy this one. Added as option. We got also another deprecation warning which is use unified topology. This is used also for searching for the servers. So let's add it here. And let's save. We are still getting error. Actually the error we need to pass also the database name in the options. So I can say that it's some reserved word, it's called DB name. And with this TB name, I can pass the database name. We named our database in the Cloud as e-shop that the base. And after saving and trying to reconnect, we see again that the authentication is failed. In MongoDB Atlas, you need to give a network axis. So this network access, you need to have a whitelist of IPs which can access your database. So I have two IPs already. I can add another IP by going, for example, to Google and just type what is my IP. And in the first search result, I will get my IP directly. So I go here, copy this IP, and then I say add the new IP. So this IP is added, I can say my home office. And then I click Confirm. So back to the application. We can see if we are able to connect or not. So just we can press Save again. And we see here the server is running, but we didn't get any response yet from the database server. And we see that the database connection is ready. So in this way, we connect the issue of back end application to the database in the Cloud. The next part, we will see how to write data to this database using our APIs which we created before. 12. Using MongoDB Atlas: Of course, there is also an local tools for browsing the database of MongoDB. You don't have to use our class online. You can also download some tool which has more, more functionality as we will see later, like export and import data. Because I want to give you the files and the data and the database which I have created to not be bothered to fill your data or database by your own. You will have the files ready. So you can use this tool to import like the databases and the tables and the documents to your database as well. With this lecture, there is a link attached for and something called MongoDB Compass. And this is a very great tool for browsing MongoDB database. And it's available for all versions of operating systems. Also, like for Windows, for a Ponto, and also for Mac OS. So after you download this link, it will give you an application you can use. And this application you can install it to your applications and then you can open it. Okay, let's open the installed application. As I show here, I have it here in my application list, in my Mac system. And it will going to append for me the MongoDB Compass. As you see here, we are initializing it. So it's initializing. And let me zoom in a little bit like Give it to be more bigger size. So now it's asking me to add a connection string, which we have created in the previous lecture so I can go and copy my connection string and then pasted here and then click Connect. I explained already how to get the username, password, and also the database name. So I have done that already. So it's in recent. I have here the e-shop user and also MongoDB and all of this information between it. So now we need to click on Connect. And then it's going to connect to my database. As you see, I have listed all my cluster, which are which I have in the atlas. So we have all the databases which I created previously. And as well the database which we are going to work with. So you have two options. Maybe you can use MongoDB Atlas or MongoDB Compass, MongoDB compounds. You didn't need to look into the browser and look into the website of MongoDB Atlas. But you can hear use locally. Just open an application, add your connection string, and it will be saved here always. In this course I am going to use MongoDB Atlas. And when we are going for deployment, I'm going to use MongoDB Compass because we need to import and export data. And as well. In the next lecture later, I will show you how to import and seed your database. You don't have to fill all of this information manually, like the database. So you will have already database you can import to your collection and then you can use it. Like to follow up with their course. 13. Read Write Data to Database Using API: Perfect, So I'm so glad now that we have a successful connection to the database, let's now try to post some data to the database so we can see them in the MongoDB Cloud. In the relational database. Previously, we saw that the relation between the tables, but here in MongoDB it's acquire different. We can consider the naming table is a collection. So as we see here, we have already a database. At inside this database, there is a collections. So we can say the collection is a table in relational database. I deleted the database which we created before. I'm going to create a new one with the table, let's call it a products. So for example, we said that our database name is e-shop. Database. Products is the collection name. So I have the database. Each database and inside that there is a table or a collection. We can call it a products. Okay, great. So now we have, let's say this collection, let's post data to this collection. So in Postman, as we saw before, we have here to this object, let's push it to this database. But first, what we need to do in the Node.JS application, we need to create a model with Mongoose. Model is the same thing as a collection. So we can say in MongoDB, it's called collection and in Node.JS, it's called model. So we need to create a model of product. This model will contain the columns which we needed for the product. For example, the name or the image, or for example, the quantity of the product in the storage in Mongoose. This is called schema. And if we go there to the documentation, we see that Mongoose has a lot of flexibility here. So we can create schemas. For example, block schema as we see here. And we can put the field's title, author, body, and there is type of it, and every field has some options. So you can specify, for example, date dot. Now, for example, we're in this record or this document is created, then we will see that it takes automatically the date of time of current time. So let's start simple. So let's first create the product model. I go to the application and after, let's say use and before the APIs. I create, for example, at constant, call it product schema. And this product schema will use Mongoose library and schema. And the schema accepting an object and this object will take the fields as we saw here in the documentation. So we have a new schema and here we can list our fields. So let's add our fields which we had before. So I say I need the name. We type is string. And for example, I need also image. Which type also string. It would contain the URL of the image. And let's add also something like count in stock. Count in stock. And this count in stock will be a number. There are a lot of types. You can check the documentation of mongoose and we will see in the course the different types which we will use for our webshop application. After having this schema, we need to create the model. So I say constant product. Normally the models start with capital letter. So we can say product, which is mongoose dot model. And the model called, or the collection is called product. And using the product schema which we had before here. So I say product schema, and I press Save. Now we have the product schema and the product model already defined. So now we need to, for example, with posting requests, we need to receive this post data from the front end, which is we can say postman or any other application like Angular or React. And then we need to receive these data by the back-end, analyze it, and push it to the database. To do so, we need first, we need to create a new product, for example, of that model. So let's do that. We can say const product. And this product is new product which we had before. But what are the fields of this product? So the product is this model which we had before. And we are going to add the fields of that product, like the name. And the image and the count in stock. So I will go here and I will receive that request, which I got. With this request, I get the body. And with the body within the body, I am sending here id, name, image, and I can send also count in stock. It will be exactly the same naming here, which comes from the front end. So the front end and the back end must agree on the same naming for the fields and the object which are sent to the backend. So here I say the name is request dot body, dot name. Image is request dot body, dot image. Count in stock is also from the request dot body dot count in stock. Now we have the model ready, so we just need to save it in the database. So to do that, we can say product dot. And it has a method called Save. Save. It means that save it to the database. If we check this save method, it's returning a promise, promise with the document. So we can say, then it's returning a promise. So we can say created product. So this is the product after it got created in the database. So it's our own method. So we can say here, response dot status, that it's successful connection or successful creation of the database of the document. So I can say here dot JSON. So I want to return back the created product to see it in the front end. And in case of error or anything can happen, we can say catch the error. And this error, we can say response dot status. For example, 500. It's the response code for errors in the http dot JSON. I create, for example, my own object. I say error is the error which I got. And for example, I say if its success or no, maybe I can use this variable in the front end. For example, to end some loading or go back to homepage. If there is some failure. We already send that product. So let's delete this part here and start our backend MPM, start. We have it now ready and the connection is ready. Let's post some data here. Nice. It's boasted, we got ID, name, image. So if we go to the our collection in MongoDB, Let's press Refresh here. We got the same data here. Let's try again by adding count in stock. Say for example, 500 pieces in my stock. I send it. I created a new product with the same name, and it's returning the ID of created product. Going back to MongoDB, refresh again. Nice. I have also two products already posted through my API in the back-end. And we notice here that it's locked and successful. Let's make an error. For example, to make an error, let's make this field as required. So database will recognize that this count in Stoke is required field. So it will response with error that you didn't send, for example, the count in stock. To do that, we go back to the schema and we change this to an object. The type of this object is number and required is true. So let's save it and run our, again our API but without count in stock. And if we validate the JSON and send again, we will see that we received an error, error and successful, false or failed. So in this case, I would say the error is validate or error path count in stock is required. So the database replied to me that this field is required. When I do it again, its success. So now we have posted a data to the back-end. Let's create a get request. So I want to get this data, display their product information in the front end, for example. So to do that, we need to create a get request. So creating a GET request just simply we change this to get. And we need to specify the products list. So let's, for example, get the old product list. And if I send the request, I'm getting the old API which we had before. So let's change it to have it from the database. To do that, we go to the get request and then we replace this constant and call it, for example, that list. And I call just the model itself which we created before and find. That's it. So I say const product list and the response will get our, send me the product list. Let's try that. We do ascend. We notice that we got an error here. The error is because that find method is returning a promise. And here, when I am sending the response, maybe this product list is not ready yet and I didn't get it yet. So I need to wait until this product list is ready and then I can send it with the response. There is another way than doing, for example, dot then and not catch. That is something we can do with await keyword. And in the await keyword it requires always async method. So I put this method here and it's async, and I have a weight here. So in this case, when I call the product list, then it will wait, it will be filled, and then I send the response to the front end. So let's do it again. Now. I am saving and then sending that request, we see that we got the data here. We didn't get the error anymore. So this is because of that we return a promise. We should wait for the database to send us their response, and then we shall wait in the front end. So maybe you will ask me how I can detect the problem or issues. It's very simple. I can say if a product list or no product list, if there is no product list, then I can say response dot status 500. And for example, with JSON, I can say error or success false. So if there is any mistake happened, for example, connection or anything, I can simply return error with a success if this list is empty. So we have two different way to express and catch errors from the database. So I can say here, find, I can put a weight and async, or I can do it with normal promises. Like for example, I say Save, dot then and catch. Of course this is more code saving. We did this only in two lines, and that's very good. So from now on, we will use always async and await. That's all for now is mongoose. Let's do some refactoring. It's very nice to have the routes in some files and the models in another file. So we can have more organization of our code, of the backend. 14. Analysing the E Shop Database: Welcome back. I changed my mind here, so we will not do refactoring. Let's analyze first the database of e-shop. So in this way we can know what routes and what schemas we can build and creating the files in the back-end. So here we have least of the tables or documents or collections which we need in our database. Every shop has products, orders, categories, users, and order items. This is the simplest e-shop. So when you want to grow up more, you need to have more tables like a reviews or for example, some new categories are bigger categories. So we start simple and we will build our e-shop to be bigger slowly. First of all, the products, for example, it has ID, which is the ID for the product. And this ID is generated when we post any ID to the database automatically by MongoDB. The name of the product, and also description. And the description reaches scription is used for, for example, I want to store some HTML code. Sometimes people are using as a description of the products with images and titles and some complicated reach texts. So we will see how we will have editor in the front end. For HTML. We need also the main image of the product. And it's a string, string, which will store the URL to that image. Also, we need a gallery of, a gallery will have some images and array of strings, of URLs where we have a gallery of the product, more detail about the product. And then we will have a brand and also price, price of the product category. It will be the type category. In MongoDB. Here we will have something called references. It's not like relational databases, but here we can define the type of the table directly. So as we will see in the future, we will see that this category is a type of category or has a reference to the category table. And count in stock how much items of this product are in the storage. Also rating based on reviews and if this product is featured or not. So to see it in the homepage immediately as a featured product. And then we will see that what they, this product is created four categories. We just need a name, maybe some additional data. For example, what I need in the front end, sometimes color, so I can color every category based on some specific color and also icon or image. For orders, we need order items, which is array of order item. And order item is a table where it's contain the product and the quantity. So every order will have a product and the quantity. So maybe I will have 10 products. I ordered them in one order. And then every product will have some quantity. The shipping address one and address two. And city, zip code, country, phone number of the user status to see if this birth order is, for example, bending, shipped or delivered. And also the total price. We will see how to calculate the total price based on the order items and the user who ordered this order. Because we will have lookin for every user who want to order something. And then the date of the order. For the users. We need an ID name, e-mail, where the user will log in with his e-mail and the password hash. The password should be stored hashed in the database. I cannot store it as plain text. Street, Apartment, city and zip code. And also country with a phone number. And also to know if this user is admin. So he can log in to the, for example, admin panel or not. Maybe someone will ask why I separated here the address from the user. Like for example, I can have extra table like address here. Then I can put this field in that table. And I can relate user and orders to that address table. Actually, most Aesop's has a problem that sometimes user, after he ordered something, he changed his address. But the order is already shipped. So we need to store the order as a plane with a shipping address, how the user placed it, not related to the user address. We will use this address just to auto-fill the order address when the user is ordering something after he locking. In this way, we took an overview about our database in MongoDB. Now we will go to the backend and create the files and refactor our code a little bit to be based on this database structure. 15. Create Backend API Routes & Schemas: Welcome back. I'm imagining now that what if we place all the schemas here in this file App.js, it would be very big. And I think we will have thousands of lines here. So normally in Node.JS, the people or the coders in general, they are putting these routes, for example, the API routes, and also the schemas in separated files. To, let's do that now and we will see how to organize the project more better way. So forth schemas. Let's create a folder here. We call it models. And inside modal, we will create a file for every model we have, for example, products or product dot js. In products AS I will place this schema. So let's copy this part and place it here. Mongoose is not defined in this file, so we need also to copy this part where const mongoose require mongoose because this file cannot see the imported Mongoose in the app.js. So we have here const Mongoose and mongoose schema. And by the way, let's get also the mogul. Though we cut it and we place it here. Now, how ArcJS will use this model in Node.JS. If we want to export a constant or for example, a class or object, we just say that we need to do it in this way. Exports dot product and then the model. So here, in this case, product will be seen in any other file. And I can import it with require method. So going to ab.js file and I say const product, which is coming from by requiring it from this file where we have the model, for example, models slash product. In this case, we got the product and we can use it as a model for our API. Let's do more refactoring. We see that we have all the APIs, get post, GET post. So if we do that for all the schemas, it would be very big file. There is a way in Node.JS that you can also store the routes or the APIs in separated file. I will show you how to do it. So first let's create a Word folder, drought routers. And inside the router, I create also products, the js. So for every model, maybe there are routers. In Express. There is something called router, and this router is only responsible for creating APIs, stalling the APIs and importing and exporting them between the files. So how to do that? First, we need to import the Express. Require Express. And the router will be part of Express. So we can say Express dot router. So this router, when I import it in ArcJS, I can use it here. And this router, it can be used as a middleware, so I can use it with app use. So first, let's move, see how to move these routers. So first, let's copy all the APIs we had and place them here. Instead of app. I just say router. That's very simple. And also I delete them from here. And as we said up the 2s is, it can use also that outer. So we can take the main API route of the products and place here, for example, product router. But from where these products router will come, it will come from here. So I can't say I want to export also the router. So I can go here and say module dot exports is router. So we have here different way for exporting. Here we are exporting the product itself, and here we are exporting a module. So in this way, I can say products router is a constant. So we can say here, constant. Products router coming from, require, from routers. And then products. So we will see here that this application is using this routes from routes which are coming from products router. So here we need to do something. We cannot use the API like this, because otherwise it will be, we can consider this as the children. So for example, here, I need to place only the stash so I can consider it when I say localhost 3000 slash products, then I can reach this one, get. And the same thing for the post. If I want something in the future like count, I put it like this, then the API will be http 3000 slash products slash count. So this is the best way how we can handle that outs in separated file. But first we have here the model product. So we need also to import this model. So I say const, product is required from models the product. Now we have the routes completed. So we have everything get post and we will see how to add the delete and update. Let's save this file and also save it here. Make some more organizing of the code here so we don't need it anymore. So we can hear, say routers. And here, the product router, we can have it here imported. Let's see now if everything works fine, we can say MPM, start. Everything is connected and everything is working as smoke. The same thing will go also for the other database collections. For example, I will have here orders GS and also user and also the category. Also the same thing for that authors. I will have the same files. So I'm sure you are not interested to see all the process because it's exactly the same. I'm going to add them. And then we will see after that how they look like at the end, our application look like that. In app.js. We have the middlewares, routes, and also the database connection and the seller. In the routes. I created routes for every type or, or for every collection we had in our application. So I go here and I created that out exactly like the products. We have, the users orders, categories. And the same thing for schemas. Every schema has its own now. So in this case, we have now everything ready to create our APIs. Currently, I use only get in every type. I just want to mention one thing. When we export the model from exports dot-product in this way, not in this way. When we import it, we need to import it as an object. So here, when I go to the products, I import it like this. In ES6, we have this object destruction. So this model is returning an object. So I need to create a new object and assign all fields of that object to this one. So in this case, I can use it everywhere for sure there is no any problem if you use this way. The way of exporting the module directly. Let's try our API. Now. I go here and I say get, I got list of products. That's it for now. For next lectures, we will see how to fill these schemas and how to connect it to the structures of our database. And we will see how to continue to build our e-shop in a better way. 16. Enabling CORS & Why Do We Need It: If you are doing a front end and the back-end development in their same time. I'm sure you saw this error. This error called Cross-Origin Resource Sharing, which means in a human language that Node.JS application cannot trust any other application. So when I am sending requests from my front end to the backend, then the back-end when Lot response to me the same that I want because it's forbidden. It's using different port, which is totally a different domain. So in my front end application, when I create a services to call the APIs, then I will get that error. And in Mozilla org, they are explaining all the data or all the details about this course. So somehow in NodeJS app, we need to enable those course. How we can allow any application to request API from my server. There is a library called course. We can use it to allow the course for any application. So I stop the server and I say npm install course. After installing it, we need to require and import it. So here we are importing everything in ArcJS. So I say const course, require course. And to enable the course, it's very simple before everything, before the application start, before using any service in the application, we need to do up, don't use cores. And app dot options. With star, like everything. Using the course. This app dot options. It means it's some type of HTTP requests, like GET and post and put and delete. But what is it? When we Google http options, we see that HTTP option is a method requests permitted communication options for a given URL to the server. So when I say, I want a star, so I am allowing everything with using this course. So in this case, I am allowing all other HTTP request to be passed from any other origin. So it's very important to use this course and enable them to avoid this error. Finally, after we finish this module or this section, I would say that this project is the startup for us for creating the issue of back-end. So I will put it as a zip file so you can download it and start from here. You can see this project in resources with this lecture. In the next modules, we will see how to build all the schemas and the APIs for every part of the application. 17. Products & Categoris: Now the things start to be hard. No, no am just giving. In this module, we will see how to work with the product itself and its categories, of course, in the back-end part. So the main steps for creating our product now, to import all the data of the product to the front end. What it means that we want to create an API to retrieve all the product data to our front end. So we needed somehow as a JSON, this also including creating the product and updating it and deleting it. So we are going first to create the product and categories schemas in the database in the application level. Also, we will start as simple as possible. So categories is the easiest thing we can do now. So we will do the rest API for categories. And we will continue to post a new product to the database through the rest API. And then we will get list of the products. And after that we will get a product detail by ID. And then we will see how to connect the products with category. For example, when I am getting a product, I will see how to get the category details inside the product. After that, we need to update our product. So sometimes we need to update the price, or we want to update their image, or we want to update the name of the product. Deleting a product. Sometimes when I don't have the product, I deleted it from my store. And then we want to do some statistics like getting products counts, how much products I have in my store. For example, I want to see only the featured products. Because if you remember, we have is featured flag. We you know, what products are featured so we can take them and display them in the homepage only. And then it's very important that we have a filtering. So we need to filter their products based on categories. So I won't only for example, something for health. So I get the products which are there categories is health. That's it for now. I hope you will enjoy this module. It will be a little bit detailed, but after that, you will be able to create the orders and the users, as we see in the next modules. 18. Products Model Schema: Welcome back. In this lecture, we will see how to build the product model or the product schema. Everything in Mongoose start with schema. Each schema maps to a MongoDB collection and defines the shape of the document within that collection. So based on the model which you see in the right of the screen, we are going to build the same schema as we build it before in that model. So the fields of the product can be like start here, I say the type of this field is a string. And there are schema options or Schema Type Options. This schema type options, you can see them on Mongoose documentation. So I go here to Mongoose documentation. I go to schema types. And in schema types, we can see that there are many types. For example, string, number, date, and there are something called options, as we see here in this example. So I go, for example, to Schema Type, and I see that there is path and options at Schema Type Options documentation, I can see all the options which I need to build my schema. What we need actually for our course, I think we need that required field and also something called href to reference to another table and default, which is a default value when the object is created of the product. So the product name is always required. I set it to true. The next field is description, which will be a short description of the product. And it will be also a string. Is it required? I would say the short description will be required in our case. And then let's go to the rich description. In the rich description is also has a type string. But I would say it's not required. And we can put a default value for it when it's created. For example, I say empty string. The same thing go for the image. So I put say here also, the image is a string and it has a default value like empty. Now we go to images. Images. They are always array of strings. So we can put it simply like this array. And the type of every item of this array is a string. We have also brand, which is will be the same thing. String and price. So the price will be in the way type is number. And the default value. We can say it's 0. The next step now we need to add the category. So it's simple. We say category is type of ID of category. So here in the product, when I want to add a product, I use the category ID, not the whole category. So I say that the link between the table and of the product and the table of category is the ID of the category. So the type of this field will be Mongoose dot schema, dot types, dot object ID. So in this case, I need to pass always the id. And how I would say that this ID is connected to categories table or category schema. I just do that. I say a reference is category schema. So in this case, this ID will be connected to category schema. So when I add product, it's search in categories and I pick up specific ID. And then I say this product has category, for example, beauty and health. Is that required? Yes, let's add it as required. The next field we do We have already is count in stock. Count in stock, It's normally a number and required. So you need to specify how much of this product you have in your storage. There is also another property we can put max and Min. For example, I say minimum has 0 and maximum. It has 255, for example. So I say here that when I post a product with minus number of count in stock, then I will get error because mongoose, when it turned to me and tell me that, no, this is wrong. You need to put number between 0 and 255. The same thing goes, for example, for rating and also a number of reviews. They are numbers. So I added them here. And the field is featured is type Boolean. So the default value of it is false. So this is to show the product in the homepage as a featured product. Also, I have the field date created. So data created is a type date and the default value of it is date dot now, so it's very simple. So when the product or this request comes, then it will take the current time. Now we have all the scheme are ready for their product and we will see later how to add product in the post requests and how to get it. 19. Categories Model & Scheme: Previously, we created the category schema. And as you see here in the model on the right of the screen, we need to create those fields. So let's start with the name. It's exactly the same thing as we did for the product. So I say type string required through. So to not take so much time in typing, I'm going to add the other fields because they are also having the string type. So here we have icon and color. The icon will be icon name for example, we are using some font icons or Google material icons. So I can say only the icon name. And also I say here the color, that color will be a hash, hash string, like something like I can say 000 000, which is black. So in this way, I can store the color of the category which I need to display in the front end. So let's start now with creating the API of the category. In the next lecture, we will see how to add category and deleted. 20. Add and Delete Categories: Great. So back to the real-world. Now we are going to have the category API. So in this lecture, we will know how to add a category and remove a category. I started simple here because the category API is the simplest we will see in the future. How to create more complicated APIs, like the products and the orders. So as you remember before we created the routes and routes, we are adding our APIs. We have here a GET, we will edit it to make better way or we can keep it to get list of products. Now, let's add a category. So by creating router dot post. So I am going to add a category, so by slash and then async, request and response. Then I will do here the adding to the database using Mongoose and adding a new category. We saw before that the request always getting the information from the front end, how they user is sending the information. And then we will read them and post them to the database. Let's create, for example, a constant, we can call it or let category. And this will be a new model of category. So this category, we have imported it already here. And we will have the object of this category will be name and also icon and color, exactly like the schema. So how I would get this data from? So request dot, body, dot name. So the front end must send me exactly this name. So also the same thing goes for request dot, icon, dot or sorry, dot, body, dot icon. Also for the color. We add here. The color. If you remember, when we posted a product here, we had something like save. So I say the model dot save, and then this save will return me a promise. And then I return back with the status that created products. And we talked before also about await and async. So let's do it now with a weight and async. So using a weight and a sink, I say category, which I created it before. I can say that our weight of category, which I created dot save. So in this case, I am waiting until this saved. And this save will return for me a promise with document or the category itself which is created. And then I check if there is no category, like no category created. Then I say return error. So the response dot status will say 400 four, for example, dots and that the response for example, or the category cannot be created. For example. And then if there is category, then I say response dots end the category. That's very simple. As a recap, I create a new category model and then I filled it with data. I saved it using Mongos and then I was waiting here until this category is ready. And then I check if there is category, there is data inside this category, then I send it. But if not, I am returning an error. Let's start our server now. Mpm start connected to database. Everything is okay. And I use Postman. Postman for example, I created this category. I said name is health and icon is icon health and some color. I send it and I see it's posted successfully. And I got a new ID of this category to check if it's really working. We go again to Atlas and check it in the database. I go here and I found it already. So let's create another category. For example, like computers. And this computer has icon computer and some specific color in front end you can create a color pickup. Color pickup. We'll assign to you the code of the color. For example, I say 444, and I send it and I created a new one. I go to Atlas. And say refresh. And we will see that that category also is added here. So we have computers and health. Now let's delete a category. Deleting a category is the same. So we can't say router dot, delete, not post. And I say that out which I want to assign for deleting a category. And then I say request and response as a callback. And I would use this request and response. Let's do it here with promise way. We did it before with a weight and async. Let's do it here with a promise way. So first, I call the model, I say category dot. There is method called find by ID and remove. So we find an ID by and remove it the same with find by ID and delete. So here I need to find the category which I want to delete. So by ID. So where I will get the ID from, I will get the ID from the user or from the client. So the client will send me the ID somehow and then I will find it in the database and deleted. So how I can get the ID from the client? There is one way, It's very good way. It's through the URL. So I can't say here by two dots and then I can say by ID. So this ID, you can put it as you want, as any name you want. Then the URL will look like api slash v1 slash the ID, which I want to delete of the category. So here, how I will get this ID from the URL. It's very simple. I say request dot params dot ID. So here this name is the same name as, as I assigned here. So for example, I say category id. I, then I must put here category ID. So before we saw that we asked for the body. The body is when we send the request inside the body. So here we have body and we are sending in the body of the request, the data. But now we will send them or we will send the ID by the URL. So as we see here, that this method will return for us a promise. So I will say then and then the promise will return for me a document and the document which is the deleted category. So I say here, if there is category, like if you find it, then return a response dot, status dot or sorry, 200 and dot JSON. And I can create my own object. I can say success is true and some message to the user. So I can't tell him the category is deleted. And then if there is no category, when I don't find that category else, I say return, response dot status. The not found code is 404. And that JSON, I say success, false. So I didn't find that category and nothing is deleted. So I can say in the message category not found. But what if there is some error happened in the server? For example, not about not finding that category, but some error, like connection error or if I buy the wrong data, wrong ID. So I can't say that with the catch error. I say that please find for me or send me a message that there is error happened in the server. In general, it's not about found category or not found category. So here I say return response, dot status. The error in general is 400. So JSON. And then I say success is false. And then I can send the error to the front end to the user. So now let's test this API, the deleting of the category. Let's create one and deleted starting the server again. Mpm start. We are connected to that database. Then let's create, for example, new category computer for example. Yeah, this name, we keep it the same. And I copy this category. And then I change this method to delete. So here I say after categories, I say the ID of the category which I want to delete. And then I press Send. Nice category is deleted. If we get the list of categories again, if you want, you can see here the history of what you did before. So let's get a list of categories. We still have the old category which ill-health that deleted also. So I can go here and say delete this ID. And then if I go back to get, I would get empty array. So we don't have any category. Now, let's try to delete not found ID. For example, I can say 444 here. So when I send it, I get success false category not found. That's good. It's exactly the message which we wanted. And also, let's make an error. Normally, if you want to make error in deleting the ID of like category or object ID has this format in MongoDB. Let's change this formats. For example, I make it short like this. So when I send, I get here the error. So the error is 400 and then I say success falls and the error happened. It's about object ID because it's wrong formatted. You have here that choice to make between async, await methods or with then. So the promises, they can be in both ways. You don't have any difference. But here also is more guided and here is shorter code. In the next lecture, we will see how to get list of categories and also one single category. 21. Get Categories and Category Details: In this lecture, we are going to get list of categories and categories detail. So first we will do the categories list. We did it before already in the previous lectures. So here I am using getMethod and then I'm using find. With using this method, I will get Categories list. And if there is category list, then I will get, I will send it by response. And if there is nothing, then I will send error. Let's edit, edit here. And we can say state 2s 200 that we found the category list. Now let's get one category by ID. So I will say here or alter. Also it's GET request. So this get will accept the same API but with parameter as we saw before. So I would use here async method, request, response, role function. And then I will do a constant category. And here I would use await method. So I will do here called the category. And there is method called find by ID. So using this method, I will ask for the id from the request params dot ID. And I will check if there is no category, then send the response wrong or error. If there is category, Then I will send it with that response. So here I did it quickly. If there is no category, then send response 500. The message to the user saying that the category with the given ID was not found. And if there is category, Then I will send it with that response. Let's test this with Postman. So the categories list is API version one slash categories and a get request I send, but I don't have any category. Let's add one. I have the post request here, and I have the body already at this one. And let's add another one like health. Health. That's end. So we have to now back to the GET request. Call it again, I have two requests or two categories. Let's get this category only by ID. So I will pass just the ID after the URL. I will click send. And I got the detailed category here in my API request. 22. Update Category: Welcome back. So now let's update the category. Updating category means that we are going to update either the name or the color or the icon. The HTTP requests for doing that is called Realtor dot put. So we've put, I can update the data in the database. But here it's mix between getting the params and getting the body, the params. We will use it to get the ID of the product or the category which we want to update. And then in that response or the request body, We will do that. We will get the data which are updated. So the same way here, async request and response will be a ROM method. And then I will constant the category in some variable. And then I will say await for category and find by ID and update. So I can find the product and then our category, and then I update it. So the first parameter of this method is request dot powerapps dot ID. So I have to pass the ID, which I got from the user. And the second parameter is the object where contains the updated data. So category has a name and icon and color. So getting them from request dot body, dot name. The same thing, exactly like how we posted a new category. So I will do it here. So if I get category, then everything is fine and everything got updated. If not, then there is error. So I am going to implement this logic. It's exactly the same how we have it in the post. So I will copy the same and put it here. So I'd I save connected to the database, and that's the state with Postman. So here we have the list of categories which we created before. Now let's take this ID and change this method to a put. And then I pass the ID which I got. And the body will be different. For example, here we have it computer elephant computers 11. Let's change it, for example, to elect through phonics. And the icon will be the same one electronic, and the color is 55 when I send. So what I've got here is the old data in Node.JS. There is option if you want to get back the old data which you send, or for example, which was the category original or the current data which you update it. Because if we go here and press on get, we will see in our list the updated data. We will have here, the electronics. But here in the PUT request, we returned the old data. So in this case, in Node.JS, you need to pass a parameter to the find by ID and update, which is called is object of course, and you can say a new through. So here it means that I want to return the new updated data. Let's save it and try it again. So we go to the port. Let's, for example, change it to another thing, for example, beauty. And here I said Beauty. And I click, then I got the updated data. If I say again here with the list, I got the all the data updated. 23. Post a New Product REST API: So in this lecture we will see how to post a new product. Like working with categories. We are going also to post a new product. So we just need to collect the fields, the same fields which are sent from the front end. And then add them as a product model and then save them to the database. Previously, we did this part. So let's refactor it and make it with our model and with our database. So let's create our copy the fields which we had in the model. So here I already feel the fields to not take so much time in filling them. They are all the same. They are all coming from the body. Let's reduce also here the code so we can use async and await. So here I will add async. And then let's move down. And we say, we have, for example, product is equal to await and the product which we created the product model dot save. So we have here now the new product is created after saving it. So let's delete this part. And we say here, if there is no product, then returned as a response, status code is 400 or 500, that it's like internal server error. And then send a message that the product cannot be created. And if everything goes well, then return the product. So what is special here? The special thing here that you can post the product easily, but what if the user or the front and center on wrong category? So for example, if I have some category ID and the user created ID from by himself, and this id of the category doesn't exist anywhere in the database. So let's first to validate if there is category is exist or know. To do that. We can the same thing, we can do, const category. And in this category we say await for a new category model. And find by ID. We saw this before. So I say request dot body, dot category. So the front end in the category will send the ID of the category which I want to add to the product. So here, if there is no category, then return response dot status, for example, 400, that the user made a mistake and he's sending invalid category. So in general, we have all the fields and the user must send the category. If everything is valid, it will continue and adding their product normally. Let's try that with Postman. So I go to Postman and I create a new API. And the link will be the same. Http and categories, not categories. We need products. So pen I think now we can add the body here. And this buddy will be the type row. And this row is not text, is JSON. So the front end will send adjacent block to the back-end. So I have it already prepared to not waste time in typing this. So I have the name, the description and read description, image, brand, price, category, and the category. I got the string from the list of categories. So if you remember, we have two categories. I copied one and I added it here. And the counting stock is 10. Rating is for not so much good product. And reviews. Number of reviews is 22. And is it featured? Yes, it's true. So now when I send the product, I will get response of the product and with a new ID of the product. Let's check the Atlas database. Here is Atlas and we have here MongoDB, I recreate a refresh. So we see here that the product is posted already. And we notice that the category has object ID. Let's now try to send invalid category. So Let's remove, for example this and make it 80. For example. Send I got invalid category. And that is bones is 400 bad request. So the special thing in posting a product is only how we linked it to the category. So you must validate every category which is already exist in the database and then send it to the post with the product posting. In this way, you will have a valid product which is really linked to a category. 24. Get a Product & List of Products REST API: When we were preparing our API, we made a get request for a list of products. So as we see here, the product list is saved with find. And then we are returning it to the front that. So let's try that with our changes. With Postman. I see here the product, I change the post to get. And we see that we got array and list of products. That's very simple. Let's create a GET request only for one product. It will be exactly the same as get list of products, as we saw before. We just need here to add the ID parameter. And let's change this name to product. And now if there is a product, then if there is no product, sorry. So you return an error. If there is product, then send it again to the front end or to the API. But what we need to change here is not fine, but find by ID. And the ID, as we saw before, comes from request looked by the or, sorry dot params, because we have the params in the URL, the ID. Let's save and try it. Now. I copy, for example, one of the IDs which I have here for products, and I put it here after the product. So I have the ID here. And I say, I get, then I got the product details exactly like here. I would like to mention here that, for example, in the list of products, sometimes if I have a big list of products, I don't have to send all the data. For example, if I want in the front end to display only the product name and image. So I crank create a specific API which returning only list of names and images of the products. Let's try that now. So always, after we have find here, find method, if I click dot, then I will find a method called select. So it's exactly like selecting a query. So I can pass here what fields I want to display. So I say for example, I need only the name. So let's say here name in a string and save it. So here we are going to remove the product single one and we get a list. And we see here we got list of products and only the names if we want, for example, name and image. So I go to this string and I add only space. And then the field which I want to display, for example, I say image, and then I save. Let's go to Postman and we would get image and name. We notice here that there is ID, so we can also exclude this ID. How we can do that. We go also to the same string, and we have the ID in this case. So I can say minus the ID. So when I press Save, I go to Postman, send that request. I have now clean selection. So in this way, you can create your APIs with more performance and more efficient. So you don't have any obstacles in memories for loading to the client. You need a list of product. So just send what you need. So you can create a special API for that. So you can send what you want through this API. 25. Show Category details in the Product Populate : So as we saw previously, that we are getting a single product in this way. So, but the field of category is only the ID. If I want, for example, to display the product with the category name. So I have, for example, the product detail, but I want also to show their name. So it's not nice to go and get another request for the category and then merge these two requests together and show in the front end what I need. There is a very beautiful way to do it in MongoDB and Mongoose. So after find by ID method, when I press dot, I see them MSO there is populate. Populate mean that any connected ID or field to another table will be displayed as detail in this field. So what field is has, for example, ID, which is linked to another table, as we saw before in the schema we have here, we created the category is object ID and the reference category. So this category actually is ID as we saw before. So I say a stirring populate. Category. I go to Postman and then I click Send. I see that I got the details of the category. So here in this way, when I create a GET request for a single product, I assume that I am in a product page. I send a request to get the product detail, and then I get also the category detail so I can display them also in the product's page. It works also with the GET request. So they get in general. So if I want here to have all list populated, so I just say populate category of all lists of product. I press Save, go to Postman. I get list of products and IC them already populated. Some of them, they are not connected to a category. They are previously we created them. So here, for example, this product, it has a category and it's connected to some category in database. So as a recap, if someone asks you how I can connect MongoDB tables together like relational database, I just create a field in the original table. And then I say in this field that I want an object ID and it's referenced to the schema which I created for the other table. And then when I am creating a GET request, I say populate this field. So this field must be an ID and then it will populate what is related to that table. 26. Update a Product REST API: So now let's update our product. Updating a product is exactly the same way how we updated a category. But as we saw in the post, we need only to validate the category. Though going to categories, let's copy all the PUT request would be exactly the same. And then I go to the product, I add the new route. And here we have product or put ID. And then we will do the same thing, which we did for category. So let's change this to product. Here is product, product model. Find by ID and update. We have the perimeters requested params ID and I will get the fields from here. Let's copy them the same and paste them here. So we have all the fields of the product, new. Yes, we want to return the new product. If there is no product, then send a bad request or internal server error and then say, the product cannot be upbeat. And also, if everything is fine, then send the new product back. We only now missing the part where we would need to validate the category. So again here we get the same thing here. And then I say paste cost category, and then I am asking for category. And if that is not category, then send invalid category to the user. So let's try it now with the Postman. I go to Postman, let's copy or we have the fields already here. So we can change this, get to put. And here I pass the idea which I want to change. So I say here, for example, this ID. And then let's change it to product one in new. And here also description you and Ford example. Let's update the price 32. And that's it. We send the post request and we got an error here that it's invalid category. So let's make the right category. So we go here to the categories API and pick up the right one and updated here. And they send, we got again the new product. So we see or hear the product new and the description is in U and with the new price. So the only thing we did here that we also, we validated the category. So in the front end, as we will see later, that we will have Forum of the product. So when I click on Edit, then I see the fields already filled. So I just update the fields which I need and then I send that request again. Let's check also the database if everything is updated. And then I get the product list. And I see here the product has a new description and a new name. And of course also then your price. 27. Delete a Product REST API: Also deleting a product is the same way how we deleted a category. But here I want to mention some point which is very important to validate our API. Let's first copy also that delete requests from categories. I will take this one and then paste it here in the Product API or product routes. We replace everything to product. Everything is replaced. So we have now all the states. And let's try it now. Let's get a list of products. Will get we have all of these products. Let's remove the old ones because they are empty. So we can select one of the IDs, change this to delete, and send that request. Now saxes through and the product is deleted. What I want to mention here is very important thing. So what if I send a bad ID like this? I will see that I will get error that the object ID is not valid. So we need also to validate the object ID in all requests. So in this case, we catched an error. But here in the PUT request, that request there is no any catching the error. We are just checking if we are getting a product or not. But here it's checking the ID, so it will hang somehow. So let's change that to the PUT request and make a problem in the, in the ID. For example, I remove this one and then I send a request and I see the backend is hanging. That's why I prefer more this way, the promise way. So I can say always what I can see, what I can get and what I can catch. But if you want to keep this way, so we can also not validate only the category. We can validate the ID. How we can do that? The ID should be the type of object ID which is stored in Mongoose. So here I will start first to do a constant. Require mongoose. This constant Mongoose. It has a method where I can use it in the PUT request. So I can't say Mongoose dot is valid object ID, so I can pass then the request dot params dot ID. So if this valid, then I continue. If not, then I return a response about the error. So as we see here, this is returning a Boolean. So let's put it inside an if. So I say here if Mongoose. So I will send also a bad request in this way and I say invalid product ID. And in this case, the product or the API will return for me error when I am passing along ID. Let's try it now. We have wrong ID. I see that I didn't return any error. This is because I said if is valid then return error, so I should have not valid, so I add not. So let's go back again and send the request again. And I get error invalid product ID. 28. Get Products Count for Statistics Purposes: Welcome back. Sometimes in the admin panel, I want to show to the admin how many products I have in the database. So in this case, I want to see an API which is giving me back all products or how many products I have in the database. So it will return only a number. Mongoose has a lot of methods. So based on those methods, you can return any query you want with an API. For example, in Mongoose, you can have from the model product any method you want to return. So you can create your own API based on what Mongoose provide you. I won't count of the products. I want total total price of my products. I want, for example, total or price of the orders, total sales, any statistics I want to have in my front end, for example, I want to have admin panel. In the future. I will show you that with some statistics. So for that, you need to create API, which is get normally to get what you want from the database. So let's add a new one here, like router dot get. It would be getMethod of course. And then say, for example, get slash count. So the API will be after products get count. So the second parameter, it will be the same as getMethod. So let's copy this one the same and just change the road there. So I say get count, I have async response and here I need to change based on what Mongoose giving me. So we create a constant, call it product count. And here I would delete until the end and say for example, there is a method set count documents. So I want to see how many documents in this model or in this table. So count documents and then it will return the count or as a callback. And then I say just return the count. So I get the count and return it. And then the count documents were returned for me, the product count. So here I say, if there is no product count and then return an error to the user, else, send the product count. That's it. Normally we return a JSON. So for example, I say here, product count is a product count, or for example, I say only count is product count. You have freedom here to choose any name. I prefer this one. Let's test that we supposed man, I go to Postman and then I say products GET method, get count. And we execute this. And we see product count is three, so it's really three. Let's check that. Yes, I have first 1, second, 1, third 1. That's cool. So we can now show to the admin what products or how many products he has in his talk. 29. Get Featured Products REST API: Another statistics request can be, for example, I want the featured products, like how we see here in the homepage of this website. We are seeing some featured products which are displayed always on the homepage. So previously in products model, we had something or some field called is featured. Is featured has a Boolean value like true or false. This mean that this product should be displayed in the homepage or not. Now let's make an API to get only the featured products. And to make it more complex, we can have account. So for example, I can get three featured products or last three featured products or last six featured product. Let's do it now. So any GET request is like starting with router.get. So let's copy this one and build our featured API. Or instead of getting count, we will say getting featured, featured products, for example. So in Mongoose, we need to find the featured products. Only, not all products, only the featured one. So I say here, products dot find. And as you remember before, we had some filtration. We just talked about it, but we will see how to build a filters with the product. So anyway, so now I find it's accepting like object and then you can define what fields are required to be the value. So for example, I say is featured must be a true. So all products which has featured through, then I will get them. So here everything stay the same is deed only the object. So ISA here just returned for me the products. So I say here products, products, products. Now let's check that with Postman. I go here, I say Get feature. So we send and we got only one featured product because we have only one featured product in our API, so in our database. So if we check it here, so the first one has, is false. The second is also false, but the last one is featured. Okay, so now I don't want to feel my homepage which featured product for example, I have like this page for example, I have 200 features products. So I won't only, for example, five products. To do that, we can merit also some limitation to our API based on what user is sending. For example, I can add here, as we saw before, we can add any parameter like before, we add an ID. But here we can add count for example. And then here I will get this count. Count is equal to request the params because its parameter and count. So if there is request dot count or request a torque params dot count, if the user pass something, then get it. If not, then return 0. So this like if here. So if there is count past with the API, then get it. If not, then return 0. So this count can be this value or this value. It's exactly like IF statement. So how we will use this count? It's very simple. After I find what I want, only the featured product, I say limit count. So let's try that with Postman. We say get featured. And then the count which I want for example three, then I will send that request. We will not is that it's hanging. So there is error. Let's check what is the error. The error is saying here that unable field to parse find products is featured through rejection limit three, Return key false. So why this is happening? Limit field must be numeric, but we have it numeric here. Because that, because here, this request dot powerapps dot count is returning, as you see here, a string. And this is also will be a string. So we have here a string value, not a number, because limit is asking for a number. So to change it to easily to a number, just place a plus behind this drink. So now, after we save and restart, the server, asks for our API. We will get the featured product. 30. Filtering and Getting Products by Category: Continuing with filtering, Let's have also filtering by categories. So when the user selects some specific categories, he will get those products which are in that category. And this is normal filtering in every workshop. So we need somehow to adjust the GET request or get product list request to have filtering by category. But first, I need to talk about something we experienced before. Two types of parameters that we can send to the backend. First one is URL parameter. So the user can send any ID after they, you are ill or in the body parameter. So we have body. And inside this body there are some parameters, and also with the URL. So we have another type of passing values to the backend, which is called query parameters. Query parameters are used always. In this case, for example, I have URL API, URL localhost, and then I pass the query parameter. The API parameter is passed like this, so I can pass here number, but the query parameter is going always after a question mark. So I can't say always that I need here a categories. So as we saw before that we can also filter in the find method. So after passing the model and then find, we can pass object like how we did before. Like is featured like one of the field must have this value. But now let's make it as category. So this Find we must have category and with a specific ID which is passed by the user. But how we can make it multiple values, because here I can have only one single value. It's very simple. You can just pass an array and automatically mongoose will realize that all of these values must be in that category. And then this will return the right products which has those better categories. So I can't say here something like this, first category and second category ID. So let's make it here like something different. So to be more different. So now we need to take somehow this query param and split it to an array and then pass it to this find. So it's very simple. I say if there is request dot, jquery dot categories, which is this one, then let's store it in some constant. Const, for example, filter. And this filter, we will have the value request dot query categories. And we will split this value. So we split it by comma. So we say split, split the string based on comma, and then it will return for me to items in the array, which is one string and the other one. So simply, we can place this variable here because we got it splitted as array. But because of scoping in JavaScript, we cannot assign this value or uses value out of this if, because other fields cannot see it. So it's better to create the variable here and give it as empty array. And this variable, I assign to it the split, and then I am using it here. Let's try that with Postman. So I go here and I tried to get the product. I get nothing because that I am forcing the API to have category. So when there is nothing, then it must have a category. So let's have like more dynamic way. I make that as empty object. And this empty object will be assigned and has value when there is params and or query params. Then say I say category is this. And then this filter, I remove all of this object and then it will be passed to the fine. So when it's empty, there is nothing. So I will get all the list of the product. And when there is query params, it would be filled with category, which is our condition, and it will have this value from the user. Let's try that again. Now. I send that request, nice. I got all the products previously. I created some products, for example, product 1 and product 2 and product 3. And they have from different categories, for example, this category and this category. So I say here, question mark categories. And the value of these categories. Let's take the first category. For example, this one. And I send, and then I got two categories or two products. So those two products, they are belonging to this category. Let's add another one. For example, the second one, by splitting them with a comma. So I say here. So we got 123. The first product is from the second category, and the other two products, they are from the first category. And when I pass nothing, then it will work normally to get all list of the products. So here the user has the option to pass the query params or not. So now in my homepage, I can have, for example, some banners which are displaying some specific products from categories and also the user when he goes to the product page, you can also filter these products by category. For example, it will be something like checkboxes or for example, some pills. So he can click on them and select the categories which you want to display the products for. 31. Changing "_id" key to "id" - more frontend friendly: When I am getting a product or list of products, Mongoose or MongoDB is sending the field with the right how I did them. But the ID, it has some small problem. It has this underscore. I want the ID to be only ID as a key, so I can use it everywhere in my applications, not only, for example, for the application we are doing in this course. So I can use this backend with another applications which are normally mostly accepting the ID only as a key. Somehow. Mongoose, we can also copy this ID and create a field called ID only without underscore. So how to do that? It's called virtuals. So with this product schema, which we created before, we can always create a Virtual ID. And this Virtual ID will have a get. And this get will be from the ID which is passed in the product schema. So this is a way how to do it and to hex string because we have hexa strings for the ID, which is called object ID. And then we need to enable some option for the product schema. And say that when I want to send some value to the front end or to the API, we enable the virtuals because this is a virtual field. So in every schema, we can add those two or four lines or two methods. And then we will have the ID. So if we try it now with the Postman, I can send. And I will say that I will have the original ID and the ID which I want. So mall front end friendly, I can use this ID directly without this bothering underscore. 32. Introduction: Now we arrive to the last module, which related to the back and development. We need now to upload the images with our product, as we saw before, the product contain two fields. One of them is a main image and the second field is the images. So where will be more description about the product like a gallery images? So in this module, you will see the main step is installing Walter library. Library is a famous library used to upload files to the server using Node.JS. And in the second step, we will find out the best configuration for our E-sharp because we need to configure this library to use and upload the files to our server. The third, we will see how to use the destination and uploaded the file names. Always when the admin upload a file or an image, he must specify the file name. But no, we can't do that for the admin or for the user. We don't have to let him named the file. You can upload any file and it will be encoded in our server. Using Postman also is very important for our case here to test the image upload, we will see how to test the image upload with a postman using uploading one file or multiple files. And we will not allow the user to upload anything. We need him to upload only specific types of images, like with PNG extension for J Beck. And of course, these all done for a single file. Now we need to extend the library to make it possible to upload multiple files. And multiple files is needed for us to upload many images for the product gallery. And finally, we will see how to fetch this product with the images and the gallery images to see them in the front end. Of course, we will fetch only the URL of the image. I hope you will enjoy this module and see you in the next lecture where we will start installing mortar library. 33. Users Model & Schema: As we had in our user model before, we see that we need a name and e-mail and password, etc. So let's build our users schema exactly how we have it in this model. On the right. I wrote them already So we can quickly go over them. And then you can implemented from the code which I am going to upload to the resources. First, the name of the user is a string and it's required. Second, the e-mail is a string and also true required. And also the password hash. We said we will save the password hashed in the database. It will be a string and it's required. The phone number of the user also will be a string or a number. And with the true and it's required. Here, we will identify the user if he is admin on the shop or no. So it will be a Boolean and the default value is false. The address which will be used for shipping the order of the user. So we can use a street like a string, and the default is empty value. Apartment is also String. Zipcode is a string, city and country. And at the end we have a user schema, as we did previously with the products, we created a virtual ID. So we would get ID in that way, not in that way. So it's more user or front end friendly. So we can use it in the front end as a normal ID to fetch user data or identify a user. And here we enable the virtuals for the schema. And here the normal export of the module and the schema. So this is all about the user schema. We will move now to create a user or registered user in our webshop. 34. Register a New User REST API: In this lecture, we will see how to register or post a new user as any post request. We can also post the user data in the body of the request and then submit them to the database. So to make it quick, Let's copy one of the post request which we have before, for example, the category. So let's copy this one and then paste it in our user routes module and start to add the body requests based on the model which we had before for the user. So let's feel all these fields like we got them from the front end as normal and paste them here in our request. So first of all, I will adjust this to be user. And here we would use user model. And then I will wait to save the user. And then if there is no user, then responds with the error that the user cannot be created or registered. So let's add the fields which we need now. So I will separate this two screens and then I will add my fields here. So name, the same name. And e-mail will be email. And here the body e-mail. Let's do quickly for the rest. Now, our new user model will look like this. So I put all the keys or all the fields, which I got them from the schema. And there I assumed that I am getting that from the body of the request. So this buddy and request will come from postman or from the front end. How we will see next. Let's try that with a postman now. So we will create an object, for example, and I will assign a user and a password hash and all this information in that object. So what will be the full route for that? It will be the API route and then users. Why? Because in the app.js, we had before, all APIs routes are defined here. So I am saying AP US products and then I assign the products routes. And then here we will have users. So in our API, we will use users. So going to the front end, Let's copy one of the APIs we had before and paste it here. And here. Instead of products, we will say users. That's perfect. So let's add a post. And then in the body, we will add a row. And the type of this row is JSON, because the user will send the data in a JSON format. And then let's create our object here. So I would say the name, and I assign any name, for example, James, and the same thing for the rest. So let's feel them. So we have here the password hash, the phone number, the admin, Yes or no, apartment, zipcode, city and country. So in this case, we will have one user which has these properties. We should not put the password like this. So we have to hash it, as we will see in the next lecture. So I pose the data now and I get all of this information. So we have here name than username, and the data and all information which we entered. And also the API responded with ID and underscore ID. So the user has created in the database. Let's check our database on Atlas. So when we go to our cluster and then collections, I will access our database, which is users or e-shop database and the table users. And we will see the user is created here. I think I missed one field which is not sent with the API, so we have to add it. So let's add it here, which is street. So we put three it also, and it's 3s. For example, 100. I'm going to add different users with different names to feel our database. So I will say James, for example, I would say Tom and Tom here. And the same password, Let's assume he has 777 here and the same address for example. And we will send, send. We will have also the same that also another user like Mike. We will have here, Mike small m. And also the same information like let's say here it 88. And the street number, for example, five, the flat is 4. So in this case, in our database we had three users. As we will see here. I'm refreshing the page. And we will see here that we have three users. 35. Hashing the User Password: Saving the password, in this case as a plain text is not secure because if someone got somehow our database, he will see the list of all passwords of all users in our database. So it's better somehow to hash it or encoded somehow so anyone can not understand what is this, the real password behind this hashing or it is encoding. To do that, there is a library, it's provided by NodeJS. It's called decrypt the js. We can install it here in a new window. So MPM install be gripped JS. And I'm going to install this library and then import it in my application. So I would say caused, be gripped and require decrypt JS. So how we will use this library? So I will not ask the user or the front end for a password hash. I will ask for a normal password, but internally in my back end, I will encrypt this password. So here I will say be crypt dot, hash sync. And then Hash Sync will ask for a string and also something called salt. The salt is, for example, like extra, extra secret information so that any person cannot decrypt this hash. So for example, I will add here my secret. You can add any secret. For example, you can say my cigarette. You can add anything. I will add here, for example, number, it's 10. And I will not ask the user for a password hash, but I will ask him simply for a password. Let's try that now and let's see what the server or the backend will respond to us after encrypting the password. So here, let's create another user password, not password hash. So it will be from one to six also. And he has some information like we had previously. Let's not make him admin for example. And I will send, and we will see here the password hash like this. So it's not exactly what the user sent. So we will use somehow when we login, we will compare this hash with the password which the user used when he locked in. This is also will be done by decrypt library. So now we have a secure back-end or secure object of the user so nobody can resolve or decrypt this information. 36. Get User and List of Users Excluding Password: As we saw before, that we created GET request to get list of users. And also we can create the same thing for getting a single user. So copying it from categories also. And I am going to change this category user. So in this way, we have a list of users and get single user. Let's try that with a Postman. I go here and I won't get one user which has his ID. There's like this and I won't list of users. Then I get them like that. We have a security issue here. I don't want to send the list of users with their password hash. So it's better to send the API or the API fields without Password Hash. How we can do that? Previously, we saw that we can exclude some parts from our API or some fields. How we do that after we call the find method, we put Select and then I press Minus, and then with minus, I can specify what field it should be excluded. For example, here in this case, I will say password hash. And then when I call the API, I will see that I got fields without password hash. Let's do that also for the single user. I will put here select, or we can copy this directly. It works also with find by ID, like with find and width, find by ID. Save it. Try it. And let's get, for example, this user with this ID I posted here. And we see that we got that user without any password hash. We can also, when getting list of users, for example, in the admin panel of my application, I just want to display the name of the user and for example, phone number and email. So in this case, you can create an API which has only these fields. So you can select not with minus, but you can say name, phone, email. So then you will get only this fields with this request of this API. So let's get them. We got name, email, and phone only. This is very helpful when you want, for example, when you have a beak list and then this big list, you want to reduce it. So you want only to select a specific fields which you want to use in the front end. Let's put it back to password hash. So I want only to exclude the password hash and get list of users with all their details. 37. Login a User REST API & Creating a Token: In this lecture, we will see how the user can log in and use the APIs. So he is required to have his email or ID and password and then send them somehow with API to authentication server. And the authentication server will respond with GW t, which is JSON Web Token, and say that the user is authenticated and is able to use the APIs which are secured. Let's start doing the first part. So we need to create a post request where person can send his username and password to the server. So let's first create a post request in our users API. So I will say router dot post, and then the path will be login. And then we will save an async method, the request and the response. And we will have the callback here. Let's do the login by email. So we will expect in their response by the email and password. So first, we need to know if this user is exist. I really have a user with this email. So first, I will create constant, give it user. And this user will have a weight method, exactly how we did before user and find one. I want to find user by e-mail. So I will say here, find one, and then it will be object. I can assign which field I want to search the user by. For example, I want to search by email. So here I will say email. And the email will come from the request dot body dot email. So here I have the user already, which are send to look in by the email. So if I get a user or if I don't get a user, I will send error. So we will do that return user or response dot status for 100 dots end. And then we will say the user not found. Otherwise, I will send in the response that the user is found. And it will be in the sand object like user. Let's try that out to be sure that this is working. So here I need a post request, I remove this, and here we will have a login. And then we don't need all of this. We just need the email, as we said, and the password of the user. So here I will have password. For example, let's say 1, 2, 3, 4, send it. And then we will get this user really exist with this e-mail. Let's make mistake in the email. You make two, for example, I will get the user not found. So we are on the right path now. So we found the user which we want to login. To login a user, we need to compare the password which he entered and with the password which is already exist in the database. But we have already a hashed password. So we need somehow to unhappy or decode this password and then compare it with the password which you sent by the user. And then I say, okay, you are right, you are authenticated. So after I be sure that I have a user in my database with that email, I want to check that if there is user we have before and decrypt With compare sing, I can't compare two passwords with the hash. So I will say that request dot body dot password, which is sent by the user and then compare it with the user dot password hash, like the user, which I found with his password hash. So if this compression success, I will say, for example, sent to the backend or to the front end. We will say, for example, response dot status, for example, to a 100 dot send user. Else. We delete this part. And we say, for example, with 400 and say password is wrong. Let's try that out. And here, for example, I have this password, username. I would say password is wrong, but do you remember we have the password in this way from one to six and the user got authenticated. So when the password is wrong, we get password is wrong. So now we come to the important part. So we saw before that the server will respond with JSON web token. So from where I will get JSON web token in the back-end. In Node.JS, there is a library called JSON Web Token. So we need to install this library. So I go to the other window which I had four for installation, I would say npm I. And then JSON Web Token. Installing this library will give me the ability to use JSON Web Tokens. So let's have it in our constants or imports we can say, okay, college AVT require JSON web token. So I can use this variable now or constant to generate the JSON Web Token. How to do that? So when the user is authenticated and everything goes fine. So I will say const token. And then I would use this library JSON Web Token, that sign there is a method there. And this method accepting the object, object with a payload and secret, which is secret or private key. We will talk about the secret. So this JVP, those sign as we saw before, it's asking for object. And this object will have, for example, you can't pass anything. I can say, for example, user ID. And the user ID will have, for example, user dot ID, the user which I got here, and with his ID. So here you can pass the data which you want with the token. We will see how to resolve the token in the front end. And also how we can compare the token in the authentication API. And here in the second parameter, we need to pass a secret. Secret is something like, for example, a password which is used to create your tokens. So it can be any string. For example, I will say, for example, cigarette. And after that there is options. And in this options, we can add some options to the token, like expiration date, which we will see later. And in their request sending succes, we will send the user with his token. So I will say send user and user, for example, email that send only the email and the token. So in this way, the user will get the token in the front end and can use it to access the API. Lets try that out. So I go to Postman. I will use log in. Again, we have password wrong. Let's put the right password. And then I got the e-mail and a token. So this token is created by the secret which we have here. So you can make what you want. And this secret, nobody knows about it. So he cannot anyone create a token like with the same tokens which are used in your webshop. So in this case, no any user send with the API, for example, any token, and then it will have the response, right response because he doesn't have the Secret. We will see how to resolve the token with the secret which we created so the user can get the right response. So if you remember, we have here the environment variables. So here we can put our secret. For example, I can say here secret. My dog is nice. So I say here secret. And we will use it here. We will say constant. And then let's say secret is process dot environment variables, dot secret, which I created here. So let's pass this secret instead of the hard-coded string. Let's check back again to be sure everything is working fine. So we got a new doc. So sometimes you see that when you are locked into a website in the next day, automatically you are logged out. This happens because this token got expired. So the server has some expiration time. So when you try to use this token, again, the server will respond to you, sorry, this token is expired. How to set expiration time? The third parameter of this sinusoid, it has options. And these options can be one of them. For example, expire in, expire in, you can specify one day, one week, one month. I want one day. I say one d. If I want one week, I say 1 w. So normally, Let's look, for example, for our web shop, we have the token for one day. When I come again after one day to use any API and I am loading the expired token, then the server will say, sorry, you cannot use this API because it's expired. Let's save it. And we will see in the next lecture how to protect our APIs. So they user cannot use any IPI only if he has a token. 38. Protecting the API and Authentication JWT Middleware: We saw before how the user now has the token. Now he can use it to access the data or our APIs, but how we can make our server protected. So no one can use the API without a token. As we saw before in our app.js, we had a middleware. And the middleware is checking everything, going to the server before it gets executed. So here in this point, I want to check if the user is authenticated or not. The sequence. To do that, normally, I create in my, for example, I want to create some helper folder. And in helpers folder, I will create a new file, call it for example, GBT dot js. And there is and there is a library called Express JWT, which is used normally to secure the APIs in our server. So let's install this library, MPM express JWT. And let's ask for it. So I will say constant express JWT. And then it will require express JWT. And the protection function will be as the following. So I will create a function, call it Authentication or our JWT. And this method will return expressed DWT as a function. And this function, it has options. We talked before about the secret. The secret is based on some string where we can create our token. So when someone pass any token to our, for example, backend, we need to compare it with the cigarette. So if the token is generated based on that secret, then he will have access to the API. But when his token based on different secret, then the API will not work. And as you remember, we have imported this secret or put it in the environment variables. So here I will say const secret again and then process the environment dot secret. Another option which we need to pass also is the algorithm is generating this token. If we go to the website of JWT io, we will see that the token can be generated based on many algorithms. Here are the most used. For the example, I'm using HS 256, which also library JSON Web Token is using. So we can have, for example, algorithms is array HS 256. Now we explored this method with the module, so we say module dot exports is our JWT. So in this way we will be able to use it in our app.js. So here I will say up, not use our JWT coming from constant of DWT, which is required. Helpers JWT. So the middleware is used now. Now our server is secured based on the token. So any request we'll come, we'll be asked authentication JWT. And then we go here or express JWT where it turned for us. If it's possible that the user can use this API or not based on his token. So let's check now if our API is protected or not. So I will ask for a get of list of products. I go here, I send that request and then I see that unauthorized error. So no authorisation token was found. Express JWT returned for me this error. So I need somehow to handle this error and sent to the user that required data. But first, how we can add a token to the request. Normally adding a token with a request come with authorization in Postman. And also in the front end, you need to use, for example, a bearer token. And bearer token. We will need to pass the token which you got by after login with the user. There are different types of authentication we will use here, the bigger one. So before we had also here the token after we locked in with a Thomas user. And here we will pass this token. So the authorization here coming for this API loaded with this token. So after I send the request, I will get there i data. If I remove that token, I will not do that. I don't have any authorization in front and we will see how to load token over the request in the headers. So now we are sure that our token is working. So let's make a change here. Make error. We will see that on authorized error, invalid token. So we have different errors here. So we need to handle this error somehow. We will see that in the next lecture. 39. Authentication Error Handling: We saw previously that we got some errors in our API. So we need to handle those errors to be displayed in more beautiful way for the user or the front end. Handling error in RGS can be done simply in this way. We go to the middleware and we say AP US. And we create a function which would contain error as a callback request response. And next, in this case, this method will be executed every time there is an error in our API. So here you can check if there is error. Then you can ascend, for example, response.status. Like for example, let's say 500 and the JSON. And in this JSON USA for example, a message and this message saying error in the server. So any error can happen in the backend will be called with this message. Let's try that with the error which we got with authorization. So I will make a mistake here in this token. So we will see here that we got error in the server because we have a problem in the token, but we don't know what is the error exactly. So we can classify these errors based on the type. Because if we print this error somehow, let's say instead of the message, the sprint, this error, a mistake here and then try, we will see that the error has a name. Based on the name. Maybe I can classify the errors or we can keep it like that. It's up to you, but we can make it more beautiful in the current way. But first, to have a clean app.js, Let's move this method to our helpers. So let's create file here, call it error handler to JS. And we create a function, call it error handler. And it will have the same parameters, error, request, response, and next. And then we can handle what we have here. So we can take this if paste it here. And in this way, we can keep up J as clean as possible. So here we have to say error handler. And error handler is constant. Error and learn is required from the helpers and error handler. So based on the type or the name of the error, we can classify our errors. For example, let's say if error dot name, we saw previously that we have a name, an authorized error. So I will return here status 401, and the error will be like a message. We can say that message is, for example, the user is not. As we will see also in the future, we will have type of the errors which is called validation error. We will see that later when we are going to upload photos. Or we say error dot name will be, for example, validation error. Then the response will be the same as this. But for example, let's be enough. Now with the error only, we will change this message when we will do the upload of the images and the files. And for general errors, it's better to handle that also. So we have here returned response dot status. And when there is some general, we can say it's a server error, so it's 500. And then in the JSON, I send the message as error. Or you can send the error directly without a message. Here, we will brace return and return here also. So we have now an error handler for our authorization and validation. So now in the front end, when I-I do some unauthorized sync. So when I ask for an API without any token, then I will get this error. And if I do, For example, I upload a PDF and I am not allowed to upload a PDF to our Thurber, so I will get the validation error. And also if there is not classified error here, then we will get the error in general as a message in the JSON. It's nice to have some comments always in the code. So you can play some comments to explain what type of the error is this. 40. Excluding REST API Routes From Authentication: Welcome back. Now we have totally a secure API, so nobody can use it without authentication. So in this case, the user, when he wanted to look in, he must be authorized. So this is not logical for us. So the user can be able to use a login to get a token. So in this case, we need to exclude somehow this API from to be authenticated. So here in Express JWT, I can't say unless. And in this unless I will have object where I can locate empathic is the whole APIs which I want to exclude. For example, let's exclude the login. Do that. I need to specify all APIs which I want them to be excluded. So I can say here, api slash, v1 slash users and login. So I want this one to be executed. Let's try that now is Postman. And we are still not authorized. This is because I need to add another slash here. So we go again to Postman. We try it and we have the token again. So you have to be careful that you have to have the slash here. So we can also add the register. I already added that it just the API, which is exactly like the post. So here in users, I have the post register, which is exactly the same as post. So the user can also register an account in the webshop. And here is used for the admin who want to remove or add users. What about the products? Products Also, I need somehow to get the product for free without authentication. So I don't need the user to be authenticated to get the product, because I don't want people to log in. Then they can see my web shop. I need them to get the product list without any authentication. So how we can do that, we need to specify the method, the HTTP method. So I can say print me only that GET requests, but don't allow post. Otherwise people will be able to post products to my web shop. So to do that, this path method accepting An object and this object has a first field as a URL. And second field is methods. And URL, I can specify the URL as we have it here. But instead of that, I will use products. And the methods will be get, for example, and options. And those will be an array. So we see here we specified the API URL, and then we specify the methods. Let's try that. I will go here to get list of products. Without authentication. It works perfect. And when I remove that, it will not work. So it's better to have it like this so the user can get the product list in the front end. I refactored here the code, so it looks more beautiful. So here we have the API variable, which is we get it from environment variable. And here I'm using backticks to inject the variable inside the strength. But now we have an issue. Do you remember? We had before in the APIs for products, we created methods like for example, get featured and get featured. We needed also to be public because I want to show the features product in my front end without user authentication. So here, if I want to try it, I go to Postman posted here and I say three featured products. I will be not authorized. In this case, we need to specify also this URL here. But then we will have very long list of APIs, especially by the time when we have very big web shop. Because we need a lot of APIs. Not only saying, for example, give me the feature product or give me the product count. So the nice thing here that I can use STD string like that, I can use regular expressions. Regular expressions are giving me the ability to specify everything after the products, for example. So here with this string, I can be able to use this one. So because here we have I have this star. So anything after products work. So now after I built my rejects, so here I say API slash, v1 slash products. Here is escaping slash. So it will not make any conflict with the slash which we have to define. This subject is about regular expressions. So you need to know more about these regular expressions. I am using always rejects tester, which is always located online. That is a beautiful website called regex 101. And here you can test your regular expressions. So here I will take this one and try it in that website. So I say here, something like that will be allowed, But if I made a mistake here, then it will not be allowed. So it's exactly this formula. So here it's better to use always regular expressions to specify more the APIs and have less code. So let's try it now. And we've got our featured products. Let's do also the same thing, four categories. So we have here 1 and categories. So we can get them. And for example, we cannot do eat or post them. So in the future, when I add more APIs, we need to add some exclusions here, always in this path array. 41. Add More Secret User Information to Token: We saw before when we had a login that we can't specify some data inside that response or inside the token. In this case, I can also pass some secret data, which I want to be only comes with the token. So if the user doesn't have this information in the token, I will not allow him to do something. One of the secret information I can pass here is admin. So is admin, I can say this user is admin on the webshop or not. So in this case, I can allow him to look in to the web shop admin panel or not. So the normal user cannot log in, but the admin, who has admin, true, he kept looking. And of course, in this case, it's better to separate the tables. So I can have users and customers, for example, or users and admins. So this we will see in the next lecture in more detail. Now we have the user and then I will check user is admin. So in this field, in this token, I can send the user if he is admin or not. Maybe you will tell me why you cannot do that in the front end, like check if the user is admin or not. In this case, the user will be able, for example, some hacker who has experience in programming, he will be able from front end to login to the admin panel. Even he doesn't have this ability. He can just create a fake data that he is admin. And then he can put like in the JSON is admin is true. And then he can look in. And this case, it's not good in our webshop, so it's better to have it secured here. So if the user doesn't have that I token, which has is admin, then he will not be able to look in to the admin panel. Let's try that and see our token if it's validated, right, I will go to Postman and press Send. That's good. We have now the token. So we check this token in DWT dot io. Go here, try it. I will say also this admin and expiration time. So in this case, person cannot build a token like that because doesn't, he doesn't have the secret. And if you remember, always the API is checking this token. If it was built with that cigarette, which we specified in our backend. 42. Users & Admins: As we saw before, that we excluded some API requests to not be authenticated. For example, here the products like Git and options should not be authenticated because they will be on public. So any public user can browse the products in my e-shop. So the login user who locked into the e-shop, he can post products or update to products, elite products. But in our case now the users, our customers. So if I am customer and I logged into the issue, then in this case, I will be able to delete products. And the first seconds I publish this website online, it will get destroyed. If you remember, we created in the model a field which says is admin. So here we specify the user if he is admin or no. In our E-sharp, we will have also admin panel. And this admin panel is not allowed for normal users to enter only the admins. So we have here on users table, some user roles. We have a customer and we have admin, and they are both of them in the user table. You have freedom here to do, for example, separated tables in this case. But here I wanted to mention the user roles. So you can also make them in same table but with different roles. There are many ways to do user roles in Node.JS, but I am going with the simplest way which we need for our e-shop. If you remember, after the user got log in to the application, he was assigned a token. And this token is overloaded with user ID and is admin. And here we know inside the token if the user is admin or not. And when the user sends a request, the JWT library is disassembling this token with the secret code which is provided in our API or in our server. And it will see that if it's really generated from this server or not. So we can identify the user if he has token from our e-shop or no. Till now everything is nice. So let's assume that I have a right token. And I want also to look in to my job as an admin. Letting this way it will keep us not secure because the user, in this case is able to delete or add products. So the express JWT has a great method that it's reviewing, for example, or revoking the token under some specific conditions. To do that, there is a field is revoked, and this is revoked is a function. So we can also, in the callback, we can specify if the user is admin or not. So I create here, for example, another method is revoked. And this is revoked will be a function, async function. And it will have request, payload. And Don. What are those parameters? Request is when I want to use the request parameters or the request body, I want to know something what is sending the user. The payload contains the data which are inside the token. For example, I want to get is admin from the token which is signed to the user. And this user is sending it to me with the request headers. So here in this case, I can say if not payload dot is admin. Because now I have access to this, is admin to the payload of that token. Then I will return that done is null and true. So in this case, we are saying that reject the token. So if any authorized API called and our user is not admin, then it will be rejected. And else, if he is admin, we can say done without any parameters. As we said before, we have only two types of user in our issue. So we have admin and users. If you have more roles, you can hear, classify them. And here you define what is in evoked or what is allowed. Now, let's try that with postman. If you remember, we have a user here, Thomas Jackson, which he is not admin on the shop. And this is his data. So we see here that is admin is false. And when I tried to post a product in our API and new product, I will get the user is not authorized. Let's change the token to be with admin through. Well, let's go to the database manually and change this user to be an admin. So I will say here admin through and then I click update. If I try now to use send, I will also get unauthorized. Why? Because I'm using the token which is loaded with is admin false. So we need to look in again to get a new token. So I go to the login API, I have the user and the password. I send that request, I got a new token. And let's use it in our post requests. On authorization. I play, replace it here and try again. And it's successfully posted the product thanks to express JWT that it has this method. So it was able and made us able to do, for example, this user role. Now our application is fully secure and nobody can use it or access it without any authorization or any admin role. 43. Get User Count REST API: Sometimes the admin of the workshop want to know how many users or customers he has in his workshop. So in this case, he needs an API for getting the user count. We did that previously with the products. We had an API, especially for getting how many products we have in our issue. So let's copy it and go to the user's API. After login and register, we can use it here. And we say the same getCount, but user. And here we say user count. If no user count, then return 500 and then your return for me user count. So let's save tried to his Postman. We go for example, here, I say users and get count. Try it. We have an error because I am doing a post. We need to do a GET. We try again. We have user count for, we have really four users. We didn't do also a delete request. So let's also copy it from, for example, the categories or products. We can do it from here and get this one. And then we put a delete request and I replace user, user. And everything else is user. So as you see here, it's exactly the same way how we did it with the products. We save it, and now we are totally done with the users. I am so happy that you finish this module and you will see the code where we arrived in the resources folder. So you can download it and then try things, change things, try by yourself and try to compare your code with the code which I uploaded. 44. Orders: Welcome to a new section. In this section is related totally to the orders. So we have created their products and also the users. And now we are going to build the orders. As every e-shop, the user is going to have a filled his card and then he is going to check out to submit an order. This order will come with the address of the person and also the shipping options and how he will pay this order. And we will see also after the user get logged in, how we would get also the data of the user and fill the order data automatically. So without letting the user to feel the billing address again. So we will let the data comes from the user information which we created before. And also in this section, we will see how to link the product with the order. So we will see that the order contains of many products. So sometimes I add, for example, t-shirt and trousers. So we will see how to link the order with the products. And in the back end or in the back office where the admin can login and control the orders. We will see how we will be able to change the state of the order. So it will be from delivered or for example, shipped, or even it's on hold or canceled. So here everything will be related totally to the backend. We will not work on the front end. So we will work with Postman. Student can understand how this backend works isolated from the front end. I hope you will enjoy this section. This section, as I told you, is not repeating of the previous sections. It hasn't new things. How we will link the products like array of order items and also link it to the order gets ready. And let's start. 45. Orders & Order Items Model & Scheme: Welcome back. Now we are going to implement the order schema and order items schema. Previously, we implemented the database or we planned the database based on what we need for the e-shop. As you see on the right of the screen, we have the table already of orders and order items. As in relational database, we see the connection between the order and order items. Let's start first with orders, as we saw before, with the products and the relation with categories. We had also implemented that the category has a type of object ID and the reference is to category table. So let's do the same between the order and order item. So I will copy this part. I will go to the order and I will put here order items. And here we'll have the object ID and the table of order item and required yes, through. But the difference here that we have maybe multiple order items, not only one. So in Mongoose we can implement that by aligning this inside an array. So in this case, we need to pass or have the order items array of IDs of order items which are existing in the database. So in this case, we need to create order items table. So let's have a file here. Call it order item dot js. And it will have the same schema, Mongoose all this information. The thing here we will have item and here are the items we don't have this. We will have quantity, which is type number. And it's required. Yes, true. And as we see also that we have a product. So we need to link this order item to the product. So I will say here that I will have ID or type of object ID. Mongoose schema types that object ID. And that is reference of this order item will be product. And let's exported as order item and have it as order item. And here we have ordered item schema. So our order item is ready, which we have imported here. And we referenced with object ID in order table. So the thing here that we have many relations. So the order is relating to all other item and order item is relating or referring to the product. So in my application, when I ask for an order, I will get all other items including their products and populate this products. For example, I need the name and the category also. Here I added quickly the other fields which we need, the shipping address, 12, city, zip code, country, phone status, which we'll say that a default value appending. So when the person submit an order, then the default value or the first state of the order will be pending. And here we have also the total price. How we will see that we would calculate it internally when we create the order. And here, another reference with object ID to the user table. We know which user or their disorder and the date ordered then here, that the user doesn't have to send it to the back-end. It will be automatically created with the dot now. So it will create the time where the post request is sent. And as you remember before, we had here some virtual ID. So to not have this underscore ID, we can have also normal ID. Let's copy it also and have it in the same way. So here I said order schema, create for me a Virtual ID field instead of underscore ID. So now we are ready to work with these tables. For example, here we have order and order item, so that relationship is achieved between these two tables. And now we are ready to create our API with orders. 46. Array of Refs Example of Link Order to Order Items to Products: So the order is linked to the order items by array. So let's see and read example how the front end will send this data to the back-end I created here and object of, for example, how the user will send the data to the back-end. So first of all, let's imagine that the user has a cart and he selected two products, product 1 and product 2. And they have different IDs. So order items will be array of two products, and every product will have a quantity. So in this way, I have array of order item or their item has a quantity and the product. And the rest will be the same. Except here we will see that the user will send the username, but we send the user ID creating the order. The same thing here. We didn't send their product name, but we send the product ID. So this is how the product ID is linked to the order item and how order items are linked to the order. 47. New Order & Create Order Items on Posting New Order: Placing an order in our database required data from the user. As we saw before, we have this JSON data where they user after doing the checkout, he will place the order in our database. So what we need first to create a post request in orders API, we have already a GET request. We need to create now a post request to not repeat the same process which we did before. Let's copy the simplest post request which we created in categories. And we go here two categories, post request and copy it, and paste it in our orders. So what is required from us, we need to create a model of order and the fields of the order we were, we had before and created the schema. So let's assume the simplest case as the user will send that data. So here we get the data. I paste them quickly to not repeat the same process. So we have from the user the order items all comes with the body of the request, which is this one here. So we have all other items and all the data which are sent by the user from the front end. Let's fix this stuff here. I am teaching cue that way how to call it fast, so we don't have to write again everything regarding the order because, you know, we have always post request, we have always delete request. So it's better to copy it from basic request and change the, for example, the name things to fit on our new API. So here we have ordered everything now order and sent back the created order. But if you remember, we have created order items table. So the user doesn't know in the front end that the order items which are stored in the database. So here you will just send this data. He want three times of this product and two times of this product. But for fetching this data and storing them for the admin, this will be like for example, we can say an obstacle, a small obstacle to get them again from the database. But we will solve that with Mongoose during this relation between order and order items. So when the user or the post request is sent or created, we have to create the order items first in their database and then attach to them or relate them to the order request which we have here. And as we saw previously, that order items, it's array of IDs from order item table. So in this case, we need array of IDs, ids which are in the database of those our order items. So first, we need to create those IDs or how Mongoose will create them for me. And then I will store them with the order or relate them to that order. So here, we will not get from the user directly the order item which is containing the product and the quantity know, we need only array of IDs. So we can say order items IDs. And this order item IDs will come from our created order items in the database, which we will do here. So we have this constant const order item IDs, which we will get them from after the creation of order item in the database. So we need somehow first two loop inside the order items which are sent from the user. So I will say request dot body, dot order items to loop always we use map because we know that the user will send array, array of order items. And here we will have or their item, one order item. And then inside this order item, we create let new order item, new order item model. So ordered item model. We need to have it from our models or their item. It's exactly like we are creating a new category or a new product, or it's like a post request. So I say here, or the item, what are the fields in the order item? We have quantity and a product. So I go here, I say quantity. So we have already one order item from the list of the order items which they users. And so I say here, order item dot quantity and also product, which will contain the product ID. So from order item dot-product, then we need to save this item in the database. So I say let or the new order item, the same variable we can use it. Await a new order item which we created previously or the model, and not safe. So here we are saving the order item in the database. So when we loop in order items, so for every order item, I will save it in the database. But I want this map to return for me only the IDs. So here I say return not the new order item, but the new order item dot ID. So in this case, we will get only the IDs in an array. So we created the order IDs and we attach them to the order, and we are going to save the order. Let's not save it now in the database, let's just send the order is created or the order model to the front end to the user after he post request. So let's try that with Postman. I go to the postman and I replace this with orders based on our API, how we created it. And then I will put here the data. Let's first review the authentication token and then the body, what we have this JSON for example, I am already getting these IDs from our database. So we must have these IDs in the database already. Let's send the post request. We see that we got an error. The error comes, Let's see in the console of our test server or of our server, we will see that we have here a weight. This is because we have here a weight, but This require an async function. I mean here. So here we have a weight and this require an async function. So in this case, we cannot do await inside a normal function. We need to place an async function basically is this one. So I would say here async and save and try again. And we will see that the request is created or the order is cooled recreated, but the order items are empty. Let's track this order items to see why they are not created. To track them. We can do console log of order, items, IDs. And let's see in the console what it will return for us. So here I saved. And then let's try again. Let's check the console. We will see that we have returned to promises. So we are not returning actually the ID, we are returning a promises. This because we have here async function and await, and we are returning with await a promise. So somehow we need to resolve those promises. Because the user is sending array of order items, not only one. So we have to combine those promises together. So here we have an array of promises to combine them, I use promise dot all. So here in this case, I will have a return promises or one promise, which will be resolved after that here, before we create the order. So let's try to consolidate. Again. We see that we got one promise, not to promises as before. So we need to resolve this promise. How we can resolve it, we can create a new constant. Call it Order ID is only or order items. Ids, for example, resolved. Because this is a promise. So I can say here, uh, wait for this to be resolved and then print those for me. And then I replace this order items ID with the resolved order items IDs. Let's try again. That's great. We got to them again. And in the console log, we have the two IDs which are created of our order items. Let's check that in the database. After logging in, I see here order items table is created. I didn't create that they book atlas is very smart. So based on the model I created in my database or in my code, it's creating the table for me. So here if I go to order items, I will see to order items which are created based on the postman and they have the same ID which are in the database. So now we are ready to create our order. So here we don't have anything, so we don't have order table. That's because we commented out this save. So here, after the order is created or saved, then I will resend it back. Let's remove this console log to not have our log full of unnecessary data. So here I will go now to the postman. Place an order. Great. We have now created an order, and we have here, the new ID is created of the order. So if I go to Atlas again, I will refresh. And we will see that orders table is created automatically because we have order model. So what I asked Mongoose to create for me this order model, then he created the table. So here we have other items, object ID of the new order items which are created again here. So every time I place the order, I create a new order items. In the next lecture, we will see how to get order items or the order itself more detailed way. So we will not get only IDs, we will get more detailed. We will see the order item, what it contains, and also everything. For example, which user created it, not only IDs. 48. Get Order Detail and Populate Products in Order Items and User Data: Okay, now let's get a list of orders as we have now one order in the database. We have created already a GET request for a list of orders. So let's try it now with a Postman. I will go here, create the same as post request, but it will be a GET and the authorization because always when I create a new API, I must have it authenticated. Or we exclude this API from authentication as we saw previously. So now I will use this token get list mice, we have list of orders. So we have now only one order in the database. And we are getting it with the GET request because it's an array. Let's populate the user so we can see the user details inside this request. Because for example, I want to see in the admin panel, in the table of orders, I want to see the users who ordered them. So here we go in the code and we just say dot populate. What to populate the user. Save. Try it again with Postman. We get now the user detail, all of his detail. But for me as a user or as admin, I don't need all the information of the user. So I just want, for example, his name. To do that. We just put after the population of the user, we put the fields which we want to populate. So all I have, for example, the name and in Postman, when I send that request, I get only the name. Let's post another order with a different data. For example, I will say here instead of country, Czech Republic, I will put USA. So here I will go there and say, I don't use a and a different number. Example, 1, 2, 3, 4, 5, 7. So here I will post another request or another order. So in this case, I will get in there least two orders. So we can also sort the orders by date. So because we have already that date ordered field, so we have the date here by the dot. Now, we can also sort this by date. To do that, It's very simple. I just go here and after population of the user, I say sort based on the column date ordered. So here we have, you remember a date ordered. And based on this column, I want to sort my output. So we go here, Postman, try to get the list again, and we see that we get them ordered by date. As you see, the order here is from oldest to newest. So we have previously this one on 23 of December at this time. And we have now this one. So we can order from newest to oldest. And I think this which interest the user to do so. We just align this in an object and then say that this object equal to minus one. So when I say in the sort method, this case, then it means that order them from the newest to oldest. So if I refresh and go to Postman right out, and we will see that we have the newest 1 first and then the oldest. You can check out the documentation of the sort method. It has a lot of features. So you can use them to sort your outputs based on some specific field or on some specific order. Let's now get one request detail or one order detail. So the same thing is here. I post or I get this request pasted here. And then instead of having the sort and population, we have find by ID. And here we specify the ID. And the ID will be request dot params. Because its parameters took ID. And we were renamed this to order only instead of ordered list. Here we have order, order, order. I go now to the front end and I get, for example, this one. After that, I put this ID of the order and send that request. And I will get only this order with population of the user. We come now to the important point. We have here, the order items only as IDs. We want to see the products are inside this items and the quantity that, let's clean up our code a little bit. So we have here populate. And we will have also taught populate of another field which is order items. We try that out now. We will see that we got the product and the quantity. But what if I want also to populate this product in a way that we see the product detail inside or the items. So as we saw here, the user, we got all his details. The difference here that we have array of them. So we need to know how to populate the product inside this array of order items. To do that, we have here a different way of populate. So instead doing this, the populate method will be an object which will accept a path. And here I put order item or order items. And inside this object, I say also populate for me the field, which is called product. So I will put it here and tried again. We will see like a magic. We got all the information about the order items. And in our database, the order look like this. So if we refresh, we have our order only with IDs and order items are only IDs. So in this way, we are keeping a small sizes the documents of the database, and we are doing the relations using Mongoose flexibility. If we see also here that the product has the category and the category is also id. If I want to populate also the category, we can't do that. No problem. We can say also this is populate. This is a path which is called product and then populate category which is inside this product. So if we go again, send this request, we will see the category is also populated for all the order. So to make it more clean, we can't have here this path, so we can understand the way how it's got built. So here I have say here, this one. Now I have the clean code. So this is the way how to make population of the relation between the tables in the database. We see in the future. Now how we delete this orders and how we update the state of this order, which will be in the next lecture. 49. Update Order Status REST API: After we made the GET request and post request for order, Let's do the update request as the requirements of my issue up. The admin of the A-Sharp want only to change the status of the order. So when some customer places an order to the e-shop, the owner of the shop want to process this older. So in this way, the order will be transferred from bending and then to processed and then for example, to shift and then to delivered state. So we need just to update the status of the order. We saw previously how we are updating, for example, the product. We were updating all fields so that the user or the front end must send me all the fields again. But here in the orders, we just need to update one field, which is the status, which is this one. To do that, let's do it that quickly. We copy one of the requests, for example, from categories. We get this one. We copy it to the orders. That outer put ID. We need the ID. And then I will say here I have the order. Here. I ask for the order model. And here we don't pass anything, only the status. So the status will come from requirement or request dot body, dot status. In that way, if there is no order assigned with this ID, then I am sending error. Otherwise, I am sending back the updated order. Of course you can add all fields which you want to update. But the requirements for this e-shop, I need only to update the status. Let's save it and try that with postman. So we have already this order, Let's updated. So I will have a row and the type of that or is JSON. So here I will say status will be, for example, shipped. So I put here shipped. And we need also to change this request to put. And we send it. And we got the same order as a shift. So let's get again the order. We have a get here, check it. We see the order detail already and we have the status of the order will be shipped. Deleting the order will be the same. Let's copy it also the Delete order from the category. And here we will add order, find by ID, and then it will return for me order. If there is or there, then return true success. Otherwise send error or not found our some error in the server. So let's try that with Postman also. I will change this from get to delete. We deleted and we get success. That category is deleted. We have to fix this because it's not category. We have to make it as order. And here also order. So now if I want to get a list of the orders, again, we will have only one order, which is the one which called USA. And we had now only one. Maybe someone will ask What about the order items? Are they deleted or no. Let's check that in the database. In our database we had order items and we should have two orders only to order items, but we see that the order items are still here. So we have an issue here. We need also to delete the order items of the order which is deleted. So I will let this as an exercise to you. So the exercise will be just to delete the ordered items also after we deleting the order. And then I will see you in the next video to see the solution, how we implemented the deleting of order items after we delete the order. 50. Calculating Total Price of one Order with Mongoose: Sending the total price from the front end is not a good practice. For example, if some hacker was able to send an order with a fake total price somehow, then it will be stored in my database with a fake total price. So maybe someone has order was one hundred, ten hundred dollars, but he faked it and he made it with $2. When I have a very busy webshop, I will not detect it. So it's better after the user is sending the order items, IDs, or the order items in general to the backend. We calculate that internally in the backend based on what we have in the database. So the source of truth is a database. So what I need to do is to loop over the order items which I got from the user or from the front end. And then I resolve that order items. I get the product related product. And with the quantity, I multiply that and calculate the total price. So everything is coming from the database. So let's try to do that. Here. We got order item IDs resolved. So somehow we need to replace this with a variable which we calculate internally. So let's call it a total price. And this total price will come from a constant where we are going to resolve this order items. So the same way, we click Create a constant, call it a total prices. Because we are going to loop on order items exactly the same way here. So we will do it like promise dot all. So here I will get the order items resolved IDs and map over them. And I will get ordered item ID. I will get back the order item from the database because it's stored here already in the database. So exactly as here, say async for our order item. And we get the order item through await. And we get also the model of order item. And find by ID, the ID which I got here from the map. And then inside this order item, we will get only the product ID and the quantity. So we need also to populate the product. And to make it faster, we can ask only for the price. So here I will get returned order item with the field of product inside it, only the price. And then I will go to Create Constant total price, only one. And I will say the order item which I got from the database, dot-product, dot price, because we have the price populated already multiplied by order item dot quantity. In this case, I will get also the quantity multiplied by the price. I will get the total price of one item. So mapping over all this array, I would like after that, return, only the total price. So here I will have array of total prices for every order item. So let's try to console log this total prices array to be sure that everything is going to work fine. And I am going to post a new request or a new order. I got an error here because I am console log a promise. So here, as we did before previously, that we have here only a promise, returned, promised at all, all combined promise, we put a weight. So it's simply we can also put a weight here, like weight and resolve this promise after everything is done inside. Let's try it again. Restart our server. Try to post. We will see here that we got array of two items or order items with their total price. So we need to make merge or summarize this two prices to one. To do that, we can't simply make constant total price. And this total prices array, I will reduce it. And it's reduced method. It's a famous way to get the sum of all numbers inside the array. So I have a and b, return for me a plus B. And here we add a 0. So the initial value is 0 and then combine a and B, or combine every item of this array. So here, after we got the total price, we can place it here, restart our server, place a request, and we will see that we created a post request with the order. And the total price is 146, which is combined of two order items. Let's get also this order detail. We go here, we put it in the GET request to get the details. So we will see first product, we have a 32 and the quantity is three. And also the second product is quantity 2, and the price is 25. The total price will be 146. In this way, we guarantee that the total price is coming only from our database, not from the front end. So first of all, we created the order items as we saw before. Then we got the price, total price of every order item, and then we combine them or summarized them to one number. And then we created the order with the total price, which comes totally from the database. 51. Get Total E Shop Sales using $sum: As always. And at the end of every module, we do always some post or GET request of some statistical data. What came to my mind here that for example, I want to show in the dashboard of the admin panel of the application how much totals hills I have in my whole e-shop. So the owner of the shop, when he locked into the admin panel, he see the total sales and he will be happy. So as always, let's create a get request. And the route will be get and total sales. And here we will, after we pass this API, after the orders, we will get the total sales. So here we have async, request and response. And it will be a ROM method. And we define a variable, we call it total sales. And we will get the total sales directly from MongoDB. So by using Mongoose, here, I have await, the order model. Then I use a method called aggregate. And the aggregate, I can group like join, we can say in relational database, all tables or all documents inside that table to one. And then I get one of these fields in that table and use one of Mongoose methods, like for example, some on that field. So it will return for me the sum of all field, which name, Total price. If you remember, we have a total price calculated already, how we saw in the previous lecture in every order. So we need to sum all of these total prices in one using some. So to do that, we have here an object. We are grouping the table. And here at the method, we say the ID is null. It's like that. And we name the field which we want to return in our API. So I say total sales is the sum. This is a reserved word in Mongoose of total price. The total price is a field in the order, and we have calculated it here while we are creating the order. So then I will get the total sales by summarizing all the total prices. Then we check if there is no total sales, then returned for me, error response.status. And then for example, we say 400. Not send, the order, sales cannot be generated. Else we say response dot send. Total sales is total sales. Let's try that now with Postman, I go here, I say get total sales. We sent a request. We see that we got array with ID null and total sales. So we saw that we got exactly what we have built in the group. So if I remove this ID null, I will get error because Mongoose cannot return any object without an ID or object ID 2, as we see here in this error, it says a group specification must include an ID. So it's better to put it back. Or you can also give ID by using Mongoose specifications, It's better to put it as null. So we saw here that we got an array. We can also directly BOP this array and take only the total sales. So we can say here, returned for me total sales dot pop because it's an array. And then total sales. So in this case, I got the first item of this array, or the light item because it's returning only one array with one item. So I say, give me this item and the total sales which I specified here. We try that again. We send that request, we will get total sales is 290 to this because we have here, if we get the request, we have orders. So first-order has 146 and the second order has also 146. We can also get how many orders are created or placed in my shop before how we make a total count of the products. So we can here copy this from the Product API and place it in orders. And we say here or there, count our undercount or the account holder count and here order. And with count documents, we will get the count and return into our order count, and then we will get it. Let's try that in our Postman again. So here I say getCount. And we will see that we have three orders. So now our API for the orders is completed. We are ready now to use all the API related to the orders in the front end. And in the next section, we will go back to the product for uploading the images. You remember, we have here image and images. The image will be the main image of their product, and the images will contain the gallery images of their product. I hope you enjoyed this section and see you in the next one. 52. Get User Orders: In the front end, when the user get logged in, he needs to know what orders he ordered in the history. So we need to have some at least of order history. So in this way, this API will be exactly like getting least of orders, something like that, but it will be specified only for a specific user. So let's take these GET requests and copy it to the last one. And we will say here that I want to get, for example, users older or user orders. And we need to specify as an, for example, as a parameter, the user ID. So here we say user ID. So when I am sending a request from the front end or from our API, we need to specify the user ID which I want to get the orders for. And as a condition for the find, we say object, user field must be request dot params dot. The same paradigm which I have here, user ID. And maybe we don't need to populate the user itself. We need to populate the products inside this order. So it's exactly as we did here in the order detail, how we were populating the order items and products and category. We copy that same one and we pass it here. So in this case, we will see that the order items are got populated with the products and they ordered from the newest to oldest To not have confusing names. Let's rename this. For example, we can say user or their list. And here user order list here also user orderly. Let's run the server. Pm start. Server is running database connection ready? We try that in Postman. So I have here orders, get user orders, and I pass the ID of the user, which I want to have his orders. So I pass this one and I got other items. They are looked like like that. And another order, it has also order items. So we have the three orders for this user. We will see here the same username are the same user ID. It's always n equals 4, 4. And here another one. So at the end of this section, you will see that you are able to create any requests or any API you need based on what the needs in the front end. So for example, we got here the user's orders and also we got, for example, how many orders I have in my issue. That's all about APIs. In the next section, we will learn how to upload files to our server, like images or some attachments in general. In this lecture, there is attachment of the resource code where we arrived in this orders. And you can download it and try by yourself to do some different things with the APIs based on your needs. 53. Product Image & Gallery Upload: Now we arrive to the last module, which related to the back and development. We need now to upload the images with our product, as we saw before, the product contain two fields. One of them is a main image and the second field is the images. So where will be more description about the product like a gallery images? So in this module, you will see the main step is installing Walter library. Library is a famous library used to upload files to the server using Node.JS. And in the second step, we will find out the best configuration for our E-sharp because we need to configure this library to use and upload the files to our server. The third, we will see how to use the destination and uploaded the file names. Always when the admin upload a file or an image, he must specify the file name. But no, we can't do that for the admin or for the user. We don't have to let him named the file. You can upload any file and it will be encoded in our server. Using Postman also is very important for our case here to test the image upload, we will see how to test the image upload with a postman using uploading one file or multiple files. And we will not allow the user to upload anything. We need him to upload only specific types of images, like with PNG extension for J Beck. And of course, these all done for a single file. Now we need to extend the library to make it possible to upload multiple files. And multiple files is needed for us to upload many images for the product gallery. And finally, we will see how to fetch this product with the images and the gallery images to see them in the front end. Of course, we will fetch only the URL of the image. I hope you will enjoy this module and see you in the next lecture where we will start installing mortar library. 54. Configure Server Side Upload: Okay, so first we need to configure the back end to accept uploading the files. To do that, we need to install a library called Walter. Like any library, we do npm install Walter. And with this, we will install the library and use it to upload files to our server. And as always, we do constant, Walter and required mortar. Let's see the documentation of this library. If you go to Google and type motor, you will see the MPM packages, the npm website, where we have all the usage of this library. To see more detailed usage or up-to-date usage, you can go to the homepage of the library. So here I click on it and it would take me to the homepage of mortar library. So the simplest usage of this library will be as the following, how it's in the documentation. So first of all, we need a form and this form will be provided by the postman, how we will see later. And the first usage here that we can call the molto library and then configure it with a destination on our server of the folder. So when the user upload any file through the form, it will be stored in the uploads folder, which will be in the root of the back-end application. And after that, in every post request, for example, we have a product posts we need to pass also not only the URL and the function of request and response, we need also to pass the upload, I mean the upload configuration from Walter. So here we can pass the upload and we say a single, we pass the field name, which is seen from the front end. So as you see here, the field name is called Avatar, and here it's passed in the request. But here the uploaded file will be exactly the same name where they user uploaded it. So we will have a problem when a customer, or sorry, the admin will upload the file. He will have, for example, another file with the same name. So then this file will replace the old file. And in this case we have a problem between the products may be I will lose some product names or some products images. So the best way we need to have more control on naming the files and naming the destination. So for example, we need, whenever the uploaded file is uploaded, we need to rename it somehow to some, a unique name and then store it in our server. To do that in multiple library, there is another option of having a full control on the name of files, which is called disk storage. And with this example, we are going to build our upload API. So we will use this part. Let's take it exactly the same and copy it to our application. And we will say that storage is Walter disk storage, which has two fields, the control of the destination and the control of the filename. The destination will be a function where it has the request itself and the file and the callback. The callback will be returned if there is an error in uploading and we assign the destination in it. So here, let's put our upload destination. We can call it public and uploads. So we here, we will have a folder called public uploads. We can create this folder. So we can say here in the back-end, we can say uploads. And inside it, or sorry, we could have public first. Public. And it's public will be in the root level. So it will have, for example here. And the public, the uploads folder will be inside it. So here now we have public uploads. So in the future, when we upload the file, we will see it here located directly in the public uploads. In the filename. It will be the same. It will contain the rock request and the file. And we need somehow to rename the file to fit on our needs and how it will be located in uploads. So there is another way like he is creating here. For example, the, some random mathematics to have a random naming of the application or over the file. And then he put the original filename with dash and the unique suffix which he created before. Let's do another way. So I would create a constant. Let's call it fine name. And this file name will be the file itself which we got that original name. It's already defined. And then we say, somehow to replace the spaces, it's not nice to have spaces in the naming of the files on the server. Because when you have the URL, you will have ugly URL where it will replace like with ampersand t2 for the spaces. But here we can have exactly our replaced the spaces with split. So I'm splitting the filename based on space and the replace or join. Again this space with a dash. You can also use another way, which is for example, dot replace every space with a dash. Both ways are fine. So we can also add some prefix or suffix to this name. So here we can say the filename. And for example, we can say date lot now. So here DataNode now method, if we see it, it will return the number of the day. So we can try it with the console of the Google Chrome. You can say date now. And you will see that you got the number of the date and the time now. So this is a great unique number to create our files. So after that, we have created a constant. Let's make it as a constant, not as a VAR. And this constant is called upload. Again, call it, for example, upload options. And this upload options, we need to pass it to our post request where we are creating the product exactly the same way how it's described in Malta library. So if we see here that we have also the upload single and Avatar and the field name. Field name, we need to send it from the front end. So here we say upload options, dot, single, and the field name where I want to send from the front end. So I say, for example, image. But here when we are creating the product, we are parsing request dot body dot image. This is wrong. We need to edit this field to have the full path of the image. So I'm Walter already sent us with this request, the file. So we can't say for example, constant filename is request dot file, dot filename. And this filename coming from here where we set up the file name of the uploaded file. So we will have the name exactly like how we have it in this way. Like the file original name, replaced with dashes and then dash, they don't know. Let's do it in this way. We have a filename and then we put the file name here. But when I want to fetch this data in the front end, and I want to see the, OR for example, display the image in the front end. I will have issue that. I will get only the filename. For example, I would get image 300, 300 dot J Beck. And this is a problem for us because in the front end doesn't know the original path of the file. We need somehow to have the full path with the URL also of the backend. So I will say http, localhost 3000 and the upload folder. And then the image with the name and the extension. We feel got also here to add the extension. So we have the file name only like this. We need also to edit the file name options here. To have also with the extension. We will see that when we are validating the file in the next lectures. But now let's focus on this part that we need the full URL, not only the file name. For that, we need to build somehow this string. So we can say constant. We can say base path, like the base path off their application. And we can do it with backticks somehow, like request dot. It has some field called protocol. And this protocol will return for me the HTTP. And then we will see that we have colon slash slash and we need to pass the host. So we can also do it in the same way. We can say request dot get, getting a specific field called host. This is a way how to get the host from the request. So now we build our base path. Let's add four. It also the part where we are saying the folder where it is uploaded. So we need to add also this part. So we can say it like this. And then we add only the filename. So we can say here, after that we have backticks, base path, and the filename. In this way, we build our API URL or uploaded file URL. In that way, we have the base path is this part and the file name, which is this part. Let's try that now with the postman. And try out if everything is working fine. 55. Testing Image Upload with Postman: Now let's test our changes with Postman. You remember, we created here the image field, which will have the path and the filename which is uploaded. Going to Postman. We need to create a post request on the product API and we add the authorization with the barrier token which we got before. And we have the token here to remind you, we got that token after we get a logged in user. So here I go. And then I look in a user with his email and password, then I will get the token. This. If you don't know how to get this token, what we explained that in the user's chapter. Okay, but now how we can test Postman to upload files. You remember we were sending in the body of the request as a JSON, and we were creating the JSON here and we were putting the name of the product or the description of the product or the description and the price. But here it will be different a little bit. In the front end, it will be something like a form. Form was fields like as you see in there right of the screen. So here we have a fields where we will fill it and send them to the backend. And the file field where the user can upload a file. This will be filled with a file data, and the file data will be sent to the backend through a form data. So we need to create something like a form data and embossed man. If you want to simulate a form, you can create a form data and every field will be named here with its value. For example, I will have here the name of the product. And for example, the product which I want to post will be product six. And I want also, for example, description of the product. And here will be product seeks description. So we need somehow to put all the fields which we wanted as we saw previously, the products model we have here. The description reads, description, images and everything here. So we need to have the image field, let me feel the fields here in the Postman. And then we will talk about the images. So here we have filled all the form fields which we needed to send to the backend and with their value. So for image here, it will evalue, will not be, for example, texts like here, or a value, or a number or a Boolean. It will be a file. So how we can make that as a file? It's very simple. We have postman, There is a trick that when you put the mouse, the field, where do you want to change? You can select that the type of this field can be a file. When you put the file, you will have your ability to select a file from your PC. Exactly like how you are uploading a file in the web form. So let's select an image. I have here, many images, for example, this one. And let's upload it and send the post request. We will see that the post request is created exactly how we did it in the back end. And we have the image as a full URL. And the image file with the same extension here. But if you see here that we have an extension and then the naming, so we have a problem here. So we need somehow to exclude this extension and put this date dot now after, and then we put extinction at the end. Let's do that quickly. We will change their configuration here of the file naming in Walter to get the derived file name with the extension. So let's change this part with the backticks will be more nice in the code. So we can have the file name dash, this date doc now. And we need here to add somehow the extension so we can say dot and here it will be the extension from where I will get the extension. In the next lecture, we will see how to validate these files which are coming to the back-end. So we need the user to upload only specific type of images. We need him to upload only JPEG and PNG. So we cannot let him applaud, for example, a PDF file or for example, an XML file. So we need somehow the back-end to refuse a request when there is not an image. This what we will do in the next lecture. 56. Validating Uploaded File Types: Okay, Now we need to create our extension. But first we said we need to validate the uploaded files from the user. To do that, we need to create a list of files which are allowed that full backend to accept. So we can define a constant. We say file type map. And this file type map will contain a list of extensions that are allowed to be uploaded to my back-end. The first field will be image PNG. And then PNG. Why I did it in that way. So here we have the key as an image dot PNG and the value is a PNG. This we need that because of mime type. Mime type. If you Google it, it's immediate type and known as multipurpose internet mail extensions or mime type. And this is an a standard that indicates the nature and format of a document file. Every request is sent to the backend. And the file which is containing the data file or the file data, has also a mime type. A mime type has a format like this. So I get and PNG document dxdy. So in this way, I can define what is the type of the file which is coming to the backend. The most three important types we need in our back-end are this, PNG, JPEG, and JPEG. So here we will have those types. And in Walter, when I want to configure the file name, I can find here something called mime type. So mime type will include the information or the file information with the ink station of the mime type here. So to have the right extinction, we will do it in this way. Const extension equal to the file type lab and get the value of File lot mime type. So here it will go to this array and take the mime type, which comes one of these, and then assign the extension as a value. And here I will get the value or the extension to the my filename. Okay, we talked about validation of the file. So we need somehow to validate the file if it's allowed to be uploaded or not. In the call back of destination, you can define error. So when there is an error, the callback will throw it here. So first we can do a constant is valid file for example. And we will use the same concept here. So it will get the mime type and check it if it's found in the map which I assigned in my back-end. And in Node.JS, we can define an error. So I can say here, let upload error is equal to new error. And we can say the error is invalid image type. And then we can check if there is, is valid. Then make this upload error as a nun. And then uses upload error in the callback. So if the file is valid, there is no error and the callback will be executed. So you remember, we uploaded with Postman one file and it has this name. So now we will not have this JPEG here. We will have it at the end. Maybe it will stay here, but we will have at least extension at the end. Let's test that with a postman. Now, with our form, I have the same data, same image which I have uploaded. Send that request, I got uploaded image. And let's check the extension. We will see it has the extension at the end and the filename. And here is the image working fine. Let's try now to upload a file, but not the image. We can say, for example, a PDF. So I have here a test PDF. I will upload it. And we got the error. So we got error, that invalid image type, which we created here. So here in the front end, we saw that when we uploaded PDF, we got the issue. But what for example, J peg, send that request. We don't have any issue. We have the full path and we have also the extension. And every time I do an upload requests, I get a new data and new date and the file, it's the same, but it's uploaded again with a different name. Going to our database on Atlas, we can check the file or the product which is created. We will see the product has the image and it has a full URL. So this will be accessible from anywhere in our application. But we must have something like excluded from the authentication. Because if you remember, all API is authenticated. So we cannot do anything without getting authenticated. But we need that to be public, which we will see that in the next lectures. In the next lecture, we will see if the file is really exist. So if there is not a file or image for the product, we need to reject the request. 57. Image Upload With Product Post Request: What if the front end send me their request without a file? Then that required field of image would be refused to handle that. Let's first check if we have a file in our request. So I go here and create a constant, call it file and give this constant the value of request dot file. And exactly with the category, we can do it the same with the file. So I say if there is no file, then return an error to the user that there is no file. In this way, we will be sure that our request will not pass without a file. When we go to Postman and send the request without file, we will get that there is no image in there requests. In the next lecture, we will see how to use images to upload multiple images, which will be, for example, a gallery about the product. So in one request, the user will send multiple files, not only one file. And this will happen in the images field. 58. Image Upload With Product PUT Request: When we are to go week to update a product, also, we need to care about the image. So what if the user wants to upload a new image to his product, like he want to update the image itself. For that, we will do the same steps which we did for the post. So we need to add the upload options as well to the PUT request. So we added it here and then we are going to do some changes here. So first, if the user doesn't upload any image, then I want to keep the old image which is in the database. But if he upload some image, then I need to send and upload again the image to the files and then add the new URL to the database. Let's make this dog to echoed. So first of all, I want to find the product. So I add here a constant called a product and the product find by ID, request dot powerapps dot ID, and then I check if there is no product, then returned for me status 400, that it's invalid product, okay, Now everything is fine. Then we guarantee that the user is really entering a specific and arrived product. Another thing, then we will get the file itself. So I will say const file and this file, we've come with their request dot file as we did exactly with a post request. And then I will define a path which is called image path. And this image path is empty. I am going to use it to fill the path of the image. Either it will be the old one which is already in the database, or then you file path if the user uploaded a new image in there PUT request. So as a logic, I will say if file, then exactly how we do with the post request. I will define a filename and then of base path. And I will say that the filename or the image path will be exactly the same how we have it here. So we will have the base path and also the filename together as image bath. And else, if there is no image bath or if there File, then I would say that the image path is the same as the old image path which was defined previously when the product got created. So I would say product, that image, the old one because I got the productive year and I guarantee you that the product is really exist. So I'm not throwing error to the user. So for sure the product has a value here. And then I will say if that is five, then upload the file and give me the past to it. Else, give the image path will be the product image, which was previous. And then here I will say that the image will be the image path with the updated data. But here let's rename that one product. So we can say a product here for getting the product. And we can say here, updated product and the updated product, I find it and then check it and then send that request back with the updated data. So those are the required changes for the post request. In this case, you will not get any errors and you're going to have any problems when you are uploading the image again or when you don't upload the image. So they user here has option, he can upload image or not in the PUT request. 59. Product Gallery Multiple Images Upload: Okay, here we had a single file, so we uploaded only one file to the API. But here we need a multiple files for the product gallery. In the same way, we can change this post request to accept also a multiple files. But let's make it a little bit more complicated to have a real practical example. Normally when you are updating a product or adding a product, the second thing you do is uploading the image gallery. And this happens normally in the web shops. After you create a product, everything is fine. Then you go and edit the product again to ablate the image gallery. So let's create a specific ABI only for uploading the gallery of the product. This API will be update request, not a post request. So we need the post request. So I copy this post request. Let's go to the end and add it here. And further out, we can keep the product ID and also we can add their doubt where we will update only the gallery images. So here we can add gallery images. And then the ID of the product. As we saw before in the post request of the product, we added also the Upload option single image. We can also add it to the PUT request. So we can add here upload options, but not single. We will say array. So we will expect from the front end our array of files, let's call it emits. And if you notice here that the array method is giving me also a max count. So you can allow maximum file upload size. So for example, I will say maximum, I need 10 files or 20 files in one request. So let's put it as 10. Let's died more our code. So let's have this in a new line. So we can't say this one is here. And here, the async method. And here we have the port and we have here the content of our PUT request. So the update request of their product will be update exactly this data, but we will have only the images, not all the data. So we can do the same thing as we did here. It's copy this part to see if the user is passing the exact or the right ID. We don't need to check their category because we are not updated it. So let's have this one also. But as we said, we had all the data. We need to update only the image. So image field will be array of images. So as we saw here, array of image strings or path of the image. So we need here somehow to build array of strings. So we can hear, say, image buffers. And this image spotters would be a valuable as array of strings. So how will we will build this array first in that request, as we saw before, that we can have request dot file. Or if you see that we have a files also not only file. So we can say files will be constant files. And exactly like before, we can check if there are files. Then I will loop inside these files and build the images bothers array. So here I will move this up and say files dot map. And this will have file. And inside this method of file, we can say Image path is dot push, the fine dot filename. But we don't have to push the file name only. We need to push also the base URL and also with the extension. So if you remember, we created here the base URL, which we build for the post requests. So we can copy this part also and go to the put method and say here the base URL or the base path. And we push the base path with the file name. And here we can return back the product. So exactly like the PUT request, we can check if there is product, then that is ponds be the data of the product. Otherwise it will be error. So we copy this part and place it here. Let's test that with Postman on what we have to do with postman, that we place multiple files here. So let's create a field, call it, for example, image. And this image will be a file. And we select two or image for example. And we don't forget that to change the API. So here will be Gallery image and the request is put. And we need also the ID of the product. Exactly this one. Let's get our product, or product is product six, which we created before. And now we will add the ID here. And we will send that request. We have our error, I forgot here to add products. So we will have the right path. Now we try it. And then we will see the product got updated. And we have two images in the gallery and main image, It's still there. Let's check our uploads folder. We will see that we have two images, this one and this one. So in the front end, always we will update our gallery or update one product and add to it the gallery images. That's all about this section. In the next section, we will see how to fetch the image URL, so we can see it in the browser and in the front end, because now it's locked and we don't have access to it because it's protected with our API authentication. 60. Excluding Uploads Folder From Authentication: Now let's try to get this URL and put it in the browser, the URL of the image. So we put it in the browser and we will see that the user is not authorized. This because if you remember, in our JWT, we were defining the bath is which are allowed for public. So we need to add the upload folder path to be allowed so anyone can see these images. Otherwise, we will have an issue. So the e-shop will not show the images of the product. So let's copy this one. It will be exactly the same Git and options. We need also to replace this one with the path of the uploads folder. The regular expression for this is this one. I have slash, public slash uploads at everything comes after it. Let's save it. And let's go to our browser. Refresh. We will see error that we cannot get public upload image. Why this because it's a static folder. We need to define these public upload as a static folder in the middleware of our application. So to do that, we need to go to our app.js. So we go here and we say up use. And then we define the path which we need to make it static. So public slash uploads. And then in Express, there is method to say this is a static folder and a reserved keyword, which is dire name return for me the root path or the root path of the application. And plus the path which I wanted to make it as a static. So now this path, any file can be uploaded to it. It will not be as an API. It will be like a static path which is serving the files. So back to the browser and we do a refresh. We still get the error. This because I need to add slash behind the public. Act with our browser and refresh. We will see the image we had already in the front end without any authentication directly by the URL. Now our backend is ready. We have created the routes, four categories, orders, products and users, which we need exactly for our e-shop. We will move now to the front end part and you will see more than new things and how we reconnect to this back end and create our webshop interface. 61. Installing Heroku and Prepare Git: Okay, In this section we are going to deploy our backend or our Web API to Heroku. Heroku is one of the tools which is used to deploy the project or web APIs. And they can be public and we can use them in your projects. So you will not have your API based only on localhost 3000 as we saw, but we are going to put it on some URL and we can connect our front end applications to it. The first step we have to do, we have to go to a website called Heroku.com and then we are asked to be locked in. Of course, if you are a few don't have account here, you can as well sign up. The signing up is very simple. You just provide FirstName, lastname, email address. And what is your role? Country? And as well, you have to put some Brian money development language. We have to put NodeJS in our case and you have to verify that you are not a spam and then you can get an account. After you log in, you are going to see a dashboard like this. So this dashboard, we need to create an application which we are going to make it public for our API. So first of all, you need to have create a new app. And this creation of a new app, you can give any name for your application. In my case, I would give it a name like e-shop, back end for example. And maybe this name can not be available, so you need to specify some specific name. Maybe you can give like any random suffix. For example, you can put your last name. For example, I will put my last name or my company name. I will see, I would say like a blue bits. So in that case, I will have e-shop back and blue bits. And then you choose your region is better to use the closest region where it is closer for your target customers. So it's better for me in this case, I am living in Europe. So I will put Europe and then you have to click on create an app. So we have now created an obligation. There are some instruction we have to do first. First we need to download and install Heroku CLI. Let's go to this link and check it. So in this link you can see multiple options for installing Heroku. So for example, you have macOS way, you can use comment if you have Homebrew and also if you have Windows, you can install an installer. And also for open TO that way, which I like always to use is using NPM, NPM global installed. So you can do npm install dash global, Heroku. So let's go to Paris and do that. So I will go here and open my terminal. I will use Control J button as we saw previously. And then I will say npm installed minus g. So in this way, I will install Heroku Domain device public, so I can use Heroku commands in my machine. But the first I need to do is maybe we need to have a permissions. So the permissions, maybe it will not allow you to install public or globally. You need to prefix this comment with sudo. So as you see here, I am not r. I don't have permissions to do that, so I need to prefix this command with sudo. So we can say sudo nmap, but in Windows, I think you will not have any problem. And then it will ask me for my password. And then I will put the password and it will get installed successfully. Now, as you see, it got installed, we have now Heroku command. So you can, for example, put Heroku like this and you would get a command like options that you have, some options you can use for your Heroku comments. So go back to our browser. After installation, we go back to our application again and we have to make good edit. And as well, we have to connect our Heroku project or our back-end project to Heroku git. But first of all, the most important thing because before we do this step, you have of course, to create a gitignore file. So for example, in Heroku, I am not going to deploy this end file. This m file contain my connection string to database is my secret and also API URL. I am not going to push that to Heroku git repository. So in this way, we need to add a file which is called git ignore. So when I use a good comment of Heroku, then it will not push those files which I specify. So also, you don't have to push node modules. Monod modules come normally a very huge file, almost 200 megabytes, because we are installing libraries and their dependencies. You don't have to use Node modules as well. So creating get ignored file, It's very simple. You just have to create a file on the root of the project. So you have to say git ignore before doing any step which is mentioned there. So first, you need to ignore node modules folder. So we say slash node underscore modules. And as well we need to ignore the m-file and also another development files like prettier RC, as you see here, we have this file so we can ignore it as well. So in that case, we have, we are, we are ready for connecting our project to Heroku repository. So we go back to the instructions again and we have to say get in it. Because if we don't have initialized our project previously as we saw that we don't have a good, We didn't connect it to any good. So in that case, we need to say get any, okay, After you do get in it, you will see that there is a file created in this repository which is going or called like dot kid. And if you want to see it, you can go here to the backend folder and you will see that this folder and got created. So the next instruction we need to connect Heroku git remote. But first we need to use Heroku login. So let's first look into Heroku. So I will use Heroku login and then it will ask me, do you want to open the browser and you can login then. So we can't say yes, we can press any key and then it will open automatically the browser. So as you see here, I have it another page. It's saying look into Heroku CLI. I will say look in and then logged in because I am previously logged in on the same browser. So when you go back to the terminal, it will know that you have already connected and then you can use Heroku commands, as mentioned in the documentation. After that, we need to connect our Heroku or our project to Heroku git repository. So we need to use this command, all of these commands, you can use them as you see, say Heroku, git remote, and then add E sharp back and blue bits. So it's exactly the same name of the application. So let's do that. And then we based this comment here. And then, as we will see that, okay, the Git repository is set to this path. So now when we are going to deploy our project or upload our code to handle cool, then Heroku will get or read all their files and the code which we have uploaded from this path. In the next lecture, we are going to see how we can create as well a production database. We don't have to use the same database as we see because maybe this database we can differentiate between development and production. As we will see in the next lecture. 62. Optional Creating Production Database: Okay, in this lecture we are going to talk about creating a production database. So when you are making a development or when you do some application, normally you have a spatial database for you, for just development and testing things and making a progress for your application. But after deploying the project to alive, then you have to create a production database. In this course, this is optional for you to create live database, production database or not. So in this section or in this lecture, we are going to do that. If you remember, we have installed MongoDB Compass and this MongoDB Compass application, we can be able to create databases and also we can as well import and export data to it. So in our course we were using this database, which is called e-shop database. Now we are going to create a new one. We can call it E sharp as well, database. And it would be a production broad. So we can have that and we can create the first collection, which will be called, for example, categories. And then we make, create for the database, and the database gets created. So as you see here, but we have only one table. So if you remember, I attached for you at the beginning of the course, some files, you can use them like as default data. It's like the data which we are inserting do the database. It's like seeding. So we can use also the seeding that as well here. So I will do that quickly. So how to import data using a compass? You just have to go here, click on categories, for example, on the collection name. And then you can say import data. And then you browse to the file where I gave you. So I gave you, for example, categories or the items and other tables. So for that, you can use for these categories and you have to specify here that you have JSON. And now we are making importing. And this import gotten completed. And we will see our data is located here. So we will do the same for all the tables. I'm going to do that quickly in front of you. So I created here a new table. I call it user, or users. And these users, I am going to import that data as well. So we have to do the same for all other tables. So now my database production is full. So we are going to use this database, but we're only for their product application or that developed application on Heroku local development, we are still using the issue of database. So how we can make that dynamically, like when I deploy ISA to the application uses database. But when I am developing, I want to say to the application, okay, use this database. So it's pretty simple. We are going to configure that environment variables which are preferred for Heroku because we are going to use these variables and we use them inside the application. And on development, we can keep, for example, this connection string. But on production we are going to have another connection string. But here as you see that environment file is not deployed because we added to git ignore. So this will not be in the deployment on Heroku because Heroku will not know that we have environment file here. 63. Setting Development and Product Environment Variables: Okay, now how we can say to the application to use that database of production, not the database of development. First of all, if you remember, we added the m-file and in the end file we were using it for connecting to the database which we have created in MongoDB Atlas. So the connection string is stored in the m-file as you see here, and we talked about that previously. So now we are going to have a connection string different for production. So in that case, okay, we are using this connection string here in process connections to make. But as I told you that when we are going to deploy this application, this m-file, prettier, IC and Node module, they will not be uploaded to the server. So from where deployed application will know which connection string to use. Because in that case when I deploy, it will not know which connection string to use because it will be undefined here. And then we will have a connection error. So for that, let's change first everything which we have, like two or in our app.js, everything we need to change to be in production. For example, this name, I'm going to use a database but abroad, not this one. So we need to change that as well. We have also to use some, another variable, which we can call it dB name, for example. And we can give this DB name in the file. So we can, after that was one line, we can say DP name. And then for local, I will have to use this e-shop database. But in production we are going to use a different one. Okay, What else? So the application as well is using a specific port. So when you start the application in production, as you see here, when we go to the browser to our application and we use, we say, for example, open the app here on the top. Then we will have a new app. As you see here, we have the link, but it doesn't contain any port or like for example, 3000 or something. Because before we had like local host like this and 3000. So we don't have the board here. So how we can also make the board dynamic. So we need to do that as well because in the production it will use a different port. So as well here we have to define a variable. We can give it like a constant and we say port. And this port will come as well from environment variables. And it will be called port. If there is no port, then use 3000. So just in case if this part doesn't come or it comes with undefined. So then we use this board here. And in my file I can define that port. So we can say as well here, use the port, we can say port will be 3000. But remember, this is only for local development. We don't have for that for production. Production will replace it with another port. But the key word for that it will be bought like this. So Heroku will find or create a port on its own. Normally, it's port 80, which is the default port for the HTTP. Ok, now we have one problem. So how the production with no connection string variable. So how we can create that. So we go again to the browser where we have created our application. And then we will find on the top something called activity or settings. And in their settings you will find a reveal config vars. So those are the conflict vars which will be used in the production. So in that case, I need to say to my application here, use the connection string, but we're production one. So I will go again to the browser and then create a new key connection string will be what it will be. The connection is staying the same but with different database. So I will use the same one. And then I will say that not use e-shop database, but each of that obeys abroad. And as well, we need as well to create another thing which is called DP name. We are going to use that name sharp, that the base, so here as well, E-sharp, that obeys broad as well. So in that case, the application will know that there is a connection string and he would read it from here. So we don't have to worry about that. So it's better as well to add all the environment variables to the connection because otherwise our application will fail. What we have to use here, API URL, which will be the same thing which we had there. It will be api slash v1 and we are adding it secret. The same. It should be also the same capital letters or small letters because it's case sensitive. And we will have here the secret or you can use another secret. So when I deploy my application, then it will search for process. But our local error is not deployed because we have it in the good ignore. So it will not be on the server so that Heroku will not know from work to get it. He will go to the conflict vars and then read those values. So in this case, we have different database from production and a database for the local development. In the next lecture, we are going to see how we can use that and how we can deploy the application to the server. 64. Deploy the App and Test It: Now let's go back to the instruction of deploying the application. So here if we go to the application again and we click on Deploy, and we will see again our instruction. So we did already that connection and we have deployed or make the link between the application and the Git repository of Heroku. Now we are going to execute those comments. First of all, we need to add the code to the good, so we need to commit it. So if you don't know what is it, It's like you are giving information about, like what code you are committing to your repository. So when I do change, I say, okay, I changed this one, I remove that. So I would say in the commit message that removing the error handler. So in that way you keep track about your changes on the project. So here we can do that as well with Heroku. So we have to make git add dot and then git commit dash am, make it better or any message. So first of all, let's do the good. It means this that we are adding all the files of the project to the Git repository to prepare them for uploading to the server. And then after that, we have to do the git commit and then dash m. And then you can specify a message. So for example, deploy first, die. So we can as well add this commit message. After that, we need to push the code to the cetera. We are how we do that with this command, git, push, heroku, master. So I will go to the terminal and then paste this command here. And then it's going to upload all the information or all the code which I specified, except the files or the files and folders which I specified in git ignore. So in that case, we will have all our files of development are there. So as you see here, it's dart, do deploy the application, the files finished, it, start to building it. And now it's showing all the progress installing libraries. It does as well npm install for installation the packages which we used for our application. And then it will have Node modules, but on the server, not this one. So after that it will compress the application for faster usage. And you have also to remember to upload the images which are in the upload folder so we can see the images as well in the, in the server. So otherwise, if you don't have those images which I attached as for you as well, because they are in the database as well, the links to those message or images. You need to upload them as well to your server. So that deployment finished, verifying deploy, done. Okay, Let's go back to the browser and go to the application and refresh here. Nice. We have message, the user is not authorized. That's great because if you remember, we have authorized our API. So if you remember in the routes or in the helpers, we said JWT that we are going to exclude some routes from authentication, for example, in getting a products or getting a categories. So let's try to get a products in the browser. So I will say here exactly if you remember how we were doing with local host and 3000 and then I put API v1, and then I put products for example. So this is like a get request when you try it, Okay, We got all the data from our database. You can't try that as well as Postman, if you remember, we have we were working with the postman a lot and we were trying our API in Postman. So here I will open a new tab for a new GET request, and then I will put this link. So the link of my application API, v1 product. So it will be exactly how I'm doing it like from local host. So you see that all of these information are stored and we are using the production database. We are not using the database which we had for local. So to prove that, Let's make a change in the database using compass. So I will go to my application, I will go on to the production database. I will click on this and I will open the products. And I will go to the one where it start with, I remember as mol, something like that. So here the small, you see here the small and this is. So let's change that. We can say change this sentence. We go to the, so we click on the small here and we can say, for example, abroad. So we can make this bigger and say production. So we can add this word production here. So after we update, and then we go to Postman, and then we click on Send. Okay, we have here production. So this is proof that I am using the broad database, but on my local host, Let's try to run application on local. So we can say npm start as we were running the application locally, okay, The localhost 3000, everything is fine. Now we go to GET request, but on the local host. So we have here, for example, localhost 3000 API products. And then if we call it, we will see that we are calling the database, which is in the local host. And if we check this database, I will go here. And I will check this issue of database. Go to products. I will have a lot of dummy products which we were using during the development. So in that case, we are differentiating every time I deployed to my application thumb thing, can you then it will use a database of their production. For example, I'm going to change something here. I'm going to add a console log. What example console log. Like using, we are using. For example, you can put additional and then you can use the DB name here. So when I save, okay, on my local, I will say we are using e-shop database, but we need to deploy that. So here, our local, local host, we have e-shop database, as we know for development. But if we deploy this, we would get, we are using the issue of database brought tea or product. So in this way, how we can push changes, again, we need to put git add and then we add a message. So for example, comments, we can say change, and then we press enter, and then we use again push common. So git, push heroku master, it will be deployed again. So as you see here, it's deploying again. The same process as we saw in the first step. Now it's finished deployment. How we can see that, for example, this message which we are using, like the database, you, I mean how we can see the console log or the errors which we see in the development. To see that you can go easy Two more here, and you can check here a view logs. So when you click on it, you will see all the logs like you are developing locally. So we say here, we are using e-shop database abroad. So that very great thing and exactly how we were having the application on local and as well, it will make like monitoring for our API. So when I call this API, then I go to the logs. I will see that, okay, we have information Get API v1 products and some other information about the request and return and how long it took. But if we go to the database, we need, for example, to check one image. So I will go here and I will go to the database and I have products. We will have a problem with the images. So if you remember, we have uploaded some images with our E-sharp. So when I go here, I will see that in the product, they still have this localhost 3000. Unfortunately, this is not possible to replace it. So you need to replace all of those strings which are related to the local host. You need to replace them annually with the link which is provided for your application. So in that case, I'm going to here to my application and then copy this part which is from here to.com. So I will copy all of this. And then I will go to that campus again. And that it plays from HTTP to localhost. Also the port is not necessary and then I will add update or update this part here. So we click on Update and then it will get updated. So when I go now to the application and paste the URL of the image, then I will be able to see the image successfully. Otherwise, all the images, unfortunately, they are still on localhost 3000. So far that based on your name of your application, you will need to replace all of this for the database. Of course, after we use this database, for example, in some front end or when we are you going to use Postman for example, when I am going to post a product using this API URL, it will upload the image based on that URL, so it will be stored in the database like that. But because we were using this database in development, you need to do that manually. Because as well, we were using when we are posting a product. If you remember, if we go to post the product and in the post product we were doing like the image using the host. I get the host current host and then put the rest here to store the image path. So the host will be taken from the host which you are using and calling the API from. So in that case, you don't have to worry about the links which we want to upload for the uploaded files. So now we have a fully functional API on the server. The application got deployed. Of course, if you want to remove this Heroku.com and create your own domain, it's not for free. You have to pay for that. And of course, you can be able to have it under your own domain. So in the front end application or any front-end application, when you are going to deploy the front end application, not their Web API. You can say that for my application in the front end in production, use this API URL for all like the application. And then when your application gets deployed, it will connect to this API and grab the data from there.