NestJS - Building an API for Real Project From Scratch | Oleksandr Kocherhin | Skillshare

Playback Speed


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

NestJS - Building an API for Real Project From Scratch

teacher avatar Oleksandr Kocherhin

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

39 Lessons (8h)
    • 1. Introduction

      1:05
    • 2. What technologies we will use?

      4:58
    • 3. What we will implement?

      1:45
    • 4. Generating a project

      10:14
    • 5. Creating tag module and controller

      13:18
    • 6. Creating tag service

      7:08
    • 7. Configuring absolute path

      12:08
    • 8. Installing Postgres

      11:32
    • 9. Configuring database

      6:56
    • 10. Creating tag entity

      9:43
    • 11. Working with tags repository

      16:28
    • 12. Creating migrations

      14:02
    • 13. Preparing register request

      9:44
    • 14. What is DTO?

      6:48
    • 15. Creating user entity

      15:55
    • 16. Generating jwt token

      16:26
    • 17. Validation pipes

      8:57
    • 18. Login request

      18:35
    • 19. Auth middleware

      25:09
    • 20. User decorator

      8:34
    • 21. Auth guard

      7:05
    • 22. Updating current user

      11:09
    • 23. Creating article module

      13:05
    • 24. Creating article method

      18:55
    • 25. Polishing create article

      8:41
    • 26. Get article by slug

      6:26
    • 27. Deleting the article

      11:05
    • 28. Updating an article

      11:12
    • 29. Creating feed

      25:28
    • 30. Liking articles

      17:38
    • 31. Disliking articles

      20:28
    • 32. Seeding the database

      14:21
    • 33. Getting a profile

      17:57
    • 34. Following users

      15:52
    • 35. Unfollowing users

      8:04
    • 36. Current user feed

      14:48
    • 37. Backend validation

      19:20
    • 38. Frontend testing

      17:13
    • 39. Homework

      1:56
  • --
  • 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.

22

Students

--

Projects

About This Class

In this course we will build a Medium clone API using NestJS, Typescript, Typeorm and PostgreSQL. This course is fully focused on fast and deep dive into creation of API for real application with NestJS. We will start from scratch and step by step you will get close to finished real application. You will deeply understand how to structure your application, build reusable and understandable modules and services and split code into smaller chunks of code. We will write code together in efficient way to make it pure and avoid data complexity. 

For each lesson you'll get source code of the lesson, so it's easy to see the progress and get a working app on any lesson you want. 

What you will learn in this course:

  • Structure and configure project

  • Write high quality code with NestJS on real project

  • Create reusable modules, controllers and services

  • Implementing authentication

  • Deeply understand NestJS design patterns

No prior knowledge except of Javascript is needed (because I will teach you everything from basics) but if you have experience with any of this  (Angular/NodeJS/Express/Typescript/Typeorm/PostgreSQL) it will be easier for you to go through this course.

If you are feeling like you learned NodeJS but you still still missing knowledge of how to build your own real application this course is what you need. This course is fully focused on creating the application without getting deep into basic knowledge of NodeJS!

Meet Your Teacher

I am a full-stack developer with a passion for learning and teaching what I know. I have been programming for around 10 years and teaching for almost 6 years.

I believe in learning through doing and this philosophy is present in every course that I teach. I love exploring new web & mobile technologies and my courses focus on giving you the edge in our fast-moving industry.

See full profile

Class Ratings

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

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

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. Introduction: Welcome to my course next, GS built-in real application from scratch. It's so great to have you here. In this course, we will build a completely real application from start to the end. And we will implement all features of typical project such as authentication, pagination, managing articles like an in disliking them, following users and much, much more. We will use nastiest together with typo room and Postgres, which is the most popular solution to build scalable applications. Of course, all our code will be dry, reducible and digital understand. By the end of this course, you will for sure have enough knowledge to build your own projects by using mass Chess. Who am I? My name is Alexander, and I'm a web developer with more than ten years of experience, as well as a professional instructor with various courses regarding different web technologies. I did my best to put all my knowledge inside this course and they want to share it with you. So welcome on board, and let's get started. 2. What technologies we will use?: In this video, I want to talk about technologies that we will use in this course. And of course, this course is about Nest chairs. This is why it is our main technology. And actually as you know, the most popular framework for Node JS IIS Express, we can build, for example, any pie or a back-end for our web applications by using Express. The main problem with Express or similar frameworks, they are really low level, which means we need to implement a lot of staff on our own, even like basic things that I'm waiting to have in all frameworks. What we have from nest, yes, actually nastiest reminds me a little bit, Ruby on Rails from Ruby world. And from my point of view, Ruby on Rails is one of the best examples of a well made Framework. Why is that? Because we have a lot of stuff out of the box from there and we don't need to reinvent the wheel. For me, NES js inside node world is something like Ruby on Rails, which means we have a lot of stuff out of the box. For example, here in documentation we have controllers, providers, modules, middlewares, and a lot of stuff that help us to build real applications. So we don't need to implement first the framework and done within our application. The next important point is that nest years is written with TypeScript directly, so we don't have JavaScript there. Why this is important. Actually, JavaScript is really easy language to start with, but it's not that save and stable because we don't have datatypes there. And TypeScript eliminates this problem like 90%. Maybe this is why I highly recommend you to use in real project TypeScript. Why? Because in your project you can describe with TypeScript all your entities datatypes, and you are getting a lot of warnings during compile state and not in John time, which means JavaScript is nice to build small and medium applications. But for medium and big applications, I highly recommend you to look in TypeScript. But of course, the risk pros and cons here. This means that to master ness chess, you must learn TypeScript. And if you don't know TypeScript for this course, no virus, I will cover some basics of TypeScript also here. But you should be aware that if you know TypeScript, then it will be easier for you to make this course to the end. The next thing that I'm expecting from framework is of course, connecting to databases and work with them efficiently. And as you can see here, we have a section database and NES GIS has a really nice wrappers and rams to work with databases. Which means we can use here different databases. We have different providers for them. And this is quite simple. We don't need to build something on our own. We just need to understand how it all works together. But here is also a small problem. We will use type or m here. And the REM means that this is object relational mapper. So it is some wrapper for our database. And type works with different databases. But this is one more layer that we need to understand and master in order to work with Nest? Yes, because obviously we need to work with databases and Dinesh just we're doing it with Iran, which is completely correct. But it is additional knowledge that you must know. If you had already some experience with ramps, it will be easier for you to complete this course. Also for our application, we'll, we'll use Postgres database. And if you don't know, this is really popular open-source relational database. So actually you must also know a database and how they are working, at least on some level. We will start from scratch and I will show you everything that you need, but you should not expect that you will learn until the end of the course, the whole Postgres from start to the end. Because we're focusing on building the application by using different technologies that you need for our real application. Also, here are two more things that if you know, will make you easier to complete this course. First of all, is Angular. If you ever worked with Angular and you know how dependency injection is working there, then it will be easier for you. If not, no worries, we will learn it with nice chairs. But actually nastiest took a lot of stuff from Angular. This is why it is easier for you to master nice chairs if you already know Angular. And last but not least, of course, if you've worked with NodeJS or you build, for example, express in Node.JS, then it will be also easy for you to build project with nudges. But you should not be worry. We will go through all technologists from the start. Even if you don't know anything, this is completely fine. We will make it together. 3. What we will implement?: In this video, I want to show you what we will implement in this course. And actually here I opened don't get hub golf things to real-world. What is the real-world? This is the real projects that people are built-in in different languages or frameworks in front-end and back-end side. And the main point here is that it's not some HelloWorld or to do MVC project. This is a real project with authentication registration, working with feeds, working with APIs like and dislike impulse following users and much, much more. This is the serious business here. The main idea is that in this course we will implement the full API for this project. So everything that you see here. And then we can take any front-end that we want and just connected to our API and do work out of the box. Here, as you can see, we have a lot of implementations of front-end and of course backends. Here I opened the really important URL fast. Here we have real-world API specification. This is exactly what we must implement. For example, here you can see all examples of all requests that we must do in this course. For example, here, this is how the response will look. One-world authenticate users. Here is profiles, single article, multiple articles, and so on. Also, there are error codes for back-end validation and of course endpoints. For example, to make a login, we must implement the endpoints slushy Pi slept users slash login, where this will be the request and response you already saw on the top. So actually this is our main source of knowledge, but this is all requests that we will implement in this course. 4. Generating a project: In this video, we will install mixtures tools and then generate nice JS application. The first step here is to install NodeJS. If you don't have known just on your machine, you can always jump to known chess.org and download here aversion. And actually there is an important point. So first of all, we want to check what version do we need? I am on the official website and just.com, and here on the left I chose first steps. And as you can see here, the important lines your notes version must be higher than ten except of 13. And actually here, as you can see, we have 14th version or 15th. Both versions will work, but I highly recommend you to always use an OLTP, especially because normally it's more stable. If you already have known, you can always check in the console, node minus version must return to some version. This version is higher than ten, then you are good to go. The next step is to install CLI. What did this, as you can see here in the setup of the project when style globally. Next GS CLI command line tool that help us to work with nurse just for example, generate nurse JS project. Then later we can use nest knew and the name of the project. This CLI tool will generate our project files. So actually you can just copy, paste this command and paste it here in the console. And they won't execute it because I already did it previously and my nest is already installed. So after installation you want to check if nest is installed. This is y here. Nest minus version should return you some version. If you are getting here, some version doesn't really matter what version you're good to go. Last but not least is of course, to generate our new project. As you can see for this word, right? And nest knew and the name of the project. I have Nest New. And let's name our project medium clone, underscore goodness, Chess. Why medium clone? Because as I said in the previous video, this is the clone of the medium website. Now as you can see, we're getting several questions. First of all, what package manager we want to use. It doesn't really matter, but I prefer normally to use yarn and not NPM. Now as you can see, nest CLI installed all packages and generated fast project. This is why at the end I'm getting successfully created project and we can start it by writing CD in this folder that was created, then yarn around stat. And if you chose not yarn button PM, then here you will probably see command npm start. This is why I am jumping directly inside medium columnist Jess. And here I want to start the server and they will do it in the separate tab here. I want to jump to medium clone nest chairs and dried yarn start. It actually doesn't matter if you are right in the yarn around style or yarn start, both will work the same. Now we're getting here, message nest application was successful, is started. And actually the main problem is that there is no port here. So you need to check the documentation or the source code. But they can say that normally this application by default has been started on 3 thousand port. Here I have localhost 3 thousand. And now when I am reloading the page, you can see here Hello world. So actually this is our web server and our generated nest GIS project. Now let's have a look on our file structure that was generated files. Here, I opened our editor and as you can see, I'm unfolded medium clone as chess. This is exactly what was generated. What is important for us. First of all, of course, our source folder in Node modules we have all dependencies. And in dist, all our TypeScript is transpired. Because actually when we're open source folder, you can see that this is all tiers file, so we're right in TypeScript here. And everything is started here in main.js. As you can see, this is what we have. We have here an asynchronous function bootstrap. And here we're creating new nest factory where we're bison inside a module. And actually this line creates a new application. Then here we're saying that our application must listen on 3 thousand port. Here we're calling this function. This is why our application is listening 3 thousand port. This is exactly what is specified here. Our next step is In module. So let's jump to the module. This is this file. This is how our module is looking like. And actually what is module in next chess, if you already familiar with clock, you can just apply all knowledge about modules from Angular two messages. If you don't know anything about N color, then the way home USGS is structured and applications is through dependency injections. What does it mean? Let's say that we have several modules inside our application. For example, module of authentication, module of articles, and maybe at some other module, maybe popular tags. And then we can say explicitly what is inside this module. So we're defining. Dependencies of every module. For example, we can create a service or controller inside each module, and then they are really belonging to that module. And then we can say that our first module is dependent on the second module. And then our first module can use something from the second module. And if we don't provide it as a dependency, then this is really isolated stuff. So we will talk deeper about modules later. For now, you just need to understand that we need modules to oscillate logic and split it. And in this case, this is app module, which means this is the main module in our application. And from wheat, everything is started fast. Here is the most interesting part is this controller. As you can see where registered here, the dependencies of our app module. This is this app controller and instead providers App Service. Let's check what we have inside. As you can see, this is app controller. This is how it looks like. We will talk also deeper about controllers in the next video. For now, what is interesting for us is this get hello method. As you can see here, we have a get and actually this is saying that this has GET request. And here is our get hello method. And now inside where column this App Service and get hello method. Actually we can assume we don't know yet that this gets yellow is what is rendering this Hello World on the screen. Now let's check what we have inside service. As you can see here, we have this observers get hello. This is this App Service. Let's open now as serous. And as you can see, this is just a class where we have get hello string, which returns as HelloWorld. We can already a little bit understand how application of Nash chairs is working. First of all, we have our main tiers. Then inside main tiers were registering our app module. And inside that module we're registered, for example, app controller and depth service. Now we have our controller where we define some methods that will be called when we're jumping in our case to slash, which actually means this is the method for our default slash URL. And inside here we simply return our get hello method, which returns as a string. This is why here we have a string. And of course I understand that you see here a lot of new staff like constructors, read-only services, controllers, and much more. We will talk about a deeply in the next videos. But for now at least you saw what application was generated faster. Then next super important thing to mention is this dist folder. And actually dist folder is all the same files that we saw already like App Controller, app module App Service, Mencius. But it is in JavaScript, which means TypeScript transpires on the fly. All these files here, and we're using them inside our server. Now here are two more things that you need to install in order to start developing an application. First of all is support of TypeScript inside your editor. As you can see here when I'm champion, for example, in that module, I have here highlighting and also stuff like outer important autocomplete because I have test server inside my editor. If you're using some modern editor, for example, VS Code, which is really popular, you have that TypeScript support out of the box. If you're using some other editor, you can simply Google for your editor some plug-in for TypeScript support because it lists you want outer complete and syntax highlighting. The last tool that you need is Postman. What is Postman here? I open that tab, postman.com slash downloads. And actually this is how it looks like. This is a special tool that we will use a lot in order to make our request. For example, here I can hit unclass. And now here I can write my request, for example, http. And we'll know that we have localhost 3 thousand. This is get here on the left. Now I can click Send, and as you can see here, I'm getting as a result, Hello World here on the bottom. This is exactly the tool to do all requests to specify here, headers, body, and so on. So by default, this tool is completely free. You don't need to pay anything. You simply need to jump to download Postman and don't load here an application. But of course there are the tears that actually you don't need for that course. This is y here on the top you have price and tab, but we will use here on the free version, and this is completely sufficient for our needs. 5. Creating tag module and controller: In this video, we will create our first module and controller. And they want to start with something simple. And actually here as you can see, I opened again our API specification. Here is one endpoint list of tags. As you can see, this is how it looks like. So actually this is the response as an object was filled Tags and inside we have energy of our possible tags for our application. And as you can see inside, this is simply strings. And here is how it looks like in front and here I opened angular real-world IR. So this is one of the front-ends for our API. And here on the right you can see popular textblock, and these are all texts that we have in this application. So actually what we need to build is an entity tag. And then inside we will store all our popular texts. But in this video we will make it easier without database just by creating a new module for our tag and you control it. So let's open our editor and now jump inside source directory. As you can see here in source, we have everything flat. So we have here App Controller, app module, App Service and Maine. But the point is that we will create a lot of different APIs, like an API for the user, authentication profiles, tags, lists, and so on. Which actually means if we will just throw all data here, it will be a mess. This is why the good approach is to isolate everything inside modules. So the idea is that we have here at module, this is our main module. And then for example, for tags, we can create new module. Then later we have maybe articles. Then we create a new module and isolate everything which is related to articles inside that specific module. So let's create here a new folder and call it Tag. So actually the name convention, the toll-like, is to name all our modules as singular. This is why it will be tagged or profile or user, or maybe article. Now inside tag, Let's create our tag dot module.js. As you can see, we're always create a module file for our new module. Here to the important part. The first one is the name of our module. Then we have this post fixed module. It is important in STS, we're naming all our entities with postfix. In this case, we rarely see what it is about. Now on the right, let's open our app module so we can look how it works. As you can see here, our main idea is to export a class. This is where here I will write expert class and here will be tagged module. And again it's not tag, it's tech module. So this postfix is important. Secondly, we're using here a decorator module to specify some additional configuration for our module. Here what we need to do is write at module. Here. As you can see, I have an auto-complete from Nest JS common because you really want this outer complete. You don't want to type every input on your own. In this case, I just typed module and then I got auto imports. We will have lots of inputs. This is why we should not write them by hand. Secondly, inside module, as you can see, where must provide an object with some properties. So now we successfully created our first empty module. It doesn't do anything. And at this moment it's not binded inside our application. What we must do to bind it is jump back in our app module and import it here, because for now I will take module is not registered inside our application. We need to jump here in app module and inside inputs array, right, our new tag module. And as you can see, I also get an autocomplete here. Here are the important part. As you can see, we have lots of stuff here. We have imports, controllers and providers, and actually all dependencies of our module we're writing inside inputs. This is why here we have our app module, which is the main module. And here we define our dependencies of app module, which actually means if we want to buy a new modules to our application, we'll also need always to register them here inside the inputs. Now let's check that we don't have any errors. So let's jump back inside our yarn start, as you can see here is my web server, and as you can see, no errors here, which means we're binded everything successfully. We can also jump in browser and reload this local host 3 thousand. And as you can see, our API request is still there, which actually means that everything is working. Now we must create a controller. So the question is what is controlling? It is a place where we define in all our APIs. Which actually means if here we open our API structure and as you can see here is the request and get tags slash api slash texts. So we want to create this request. To do this, we need a controller because this is the only place inside niches where we're registering our URLs. So our API. In this case, I want to jump back in our project and create here in your file. And I will name it tag controller.js. And again, tag is the name of the module controller is to our postfix and Ts is an extension. Now what we want here, we want to create a class and the class will be tag controller. The next step is to add here decorator control it. And actually here in STS, we're writing a lot of decorators because it's really sugary stuff to add some additional properties or additional logic. In this case, I am outer important controller from last year's common. And actually if we don't try this line, then nothing will work because then it's not nest chairs controller. In this case, we're registered that this is exactly the controller. We created this file and our first-class, but we also need to bind it to our module because for now without binding ETL module, this file is not visible for our app. For this, we need to jump in our tech module. And here inside our module, we can create new property which is called controllers. And here is the array of our controllers that we can provide here. And denote case it will be tagged controller. Once again, what we are doing here, this thing is called dependency injection. So we're injecting dependencies and split all our application in modules. And in this case we define the tag module. And inside we have some isolated stuff. In our case, the isolated Staph is this tech controller. It's not visible from the outside, but actually it will be binded correctly when we're binding to our app module, this tech module. It's also really important that we can now remove completely tech module for example. And then it is just gone from our application because everything is related to tech module is defined inside. Now it's time to create our first route. So let's jump back in our controller. And here we must provide some functions. And actually when we're creating here f function, then we will create here a new route. And actually let's open on the right here, our app controller tears. As you saw here, it looks a little bit similar like we wrote. So we have here controller and class. And here is get function. When we want for some EPI to return some data, we must create here a function. As you can see here, we have function get hello wherever we're rendering this Hello World string. And different site tech controller will want to return our list of tags like you can see here. Then we must create here additional function. And we can name this function how we want. We can write here f2, but of course we want something human-readable. And actually the idea is the tower slash API slash tax returns for us, the array of all possible tags. This is why here I will name it, find o, which means actually we will find all our texts here and return them. Now inside we can simply return whatever we want. For example, here let's say that we have several texts, dragons and maybe coffee. This on our array of tags. Of course it is marked, but this is good for now. But the next point is that we didn't register any API. As you can see here, we simply created a method inside our class. So what is important is to add here on the top of our function decorator. And we can name it get, for example, as you can see, get decorator and don't forget round brackets is a decorator which creates a GET request, which actually means here slash api slash tax is a GET. This is why here we are right in and get the crater. Which actually means creating a function without the decorator doesn't do anything. This is why for every function that must work for our API, we must provide here some decorated like get, post, delete, whatever we need to. Now the question is, how do we provide a route? As you saw here inside our app controller, would don't provide here any route. This is why we can see on our slash. So this is a default homepage, this Hello World, which actually means if we don't provide anything, then this get will be our default homepage. And we don't need this because we really want to implement slash tax. Actually here everywhere you can see slushy pie. But as our project is on the isolated API or you don't see any point to write everywhere slash API. We will always write the URL without the Pi. This is why we've wanted to create slash tags. And for this, we need to know a controller to write tags like this. What does it mean? Actually, this means that we are registering this whole controller. So all methods inside this controller with prefix tags, which actually means that now we can jump here in our local host 3 thousand and tried slash tags. Now I'm hitting Enter, and as you can see, we're getting status code for 04 cannot get tags. So actually this is happening because we're using wrong command. Actually, as you saw in our web server, we used yarn start. Now let us look on our package JSON. As you can see, there are lots of commands that are already prepared for us from Nest chest here or start command that we're using. This is just nested what it does. It simply transpires our project and the toll. And actually all our changes that we made are simply not there because this command is not doing any changes until we started. Actually start is not the command that we want to use for development. And as you can see here, we also have started dev, started debug and start broad. And as you can understand, broad is for production. Debug is for additional verb balls messages, and dev is for development. So let's now start with start depth. Then we have this minus, minus voyage, and this is exactly refreshing on our changes. This is why here we want to write the yarn stored and here will be deaf. As you can see now, we have command netstat minus minus. Here we can see starting compilation in watch mode. And now actually this information here is important because as you can see here, we have started nest application and here we have tech module dependencies initialized. This actually means that it was successful binded our tag module because in other case, it won't be registered here. As you can see here, we can see all modules that we bind it. And as you can see here, we also have app controller. This is the default ones. Here we have tagged controller and this is slash tags, which actually means with this line that was successfully created our first route slash tags. Also here on the bottom you can see this maps line. So actually met. Then slash tags get this part is exactly our function. This function, because here all functions that were registered will be written. As you can see here. For example, for app controller, we have mapped here, we don't have any URL, so it is home, and here is scared. So this is home URL and this is slashed tags get. Now let's check if it's working. So let's jump in browser and reload the page. And as you can see here, we have slash tags and we returned our array of data. So actually we successfully created our first module, tech module and our first controller. We even created here our first method, find all where we returned the ray of plain data. 6. Creating tag service: In this video, I want to talk about services. So actually we're already know what our controllers for where registered URLs there. And actually we can write the whole logic, for example, connecting to database and then fetch and some data from database directly in controlling. But we can do better because the point is if we have, for example, ten methods that we want to register inside our hotel controller. This means quite a lot of code. And actually we don't have normal loop online are there. But we can have like ten or 20 lines inside each method, which actually means we will create the super huge file. So the main idea is that for these values and services, what this service, this is simply some additional class with some methods. And normally, for example, if we are talking about tags, we want to create tech service where we will store all business logic related to tag. And then inside controller we simply use the service. So we don't have any business logic inside our controllers. Of course in Nest just normally we're working a lot with database, which actually means all database requests were doing also inside our service. In this case, we have tech controller. Let's now create our tech service. Here I will create tag, the service dot ts. And inside I will create our first-class. Previously here we're right, an expert class, and here will be our tech service. And again, we're postfix in is with word service. We also need to register it as an injectable service for our next JS application. Because in our case now this is simply a class. This is not a service which nest just nodes. This is why on the top we want to write our decorator injectable. And as you can see here also round brackets are important as always. Now, we want to move all our business logic from our controller to service. This is why here I will jump in tech controller. And as you can see, this is our business logic. Sure, this is just a single liner, but normally it will be much more. What we want to do is we want to create inset service, some method that will return this data. This is y here inside tech service. Or we can create new function find all here inside. We simply can return these lines, so return dragons and caution. Nothing special here, but this business logic is inside our tech service. The next step is that we must register our tech service inside our module. Because in other case, we can't use it inside our controller. This is why I will jump in our tech module and here I will create one more property which is called providers. And normally we're registered all our service inside this property. This is why here I am right in tech service. There is the tech services also isolated inside our module. Now we can use this service inside our controller. Let's jump to our controller. And here on the top to register our service, we need a constructor. So if we want to use some service inside our controller, we must always define it inside constructor. Here, inside constructor we can say private and actually even read-only. And here will be tech service. So this is our local property. And then I have here take service. Here. We need to close our constructor. So the idea is that here inside constructor, we're defining all our services that we want to use inside this controller and denial case, we wrote here private read-only. So first of all, it's not available outside. Secondly, it is read-only. And now we can use this text service as local property. This is our local property and here will be the instance of our tech service. So now here, instead of this return, we can write return and here will be this text service, as you can see now we have tech service inside this. Here when I am writing dot, you can see autocomplete of TypeScript. This is our find all methods that we wrote. And now we can remove this one liner. Now we simply have the function called from our tech service. Why it is good? First of all, we isolated full business logic inside Service, which means we can separately test controllers and services. Our controllers doesn't know anything regarding some business logic or database work because it is isolated Insight Service. And also we can share our services between different modules if we want to. Let's check if it's working. I will jump inside Overwatch. And as you can see, actually now we have a batch mode, so we don't need to restart our web server. Now let's jump in browser and reload this page. As you can see, it looks exactly the same. So now let's check some strings to see if it's working. I will jump in our text service and dry it here. Additionally, whether Let's reload the page. And as you can see here, we're getting weathered, which actually means we are getting our data now from the service and not from the controller. Whereas isolated our business logic inside tech service. But here is one more important point. We're right in TypeScript, this is why we really need to cover everything with typed. And if we don't do it, then TypeScript country will help us. What we want to do. We want always to define correct types. As you can see here inside our attack surface, would didn't defy any return types for our find all method. And actually if I hover on this method, here is column and array of strings. So this method returns array of strings and TypeScript understands it on its own. But we really want to provide explicitly what all our methods are returning. In this case here I want to say that we're getting back array of strings. In this case, even if we return something which is not correct here, then TypeScript will scream. For example, if I'm writing here return 0, then we're getting directly TypeScript error. The type number is not assignable to type string in the previous example, but won't get any error because TypeScript just understands that we want to return here number, but actually we don't want to. We really need to cover every method that we're using with datatypes and everywhere rebel also. This is why here we are returned an array of strings and we want to do the same inside our controller. So actually when we're checking this function, we don't know at whole what it returns true. We can check it here and understand or even here. But it really nice to define here that we want to return here array of string. Then we're always on the safe side. And here we directly see that we have a fine old method and it must return the array of strings. 7. Configuring absolute path: In this video, I want to talk about absolute path. So actually what I mean by that, as you can see here, for example, in source main or every file, we have here a relative path. So we have here dot slash and not some absolute path, like for example, at NUS chess, the same word doing everywhere. For example, in our app module, we have relative path. And this is how it works by default in last year's, just because they didn't do anything to solve this problem. Now of course the question is, is relative path bed. And I think that yes, it is bad. The main problem is when I'm, for example, copy paste in this line and put it in other place, then this input is not valid anymore because this is relative path which is related to the specific file. And yes, it works, but first of all, you can copy paste it from here. Secondly, you can't replace it everywhere at once because it everyplace you have a different path. And the third part is that it's not clear where our file is lying. For example, here we can't really understand in what folded it can be insurer with dot slash. We can understand, but if we have something like this, then we don't have any clue and we don't understand our file structure. This is why in all projects I always recommend to configure absolute path was absolute path. We want to write something like app slash. And here will be observers if it is inside our app folder. But unfortunately, less GAS didn't do anything to solve this problem. And there is not a good way of doing it. Which means actually we must configure everything on our own. Because everything is just Node JavaScript and we can do it. But I just wanted to say that this is not that comfortable as it should be in normal framework. What problem do we have? Actually all people just think, okay, we can simply tune here our Ts conflict Jason here, for example, set here, path. And it is fine because we have TypeScript. And yes, it will work, for example, in development mode because we're using the ts node, which means what transpired in our TypeScript on the fly. But it won't work, for example, on production because actually as you saw here, we have a dist folder. Here is all our JavaScript. And this JavaScript is already transpired and it doesn't know anything regarding, for example, App Path, which we can write inside ts config, which actually means our solution should be flexible. And it should work in both cases with TypeScript and with JavaScript. So let's start this out. First of all, in our ts config JSON, I want to add new conflict. Here. We can provide new property path with S, and this will be the object. Now with the key, we specify our Alice, for example, here we can try it at ab slash and a star, which actually means that we want everywhere to have this app prefix for our source folder. Now here we can write it as an array dot source, and here will be also a star. And this actually means that inside TypeScript for all our files inside source folder, we have an ls at App. Our next step is to use additional package module. Allow us if you don't know what this package is doing here, I opened it on npm and actually it creates aliases for directories and it registers custom module path. Actually they did is that we want to use this module only in JavaScript case and not in TypeScript case. For this, we need, first of all, to install this package. This is where I will jump to the console. Now here I can write yarn, add module ILS. And actually you can use here also npm to install a package. It doesn't really matter. The next thing is to create configuration for module. As you can see here, we can scroll a little bit and inside package JSON, we can create new property module aliases and then write all our analysis here. This is exactly what we need. So Poupon to open our package JSON, and now somewhere on the bottom we can create new property underscore module ILS is, this is the object and here we want to use an app. This is exactly what we wrote in ts config and here we have slash disk. So the idea is that we want to remap all our inputs with an app inside dot disc. So we have relative path for our build for production. But it's not all actually when we check here the documentation, you can see that we must add this require on the top of our application. So actually we want to add it inside source main here on the top. But the problem is here that we don't need this slide at all in our development mode. When we're running test node, this line must not be there. This is why here I want to write if. And here we can write process and. Dot for example, is Ts node. And then inside I will move this code. So the idea is that we need to somehow specify in our command when we're calling our application, this property is Ts node. And when we have this property, this means that we are in development mode with Ts node and we won't require module ILS register, but in production we won't have STS node and then this require will be there. Now, the next step is to provide custom property is Ts node for our starting of application. This is why I want to jump in our package JSON. And actually here on the top we have lots of commands like start broad, debug, dev, and start. Actually we need only to one for development, one for production. This is why I will remove from here start dev and start debug. And we will only work with start and start proud, start broad with don't need to touch because as you can see here, we have just playing node and here this main, so we're calling main, which is already transpired there. Now what do we do? We start command. The problem with that, we can't really sit here plots environment because it is a ness start command. What we want here, we want really to write exactly the same code which happens inside nested. This is why I will remove it here and write Eastern node equals true. This part will set in process environment this property here we have now TS known and this is exactly what we have inside nested. And here we must specify minus r ds config path slash register, and here will be source main ts. So your first question is for sure what is TS node? Actually, this is the possibility to transpire our TypeScript in JavaScript on the fly, and we're using it only for development. Here we have minus r ts config path registered. And actually when we copy this part and look for it here, we already have this package which is installed automatically when our project was generated. Here is this NPM package. So actually the idea is that it loads modules from location specified in path section of this conflict JSON. So the idea is that we must write this code if we want inside our Ts conflict json load this path. This is exactly why we wrote here minus r and here is ts config path register, and then here is our starting file. And actually this code will work so we can check here, I will restart our server and just run Yarn start, so we don't need dev anymore. As you can see here, we have STS no true, which actually means everything that will work. We can reload our page and we can see the result. But here is a huge problem. But don't have watch here anymore because we wrote our own command and it's not watchable. Sum now we somehow need to implement watch part. For this, we can use a package which is called non demon. This is the most popular package for deve development when we masked restart our web server when we're changing the file. So actually this is why I will jump in the console and dried yarn add, and here will be no demon. And after installation we must create a conflict file where inside we will specify our command. This is y here inside route, we must create a node demon dot JSON. Here, no demon dot JSON. And inside we're passing our configuration. First of all, here we have watched property and we're specifying that we want to rely on our new demon. So our web server with when we change something inside source. Secondly, boop want here our extension. And in extension we want to provide TS because we're working with TypeScript. And last but not least is our exact command. This is the command that will be executed. And this is exactly the command that we wrote in package JSON start. So I will copy paste it from here completely and paste it here. Actually this is our main command. And now inside start we can simply call no demon because this will start our no demon locally with this configuration. Let's try this out. I will restart now and just write Yan stat. As you can see now here we have logs from no demand. First of all, we can restart at any time by entering arrays. Also, we have watched in source and everything inside and we're watching for extension Ts. And this is our command. And the point is that here now we can use absolute path. First of all, let's check if it's working. So here I am jumping in browser, reload in and everything is fine. But the second is if we have watched or not, this is why I am jumping inside of a text service and here I will remove our tag weather. Now as you can see in browser, we don't have a web server. And then after one or two seconds when demon restarted our web server, we have our changes. This is why here you see on loop two tanks. Now inside our survey you can see that we have no diamond restarting due to the changes. And this is now our command which is called again and start in the web server again. Now let's check that absolute path is working. So we want to jump, for example, in our app module. And here everywhere we don't want to use relative path, but we can now write at AP. And here will be the name of the path. So actually fast at AP is our source folder. And now we can understand where all these files are situated. As you can see when I'm writing something not correctly, TypeScript screams directly that module is not there, which actually means the TypeScript understands correctly our ad path that was specified in TS conflict. And I understand that the amount of changes that were made in order to bring our absolute path to the life was enormous. But actually, if you want to use them, you don't have other choice. There are other possibilities to do this, but they're also not that good. And this is like the most stable and works for development and production. 8. Installing Postgres: In this video, I want to install postgres on your machine, so we have a database to work with. And of course, the first question is why I chose port Chris and not for example, MongoDB, because I know that one could it be easy, really popular database. And a lot of people who are developing with known chess liking and using MongoDB. First of all, you need to know that there are two types of databases, actually more, but to our most popular, first of all, we have relational databases which actually adjust tables and relations between these tables. And secondly is document-oriented database, which actually means that MongoDB is document-oriented database. So actually it is for storing documents there, which doesn't have any schema and it doesn't have any relations out of the box. Actually for normal applications where you have a lot of relations like for example, users, users can have articles, articles can have comments, then you have likes, dislikes, which means this is relations between maybe users or posts and so on. These are all staff of relational database. And true, we can build all this stuff with MongoDB, but it doesn't make that much sense for me because we're getting a lot of stuff which is really useful from relational database out of the box. And also we are getting schema, schema validation, all these references and all that we need. And actually almost always in production, we have a lot of entities and we want to build relations between these entities. Ensure I understand that a lot of companies are using MongoDB in production and they can build relations or whatever the one there. But it takes more time and effort and it's not really better than traditional relational databases. This is why in this course we will use Postgres, which is one of the two most popular databases. The first one is MySQL, but I highly prefer Postgres because it has more features and it is more stable and user-friendly. This is why in this video we must install postgres on your machine. This is why I opened the homepage of Postgres database and we're interested in Download tab. And actually if we will click on windows here, you can see download the installer link certified by EDB, which actually means this is not the official installer of podcasts itself, but this is the third party installer, but this is so good that they wrote it on official page. Here I open this link on the right, and as you can see, this is the website of EDB. Actually, this is enterprise DB, which is just a company that is highly using and make and scalable Postgres. Actually, the idea is that the heaven installer, which works on all operational systems. This means that it looks and works everywhere the same. This is why they have the recommendation, how we can start with using Postgres. This is the website and here we have section for installing Postgres on Windows, on Linux and on mechanism. And actually it looks exactly the same everywhere. Here. I just want to shorten the goal through all screens. But normally it is just download in your execution file. And then next, next, next set and password finish. Let's check this out. Here I opened windows and as you can see here, the links for macOS and Linux. So the idea is that first you are downloading the installer. So you're jumping here in this link. Here you are choosing your operational system and truer, you want the last version, which is 13. So you just don't load here your execution file for Windows for example. Then here you are starting your setting up. As you can see, this is just a window you're clicking Next, you are choosing the directory. You don't need to change it. Now here you have something that you can select actually from these four checkboxes where you have Postgres, server, pg, admin, stack builder and command line tools. You must choose on the tool. First of all, it's Postgres itself. So this is the first one and command line tools. Why is that? Because we will use Postgres inside common line, which is why we must install them. And after this we simply click Next and then we have a password. So actually what did this, this is the password for superuser, which is Postgres user. Here you can say whatever password you want. Actually 123 is enough. Nobody will care because it is Postgres on your local machine, but you will need this password later. Now here we have our port for Postgres. We don't need to change that. Here located. We also don't need to change. Now we're clicking Next and here one more next. And here everything is installed. Actually if you are seen something like this. So completing the wizard, which means you successfully installed postgres on your machine. And actually, you just need to come to this step because after this they have the example with pg admin and we won't use it. We will use only console version. So the idea is that after installing this Postgres database, it is shining on your machine. And now we can connect to this database from different places. For example, from our application or for example from the console. There are hundreds of other tools and DUIs where you also can connect to database and make something with data inside. But we want to use console. So here are a few commands. First of all, we're right in Sudo minus u, Postgres PSQL. What did this? So here we're saying that we want to call sudo command as the user Postgres. And actually Postgres is the default user of Postgres database. Here we're calling PSQL. What did this? Psql is a common line tool for Postgres. Actually want inset console to open PSQL. Here I'm hitting Enter, and here I must provide a password for my user of my machine. So it's not the password of Postgres. Here. I'm typing now my password and as you can see, I'm getting one more message, password for user Postgres. My password here is 123, so it doesn't matter. You can set it also 2123. And as you can see, I'm coming to PSQL, as you can see here, hash, which means I am already inside PSQL. This means that I can do some commands to connect to my database, for example, or create users and portraits and so on. If you are seen such window, this means that you installed everything successfully on your machine. So here now we can use some commands to check, for example, what databases we have or what users we have inside Postgres. First of all, we have a command list or slash L. And this command will show us all our databases. As you can see here, I have list of databases. Here we have a lot of fields. So actually this looks like a normal table. And we have here name, owner, and all other fields except of access privileges is not that interesting faster. As you can see here, we have named Postgres and this is our first database. We also have here two more databases, template 0, template one. We will create our own database because we need a database for our project. And the second part is that we need a user to manage the specific database because we don't want to use a superuser Postgres for our own database. And here we can also see the list of the users for this, we're right and slash display users. So DU, as you can see here, we have list of roles. Role name is Postgres. This is our first user, and here is all roles. Obviously this is superuser. It can do everything. Now we must create first Asia, then a database, and then give a privileges for this user to manage this database. So first of all, let's create a database. Here I will write create database, and here will be the name. For example, you may doom clone. Here will need to put semicolon. This is extremely important because this will end our command. I'm hitting Enter and as you can see, I'm getting a message create database. And actually now I can write here slash list or slash L to see all databases. And as you can see now we have our new database medium clone. The next part is to create a user for this word, right? And create user, and let's name user like our database. It doesn't make realist sense to name it differently. This is why I will create user medium clone. And now I want to say with encrypted password, I want to create a password for our user. This is why here I am setting password and let's say here also 123. And don't forget semicolon. I'm hitting Enter and as you can see, I have a syntax error. So I wrote word password not correctly. It should be W2 S. Now, when I'm hitting Enter, you can see the message create row, which means now we can see all users display users. And as you can see now we have not only Postgres, but also a user medium clone, which means we successfully created user reset password to 123 and we created our first database. Now as you can see here was our medium clone database and access privileges are none here, which means nobody can access this database. What we must do now is allow our medium clone user to manage our medium clone database. For this, we need to write here, grant all privileges. On the database. Here will be the name of our database. It will be medium clone to medium clone. And these two medium clone, medium clone is a user and then hit an Enter. And as you can see, I have a syntax error. Here is privileges, sir. Now we're getting message grant, which means everything is working. First of all, what you can see, postgres is really nice made and everything is superhuman readable because all our commands is really like an English. Grant or privileges is really a command and we can easily understand it and read. Now let's check our databases again. Here I will write slash L to get a list. And now we see here our name medium clone, this is our database. And here we have access privileges. And as you can see here is the word medium clone. This means that we have access to this database, which actually means that we successfully installed postgres, created our first database, created our user, and allow this user to manage our database. So now we're fully ready to start typing the database inside our next JS application. 9. Configuring database: In this video, we will configure our Postgres database inside our application. And unfortunately, there are lots of ways how we can do it. Let's check this out. The first step here is to configure type or RAM. What is it? Here I open the official website, type RM AR. And as you can see here, type where RAM isn't RAM, which can be run in different places, for example, in node. And this is what is interesting for us. And we can use it with TypeScript and JavaScript. And if you don't know what is our RAM, this is object relational mapping, which actually means that this is some kind of wrapper for our database. So we can work easier with database. And also, for example, type programs supports different databases. And actually when we're writing code using type or RAM, this wrapper, then we can use any database underneath that we will specify. This is really amazing. And as you can see here with the official website off nice chairs and nest GAS works with different types of ramps. Here you can see squigglies type RM Prisma connects and so on. But actually toupper RAM is not that often updated, but it's really stable and well-suited for production application. This is why we will use typer room as our RAM for Postgres database. Now we want to create conflict for our type ramp. And actually they did is that we must pass all credentials for our Postgres database to topo RAM. Let's do this now. For this, I will jump inside our code and here I am in source directory. Here in source I want to create new file config dot ts. And as you can see, this is simply a TypeScript file. And here we want to define a config of type connection options. And this is really important because in this case, we will get a lot of errors because we must specify here all correct connection options for the database. And after this we want to export it. So here will be export default, and here will be our conflict. So the idea is that inside this config, we will provide all our credentials for database and configuration for type RM. This is y here inside I am setting the type here is Postgres, because Postgres is our database. Now we have here host and the host is local host. The next one here is our port. And this is the default port of Postgres. If you didn't change it in configuration, then it is 5432. Now after port, we must set here a username. And this is the user that we created in previous video for our Postgres database. So our user will be medium clone. The next one is our password. And as you remember, I said the password to 123. And the last one is database. And other database has the same name as our user. This is why here we also have medium clone. Here actually we provided everything that we need, but I'm getting a strange error. Actually, this error says that I didn't provide some fields correctly. But the problem is here that I had an outer input and it's not correct. We don't import connection options from NADH TLS where inputting it from type or a ram. And actually this is the problem type where ram is not installed by default with nurse chairs because we can take different to a ramp system. This is why we need to jump to the console and right yarn add type or RAM. And this will install a type of package files. Now when I'm jumping back, as you can see, I don't have a typo error anymore and this connection options is now correct. So if I'm passing here, for example, foo, we're getting a narrower that full property is not needed to be here, but it is not enough typer RAM is just a library for using this RAM, but we also need to install bindings between our nest JS application and type where RAM. For this, we must try it here on Add, and here will be at Nest chair slash tapeworm. This is a package that was created by Nest chest team and it supports binding to our typo RAM. Now inside our app module, we must import type where a module. Here I am writing type or RAM module. Unfortunately, I don't have here autocomplete for some reason. And inside we have four root or a conflict. What it is about, first of all, here is type where a module, this is exactly the module that is inside this binding nest GAS type RM. Here. I'm importing it and as you can see, I'm getting this outer input from Nest GS type RM. And actually here we're not writing just a module, but also dot for root. What is four root? If we want to configure our module or not our module, but a module from the library, we must write dot foe root and we can provide some configuration. In this case for type where a molecule we must provide insight, correct conflict to connect to database. This is exactly this config or ARM config that we created five minutes ago. Here I want now to import this herem config, and as you can see here is relative path. We want to change it to app slash I am conflict. This is our config, which is just an object whose properties. And here we started our type or a module, which means our application should work and be correctly bind it to our database. Now let's jump to the console and check if it's working. As you can see here, we're getting an arrows from typo error module and enabled to connect to database. And here we have a narrow Postgres package has not been found and installed, try to install it with NPM installed PG. So this is what we need to do. We must install Postgres as a package for our project. This is why I am writing here yarn add post crisp, and this will install Postgres package for our project. Now let's check if it's working. Here. We can write arrest to start or just manually stop and start our web server. As you can see, we're not getting any errors here because our database is binded correctly. And as you can see here in logs, we can see a tapeworm module dependencies initialized, which means it is really binded. 10. Creating tag entity: In this video, I want to talk about type RM entities. What does it mean? Actually for this, we must check the documentation of topo REM. And actually, as you can see here, there's something about connection. We're already made this because we're connected typo or RAM to our project. Now we need the part about entities. So actually what is entity? Entity is overrepresentation of database table. If you've worked with other ORMs, normally you hear the word model. This is our object or entity with which we will communicate. The idea is that we define it like here. So here we're defining our entity user, and here are some fields that are user has. And now we can do different things with this user. For example, we can create a new user or save it to database, find it in database and so on. So actually it simplifies working with database and actually type or RAM is not part of nas chess, but actually third-party library. But it works really nice in combination with nash chess because it also uses TypeScript decorators and similar approaches to create an entity inside dipole RAM, we must create a class and have here a decorator entity. Now inside we have NAD always, this is why the decorator primary generated column, and then we can create other columns. For example, here we created column firstName, lastName and is active. And as you can see when we define such entity, and then we do some magic type or RAM will create in our database the following table. This is the user table because our class is named user and here are our properties. So as you can see in the first column, it's ID, FirstName, LastName is active. Here we have types of data. For example, ID is an int. Here we have var char because it is a text, and here is Boolean. And we can see here that our ID will be auto-incrementing. As you can see, we define not that much, but actually type eardrum did quite a lot of stuff for us. And we don't see communication with database and all of this low-level stuff completely. Now let's try and create our first entity. And for us it will be tagged. So actually, as you saw here, for us in the application, the x is just some texts and NAD for this, let's jump inside our project. And here we have attack folder. Here we can create a new file tag, dot n, dot ts and dissolve with entity is actually the postfix of the file type. So we have controller module service, and now we have an entity. Here. We need to export our class and wear a name tag entity. Again, don't forget the postfix. And now on the top we must use here entity, and this is a decorator and don't forget round brackets. Now inside we want to write, first of all, decorator for ID. As you saw here in the documentation, it is primary generated column. So I am writing here primary regenerated cone. Here, ID is a number just for you to know all a decent said Postgres, our numbers and not strings. This is important in the future faster. And secondly, I want to create a column where we will store this text. So actually we have a record Dragons for example, and the record CAUTI. We can name this column name here. What we can write that we have a column and after we're writing, namestring will know that our name is string type. This is why we're storing it here. So actually this code will create a new table, and this table is named tag. And we will have the two columns. First of all ID and secondly name. And this is enough for us in our project because popular tags is not that huge. But actually after writing code in a lot of languages and working with a lot of libraries, normally I like to keep the table names in my database in plural, so I like to have it not tag, but tax, for example, not user, but users. I really got used to it. This is why I want the same here. And it is completely possible here inside the entity, we can provide as an object some arguments. And here I want to specify a name and the name will be taxed. As you can see, this is plural, which means this gigantic will create a table not with singular tag but tags. Now we need to add two more lines inside our RAM configuration. For this, I will jump back in source or ARM config. And here after the last property, we must add property entities. So entities are exactly the type of RAM entities. So the idea is that we can provide them for toupper RAM and then type RM can generate them for us. And actually it's not the best way. We will do it on the farthest start. And then later we will change it properly. Here I must provide the full path to all our entities. I want to use here dude name. And if you don't know, directory name is current directory. And they wanted to concatenated with a string. Here we have slash two stars, then slash star dot entity. And here I have brackets and inside dot ds, coma dot js. What is it about? Actually, as you saw, we have here source, so we are here and then say tag, we created file Tag entity Ts. So actually this part will look for all files, doesn't matter how deep they are with extension dot entity. And actually here I made a mistake. It should be like this dot entity. And as you can see here, we have brackets with dot ts or dot js. This is super, super important because in development mode we have dot ts and then production mode in our dist folder, we have done chess. And actually if I'm opening now dist folder here we have tag folder and inside tech folder later we will have our tag entity dot js. This is exactly the problem because here if performed try don't chess, then toupper RAM can't find this entity and work with it. The last configuration that we want to provide is synchronize. And here is true what this option is doing every time when we will start our web application, diapers and Wilson synchronize all our entities and create tables in database if needed to. So now we can rely on our project completely. Actually, it will be reloaded automatically, but I want to be on the safe side. So at this moment, already type RM must create for us a table. Here I opened again this PSQL tool and we will use YouTube a lot. As you can see here, I have hash, which means I'm inside Postgres. And now we want to connect to specific database to see what we have inside this database. For this we have slash connect or just C, and then the name of database. In our case, this is medium clone. And as you can see now we're getting a message. You are now connected to database medium clone as user post-class. So I am rude because we just want to check what information we have inside. And now we can write slash DT. So display table to see all our tables. So as you can see here, we have a single table with name tags and type table own medium clone, which actually means that we successfully created our new table automatically from our entity. And of course, we want to see how our table is looking like. This is why we're saying here slash d, So describe and here the name of our table, it is tags. And as you can see now this is the information about this table. This is the name tags, and now we have two columns, ID and name. Here the type is integer and here is character version. So we're char, normally this is stream faster and as you can see, they're both not nullable. But the point is that you should not know that much about databases actually sure additional knowledge is always good, but type RM isolates a lot of stuff for us. And it is easier for us to work with her RAM and define entities then to work directly with database. Once again, what is happening? First of all, our application is configured in app module with typo RAN module with this ORM config. The most important part here is this entities and synchronized, which means when typo RAM is starting the application, then it checks all the sentences and we have our entity tag and TTS. And toupper Ramses this entity that we created and tries to create this table if this table is not there, because in our type program conflict, we provided this synchronous true. This is why our table is created on the fly. So now we successfully connected to our database, created a table, and we can work with our tags and save them through the ORM. 11. Working with tags repository: In this video, we will fully finished our first API method, getting texts. We successfully configured our database and now we need to start working with type or RAM. Now I want to show you once again our request. As you can see here in specification, we have on the Get Text, this is slash api slash tags, which actually means we have just a request to get a list of tags. For don't have a request to create tags, update tags, delete tags, or get a single tag. Which actually means the idea of this project is that somebody, for example, admin, the very beginning, create on its own in database directly these tags, which actually means for us that we need to create in our database several records so we can fetch them later. Then I'm assuming that you're not that familiar with databases or relational little basis. This is why I want to teach him not just some things, but how to search when you need something. This is why now for example, we have our open PSQL here and we want to create several texts. And we can do it here directly inside the console and just create new records inside our table, but we don't know how to do it. This is why I opened here, Google and the road create records, postgres, PS scale. And this scale is important because if you're using different UIs, it will be different. There is a lot of nice tutorials and documentation regarding peer scale and Postgres. This is why normally you just open the first link that you have and check it here. As you can see here, you have some information that in Postgres, we have a word insert, insert, create a new row in a table. Here with the example how we're using it, we're right and insert into here is table name. Then we have round brackets. Here is the list of the columns that we want to feel and hear space values and here also in round brackets the values. Actually this construction we will use a lot and this is the basics of PSQL, Postgres, or actually other relational databases. This is why I wanted to jump here in the console. Here I opened pH scale, and as you can see where I insert in turn, actually it should not be uppercase, but nevertheless, I think it is easier to understand what we're writing here is insert into the table name. Our table name is text. Now we must specify columns. But actually this ID will be generated automatically, which means here we must have only name. Don't forget round brackets. You can put here space. This doesn't matter. Now we have one more space and here is our values. And as you can see in values inside would need to provide the same values in the same order like for columns, which means this is column one, this is value one. In our case we have online name. Let us provide here, for example, dragons. Now, don't forget a semicolon. Now I'm hitting Enter. As you can see, we have an error column. Dragons doesn't exist. And they actually were getting an error here because we used double quotes and single quotes. And the idea is that inside Postgres PSQL, we're using double-quotes only for names of the tables, for example, but not for strings. This is why we always must right here everything in single quotes. So here I wrote dragons in single quote. Now I'm hitting Enter. And as you can see, insert 01, which means we successfully inserted inside of a tags this new tab. Now let's create one more tax so we can test with several texts. Here I am writing CAUTI hitting Enter, and we'll also go at the same message. Now the question is how we can see what is inside our database. For this, we also must write a specific command. The command is select star from, and here will be the name of our table tags, and here is semi-colon. And when I'm hitting Enter, as you can see, this, the result we have here ID and name. Here we have 12 Dragons coffee, which means this is exactly our data inside database in the moment. And this means that we successfully created two new records in our table. Just to remind you, things like selects, for example, or inserts are basics of working with databases. This is why you need to master them at some point, but at least for this course, you need to understand basics. Our next step is to get this data inside our next JS application. So let's jump back inside our application here we have our tag entity. This is super important for us. We're not working directly with table or directly with database. So actually our idea is that we're working with database. Only inside our service. This is why we have tech service. And here we must use Tag entity to gather with Repository from topo RAM. The question is, what is the repository? This is special pattern. How we're getting things inside our service. Here, how we're doing it. First of all, we need here on the top to import repository from. And here we have typo RAM. This is directly from taper RAM, not from last year's. Now we want to modify this fined or method because for now we're returning here array of strings. It doesn't make any sense for us. We want here to get an array of our entities. In our case, this will be Tag entity. Here we can write that we want bag tag entity and here is the array. But this is not enough for us. Why? Because actually the operation to get some data from database is a synchronous, which means we must wait until we're getting this data, which means find all control the return directly Tag entity, but it returns a promise. This is why we're right in here word premise, and then in tags inside verite integ, entity. And if you don't know what these texts are, this is genetics from TypeScript world. Just to simplify this and not go too deep inside TypeScript, our idea that for promise, we can specify some datatype that will be returned. And by default here, if we're writing like this, promise doesn't know what data we're getting back. We want to specify it, and this is how we're writing it inside tags, we can write here, for example, array of strings, or in our case, this is array of our Tag entity. The next step is to inject here a repository. Actually a lot of stuff in last years is working with injectors. If we want to use some additional thing, we need to inject it inside our service. And normally we're doing it inside constructor like we did previously inside our deck controller, as you saw here, we have constructor here, tech service, tech service, and we will use something similar here. So I have here a constructor and inside I am writing a decorator inject repository. And this is a special thing as you can see from Nest GAS typo RAM. This is the way how we can bring type of RAM support in their chest. This is y here we're injecting the repository. Here we have round brackets where inside we're passing our Tag entity, which means we're saying here that we need a repository which will work with our Tag entity. Now after this, we'll need to create our property. Here. We're right in exactly the same like we did in the controller. So here we have private than read-only, and here will be any name in our case, tag repository, because this will be a repository to work with. Stack. Here is tag repository and we are saying that this is a repository of type tag entity. So this was quite a lot of code. But actually you just need to remember this construction because we will use this construction everywhere. If we want to work with type program, we must bring it inside our service. And we're normally doing it with injecting our repository. So actually what is repository? This is a special rapper which helps us to work with database. Here we're saying inject repository Tag entity because we want our tech repository to work with tech table. Here we're saying that this will be our local property. The type is Repository Tag entity, exactly like here we said promised again to do to specify what datatype have inside promise. Here we're specifying that inside repository we have a tag entity datatype. So this was the most difficult part. Now we're coming to the easy part. First of all, as I said, our function returns a promise, which means here we can simply write as sink and then we can use a weight and side. This is nice because next year support await and the sinks everywhere out of the box inside controllers, inside services. And you will see it in a second. Here we said that our function is asynchronous. This is why inside we can now call a weight code. This is why here we want to return a weight because we want to wait to this request. This is where here we're saying this tag repository, this is what we injected. And here I have dot, and as you can see, we have lots of methods. This is actually ORM, this is our wrapper to work with database. As you can see here we have find safe count, get ID, whatever you want, you name it. Now we want just to use Find. And actually as you can see here, I have a highlight that find, finds entities that match given options. In our case, we don't need to provide hear any options. And then this line will return false from the database all records of entity tank. Now let's check what we have inside web server. So let's jump here. As you can see, everything is red because we're getting an error and enabled to compile TypeScript. Type promised again, entity is missing the following properties from type string, which is actually valid because this error is inside tech control ts. Let's jump there and check what we have. As you can see here, we said that this fine ball must return an array of strings. This is not valid anymore because we're using this method, find all from tech service and it returns back a promise of Tag entity. And this is actually completely fine for our controller. We just need to update our method. First of all, here we need to write a sink because it is also a synchronous, because our tech service dot phi and all is also a synchronous. Here we want to return a rate and here will be our this deck service fine doll. Now everything is fine and we just need to tune this logic because actual string array is not valid anymore. And here we must write exactly the same stuff like we did there. Back. We're getting promise of Tag entity. In this case, we should not get any errors. Here. Of course we need to put brackets because we're getting back an array and not a single entity. So just for you to know if you are not that familiar with TypeScript, here we're passing something, for example, let's train. And then this brackets after means that this is an array. In our case we are saying, okay, we're returning here a promise with datatype. Again, array inside. This is exactly what we're getting back. Now let's check it once again. As you can see now we have a different error. So we are having the era that tech entity repository is not exploited inside our module. This is why we must export it and define inside the module. Every single time when we want insert module to use typo RAM, we must provide it inside our module. This is why I will jump back in our tech module. And here we're lacking an input. Here I want to import type or a dram module. Here we're writing for future, not for route. Just to remind you inside a module we wrote for root because we're born to, to configure it there. Now inside every module we're running for future because we need to configure specifically this module and each module is kind of feature. This is why here we are setting for feature and inside we must provide an array of our entities. In our case it will be only take entity. So this line is mandatory if we want to use taper RAM inside our tech module. Let's jump back. As you can see now everything is green and we don't have any errors. Now let's hope and browser. And here I have localhost 3 thousand slash tanks. I'm reloading the page and now this is our answer. As you can see, it looks different because here we are getting the data directly from database. And as you can see here, the important part that we are getting array of objects where we have ID's and names, so not on the names. So actually we successfully got data from database, but they're not in the correct format. Actually, if you open here the example of our spec, we get a pi tags should return a list of tax. And when we're clicking on list of tags here, how it looks like. Actually this is our response. Here we should have property tax, and this is just a simple array, which actually means we must write our code in different ways to get exactly this structure. This is easier to do. First of all, I want to jump back in our tech controller. And now here I want to prepare our data in the correct format. You might ask Why here and not inside tech service. So the idea is that inside Service we're writing reusable things. And normally I'm trying always to write inside services, things like getting data from database, not how they should look for our API. And the Pi view I'm normally write in inside controller or if it is to match, then of course we're moving it inside Service, but you will see it later. Now we want to store this response in additional property. So here will be constant texts for example. And now we want to generate this format. So we can say here return and here we have property tax. And we just want to loop through our tags, for example, this map, because this is plain JavaScript in our case. Here we're getting each tank and we're born to return tag and dot name. And as you can see, we're getting really nice outer complete because TypeScript understands that this is an entity. And here we're getting on the properties of this entity. This is why here I can say tag name and we won't get any error. But of course, our final method doesn't like what we wrote here because this is not valid. Here. We're saying that we're getting premise of array of, again it is. But actually we are getting here completely other thing, here, I will remove this Tag entity array and write this object with tags. And here we have just an array of strings. And as you can see now it looks fine, but we don't need to again to the input anymore. Let's check if it's working. Now, I'm reloading the page. And as you can see, the response is exactly like we want. So here we have property tags and inside just the rate of strings, we successfully fully rendered our data from database through our service and controller on our API. 12. Creating migrations: In previous video, we successfully finished our first module tags because we just had a single request there, get old texts. This is why in this video, I want to make last improvements for working with database. And actually I want to talk about migrations. If we check here inside source or a ram config, we have here an option synchronized, True. And actually this option is really bad one, and it exists only inside type program. And the DEA is the type or RAM does some magic and create for us all tables through our entities. And it sounds all good. But actually it's not. Why? Because normally if we're talking about other frameworks, we don't have such thin like synchronized, True, we have the thin which is called migrations. What is migration they did is that you have your database which is completely empty, so you just created it. And then you want to add something, for example, to create a table. In our case, we have our first entity tags. This is why we want to create our first table. And actually we're making it through migration, which means we are creating, you may creation and inside we create a table. Why it is important, this means that actually we saved somewhere how we're changing our database. This means that every single time when we need to update something in database, we are migrating our schema, which means we have the old state and we're getting a new state through our migrations. Which actually means it works somehow similar to the gate where you have like commits in your repository and then you can switch to older versions. And actually here was my creations. You always know in what state you're in and what state will come. Also synchronous through is unsafe for production because there we don't want to remove any data, which means we must fully control how we create tables. This is why I highly recommend you to always use migrations and never use synchronous option. And if you don't want to bother with migrations and you want a short and fast result, you can use synchronous, true, this is completely fine if you just create a project to make it fast. If you're making real project, I highly recommend you to look on migrations. If this was theory. Now let's do this. So now we have just a single entity tags. And this you saw inside PSQL, we have our first table. What we want to do now is delete this table. Why is that? Because normally group want to start our application or at least set up our project. Then we want to create our database completely from CLI. Then we want to make great all our migrations that we have. And then we have a schema of the table. This is why the first command that we need is db drops or dropping the database. And actually for testing or for development, it is truly important and useful command. Let's jump inside the package Jason. And here we'll want to use type or amyloid. And tau typo RAN module is situated inside node modules, but we don't want in every single command to use Node modules path. This is why here we can create an additional command which is called taper RAM. We won't use it directly only inside other commands. So here we can say ts node because we want to use it through TypeScript. And here we must add this attribute minus error ts config path slash register because we want that all files have our paths that we specified. Now here inside we must provide a full path for Selye of type RM. This is y. Here is node modules slash taper around slash CFLAGS. Now we must specify our config that were already created previously. This is where here we're right and minus, minus config, and here will be source slash or a ram conflict. Yes, we're just saving it. As you can see here, we must use ts known because we provide in here Ts conflict. Now, when we create new commands, we can always use this taper RAM and it will be with TypeScript and risk correct conflict. Here I want to create first command dB drop to drop the database. So as this type rm command is inside scripts in package JSON, to use it inside every command, we must run it through NPM or through yarn. This is why here I will write yarn and tapeworm, and this is the usage of this command. And now here we can specify something, for example, schema drop. And they actually inside type or RAM, they already have this command schema drop, and it will delete all tables inside our database. And this is exactly what we want. So now I can jump inside shell and just write yarn dB and drop. And this will remove all our tables inside database. This you can see we are getting here nice slog, so we have transaction and here is drop view and so on. You don't need to fully understand it. Of course, if you can, then it is easier for you to debug your Postgres later. But actually for now we can see here the database schema was successful at dropped. This is why if am jumping now inside PSQL and I'm writing just slash DT, I don't find any relations because our database is completely empty and we don't have any tables. The next command is to create a migration. So actually we have our first entity tags and we want to create a migration for it. This is why here we can create new command db create. And just to remind you here, I prefix all commands with database with dB. This is why it is easier to use them. Here we also want yarn type of RAM, and here we want to use Migration. Generate minus minus minus n. The idea is that this is the attribute inside we can provide a name. Now let's jump in source CRM config, and first of all change the synchronized from true to false. The next one is to provide here a migration path. And we want to store all our migrations in a single place inside source. This is why here we will have slash migrations. And here we will have star, star, star dot, and here will be our extension dot ds, n dot js. And if you are asking why we have this strange extension, because this line must work in TypeScript and in compiled JavaScript. Either it is inside source with this directory name or it is inside this. But it is not enough because we also need to provide a configuration for CLI. So here we have an option CLI and inside migration directory, here we must have source migrations. So this will be our future directory. As you can see, these lines both i important for our migrations and of course synchronized false. Now let's check if it's working. First of all, I want here to use again yarn dB drop to be sure that our database is completely cleaned. And now we're right in here, yarn TB create, create tags. And in this case with our new configuration, our migration is being created inside source migrations. Here is our unique ID and create test.html, which means we successfully created our first migration. Let's have a look what we have inside. Here. Inside Migrations folder, we have this new file. As you can see here, we have a class grade tags implements migration interface for us is important. First of all, their name, this is just a unique hash. Here we have two functions up and down. The idea is that here we can always roll back our migration. Which means here we define what our migration is doing. This is our app. And if we want to roll back it, we can use down. Here is the code. So here we're using query, run our query and we are using create table tanks. And you can understand from this code what we're doing. Actually this line creates for us tax table. The most important part here is we don't have any magic inside type or IRM. We really see what typer RAM is doing for us through migrations. And here we can even change something if something is not correct. Actually, the whole code that you can see inside the strings is Postgres native code, which means I can copy it from here, paste inside PSQL and execute, and it will work. So here we're saying create table, which creates a table with name tags. And here we have round brackets. Here we must provide our column names and then the type. Ensure you should not understand on a 100% at the beginning, everything that you have inside migrations, you can simply execute them and then they are working. The most important part is that you can learn it later and always check and understand why it's not working. So actually we successfully created our migration. And now we know that here our migration was created based on our entity tag that we changed. Now the question is how we can execute this migration? Because normally when we've just set up the empty database, we want to apply there the correct schema, which means we need to run our migrations that we have and generate the latest version for our schema. And this is why we're jumping back inside R packages. And here we must create a new command to run migrations. This is why I am saying db migrate. Here will be yarn typo RAM. Here, migration Run, migration, run command executes all our migrations in the correct order. Now let's jump into console. Right here, yarn db migrate. And migrate doesn't create anything. It executes all migrations. So here we have lots of logs if you are interested. And here the most important part for us is that inside migrations we have this line create table tags. Which means after running our migrations, our table was created. And now we can jump inside our PSQL and right here duty. And as you can see, we have not one table, but to, first of all, we have our tags which is correctly created. And secondly, we have now a table with our migrations. Let's check what we have inside. Here. We can write select star from migrations, semicolon. And as you can see now we have only a single record here with AD. This is the timestamp when our migration was executed. Here, read the name. Why do we need this actually type program control and know what migrations were executed. So at the moment when we're running yarn db migrate, diapers need to check what migrations are there already in database. This is why here it is storing them. We don't need to do anything with this migration stable, but diaper RAM will use this information to understand what migrations it needs to execute. Once again, what we did, first of all, we removed this synchronized false. Why we need to remove it because we don't want any magic from typo RAM. Second, Lubert added here configuration for our migrations and created our first migration for our tags. And when you want to create a new Migration, dipole room checks in what state our table and database is and what entities we have. And if we have something different than this, changes will go in this migration. This is how our create decks was created. Now I want to short-lived goals through the whole workflow using migrations. So first of all, we're committing all migrations because they are a part of the project. Which actually means every single time when you are changing database, you create new migration. And this is a mask. In other case, you don't know what you really changed. First of all, when you want to run your project on the new machine, you clone it, install all dependencies, and then you want to do migrations. This is why you just execute yarn db migrate if your database is empty, if not, normally you want to make first young to be dropped and then yarn db migrate. And actually at this moment you will see that I don't have any migration. So here you can see no migrations are pending because our database is in the last state. When you are doing production, you normally will clone your projects there or maybe deploy. And then you also want to execute their migrations. And if you want on production later to change the field or maybe to add new table, then you simply locally create a new Migration and then you execute this migration on production. And you are sure that you won't break the database. Because inside migration, you really know how you are changing the state. So migrations are a must for real-world projects. This is why we will use them for all our entities. 13. Preparing register request: In this video, we're starting to create our new module and new API. This is the registering of a user. Let's check this out. Here. I opened our requirements. As you can see, we have here a registration part and this is the post request. So we're creating a user for slash api slash users. This is the example of the request. So we have an object whose property user this is important, so we're not throw in all fields just inside rude, but they are inside user. Here we're biasing the users name, email, and password. And of course all these three fields are mandatory, no authentication required, and we're returning back a user. This is how our user is looking like. So it is looking like this across the whole application. Here we have an object with filled user, and here's our e-mail username, biography, image, and talking about token, we will talk later, but this is the raw thin that we will implement. Solid start coding. I will jump back inside our source. And as you can see here, we have our tag module. So actually all requests which are related to tags were right in here. If we're now talking about authentication, it makes sense to create everything in additional module and we can call it, for example, user, because actually registration is just the creation of the user. This is where here I will create new folder, which is called user. And as always it is singular and inside we're registering module. And if you don't know how to do it or you don't remember, you can always open on the right tag module, for example, and copy paste almost everything from here. But I highly recommend you to write from scratch several times so that you understand and know what you are writing. Here we want to expert our new class user module. Here on the top of this class we must write our module were important module from last year's common. And inside we're passing an object with some things. Now we must register our module inside module, because in other case it won't work. This is why I am jumping inside f module. And here I am importing our new user module. Here I have autocomplete and as always, it is relative. I want here absolute path. We successfully created our module. The next step is to create controller, because without controller, we don't have a place to write somewhere our API. This is why here I am creating user dot controller dot ds. And inside we're creating also export class. And here we will have user controller. On the top. We must add here a decorator controller. We're inverting it, and now we can create our new API methods. Now here is an important point, as you remember here inside tank, we wrote and said controller on the top, these tags, we specify that all our methods here inside must be prefixed with stacks. But this is not always comfortable. Why is that? Because if, for example we want different paths for different requests here, then we should not write it here inside controller because it will be then global for this controller. What we can do, we can manually specify a path for our average request. We're doing here, the creation of the user. This is why I want to create here a synchronous function create user. For now we don't know what we're getting and what we're returning. Actually, we can write here promise any, just to see that we didn't specify here any interface yet, and we must create it. The next step is to specify what type of request it is. And this is a post request because we are creating the user. This is why on the top I am writing a decorated posed by importing it from Nest chairs. Now of course we're master returns something here for now we can simply return, for example, a strain create user just to test if everything is working correctly. Now we can jump inside our server and see if we have any errors. There are no errors here and here somewhere. And we must have our user module. As you can see here, the line user module, which means that we are binded it correctly. But there is one more thing that we forgot to do. As I already said, we didn't say here inside controller what route Groupon to use. This is y here inside post, we must specify this route. In other case, this will be posted for home URL and this is not what we want. What we want here is slash users because we want to make post request on slash users. And this is exactly what is written here inside registration. So it should be slushy by slash users. This is why here I wrote users and it is valid only for this request. And if we will create some other requests, we can provide different path here. Now let's check if it's working with Postman. Postman is our bread and butter to test requests. As you see here, we have some URL that we can type, in, our case, localhost 3 thousand slash users. This is fine. Here we can choose what method we want. Here we want to post. We can also provide here lots of stuff. We don't need it now, here I want to click Send. As you can see here we're getting cannot find both users and this is not found. This is really the mistake that people are doing super often, especially when they're just starting to work with nice chairs. And the problem is here that it's not just not working, it just forgot to bind our controller inside module. Let's jump back inside our module. And here was user module. Inside our module we must write controllers array, and inside create user controllers. And of course here we will have add ab slash users slash user controller. Now when we try once again, it must work. As you can see here after sand, we're getting the message create user, which means our API is correctly created. Here is one more important thing that I want to show you. We will do a lot of requests. This is why we really can't type every request here. We want to save them. And in Postman, even in the free version, we can use collections. So actually here I can create new collection and name it, for example, ness chess. Now inside I can save all our request. And it's not that comfortable to make it here with plus, but we can jump back inside our history. Here is our slash users posts. And we can just say here Save and here we As. So we want to save as, and this is the request name. So we want to name it register just to know what we are doing here. Here is our collection list just here I am clicking Save. And now inside collection, Let's js. We can always click Register and this request will be out of field. If we change it with some data, then it will be also saved here. The next thing that we want to do is to create our service. So actually we don't want to write our business logic inside controller. This is why we will create user service. Here exactly like in tags, we have a service and here we first of all need an injectable. And after we're experts in our class User Service, now inside we can create a method create user. This is why here I am right? And create user exactly like in the controller. If you don't know yet what we will get back. But here at least I want to return create user for Rome service. Why is that? Because in this case we can first check if we bind it everything correctly. Here is our user service and we must registered inside user module. This is y here, result providers, and we're right in here, user service. And here is our input on the top with ab slash user. So our services there. Now we need to jump and controlling and do import it here. Again, if you forgot how to do it, you can always underwrite open our tech controller. We wrote exactly the same logic here. Here we have our constructor. And inside the constructor as an argument, we need to write private read-only, and here will be our user service. And the name is user service. We will do exactly the same impulse everywhere. So you just need to remember this one line here in the import I have slash slash user. And they think I will stop to change this relative path to absolute path. Because you already got the idea that absolute path is good. Now here instead of our great user, we can call this user service create Houston. And in this case, we don't have any business logic inside controller Bot Insight Service. Let's check if it's working. I'm hidden sand and here we're getting create user from service, which means we successfully configured everything to start developing our register module. 14. What is DTO?: In this video, I want to talk about D2L in this chess or data transfer object. And this is really simple. So normally when we're making, for example, post request, we have the body. And actually this party is named DTO inside knees, chest. Here the documentation we're inside controllers and detail is data transfer object, which actually means this is a schema of the payload that we provide for our back-end, for example, were registered user here we can check it as you can see here, there's registration, all this stuff here is actually our detour because this is the object that we're sending inside backend. So you might ask why it is important. This is simply pay Laude, simply body and we're throwing it. Yes, but we can validate detours inside nice chairs. This is first one. And secondly, actually DTO is a class and not an interface. Let's check this on the example. Here we have our create users here are exposed. And actually what we want to do, normally we want to read body here. And actually we have a special decorator to get boarded directly from request. Here inside create user, we can write directly at decorator. Here we're writing body, as you can see here, result or invert. And then side round brackets, we're right in the name what we want to get y, because actually we don't care about this property user and we really want to just get this data. This is why here we can write user and then we're not getting the whole body but just using, this is really convenient. Secondly, after this decorator will need to provide the name for our local property. And actually I will name it create user DTO just because they don't want to have some strange naming and will know, okay, the request is create user, and this is the payload of create user request. This is y. Here is create user DTO, and for now I will write it here as a type. The most important part that this is a local property, which is just a body of user. And now we can pass great detail, for example, inside our service. But for now I will simply console log it here. This is create user, and here is create user DTO. Now we need to pass something inside our request. This is y. Here I'm clicking on Body tab. And here we are interested to select row by row because here will be a plane JSON. We want here adjacent with field using it. Now inside the user we have an object with several properties. First of all is our username. So here we're right in the username. And this is, for example, full. Then we have here e-mail, and this will be full at gmail.com. And we have here, our password. Here will be 123. The most important part is that this is adjacent, which actually means you must write here quotes. In other case, it won't work. Here. You can select this as JSON and then you will get a nice highlight. And actually here, as you can see, I missed the quote. So this is how we're passing body. Now I'm hidden sand and we must look inside our console. As you can see here, we're getting consoler create user, username Fu, email password, which means we don't need to do anything. We don't need to install additional packages. Like for example, with Express, we're getting all this stuff out of the box inside nice chairs. We have this decorator body and this is how we're reading body inside our requests. So actually to make it more realistic, we can pass inside our create user function, create D2L, and then we can jump inside our service. Here we know that we're getting create DTO for now without time. This is why here I am writing any. Here we can return our create the term just to see what we passed inside. Here, let's jump in Postman, I am clicking Send, and here we're getting our data back, which means we pass them inside service and everything is good. Now the question is how we can write a type for this DTO. And as I said here in set controller, we don't want, of course, any book Born to specify an interface. But here is the problem. There is a difference between an interface in TypeScript and the class. Interface is just a datatype and to just exist inside TypeScript. So it doesn't exist inside the runtime in JavaScript. But classes actually exists in JavaScript because this is just prototypes and they have been cold. This is super important for us because we want to validate them. This is why here it doesn't make any sense to write just an interface, but we can write here a class. What I want to do here is to have a class create user, DTO was big C. Now we must create here a new folder duty on, and here inside we will store all our details. And here we can name the file create user dot dto, dot ts. So actually the TOR is our entity. And now inside we simply create a class. This is nothing special. There is no magic here. So this is just a plain type script class was no less chairs. Here we are saying that this is create user DTO. And inside we can write several properties. For example, we can say that here we have read-only username. This is type string. Then we can create read-only e-mail. This is also type string, and here is our read-only password. And if you're asking why I am right in here read-only because actually this is the payload and we should not change our payload. Now we can use our class that we created inside controller. So here I will import it on the top and now visit the class. So we're passing inside actually the deuterium, which is our class. Now here we're passing it inside and we can also use it here instead of Fannie. Here we're getting create user detail. And actually it won't change anything from the code. Because here we just specify that as a datatype. We can check that this is still working here. Send, we're getting the same data back. But the point is that later we will validate data inside this class. And this is exactly the idea of detail. 15. Creating user entity: In previous video, we prepared everything that we need to make our register request. Now it's time to start working with user. And actually we always must plan our application by entities. For example, we have an entity tag and denote case. It's even easier because we can always jump here inside our specification and check all entities that we must implement. In our case, for example, we have an entity user later, also profile and so on. Now we want to create an entity user, and this means that we can operate with this entity. For example, we must create a table where we will store our users. Also, we can get user, of course, save user registration or maybe update currentUser. In our case for this, we're doing exactly the same lake with DID insight tag. This is why I want here to open our Tag entity on the right and on the left-hand side, the user, I will create a new file, user entity dot ts. And this is where our user leaves. And this is the entity by which type of RAM will create a table for us. And we will of course do migrations. What we want here is export class and here we have user entity. Here on the top we must write and decorator. And here we're saying name users because I want my table to be not user like this entity but users. Now let's create all properties inside will always need here a primary generated column. This is our AD and we know that this is a number. Now here we will create other columns. As you can see here, we have e-mail token we don't need to store, we will add it later, username, biography and image. Here. First of all, we can say that we have column and it will be our e-mail which is a string. Now also we need biography. So here will be also column with round brackets of course. And here is biography and it is also a string. But here it makes sense to set a default value. And we can say that this is an empty string, in this case in front, and we should not check if it is now or string will always store here string. This is why here we can say default. And as you can see here, there's autocomplete of TypeScript for us. And here I am saying an empty string. The next property that I want to store here is of course, our image here will be column, and we can also set the image to empty string. This is y here will be default empty string. And here is our image, which is string. And actually in our case, image is not truly an image. This is just the URL where we can load the image. And last but not least here is of course a password, but we don't want to store it. Just like we said, it inside the forum would want to hash it. This is where here I will add one more column and we know that this will be password and it is string. But now we don't want just to save it here, but we wanted to generate it. For this here on the bottom, we can write before insert. And as you can see before insert this as a decorator, which is a method. And this method will be called when we make an insertion, which means after creation. Here we are right in, before insert in here will be our function which will be assessing. And we can name it how we want, for example, hash passport, because this is exactly what we're doing inside. Here. We can write this password. Here, we must hash it. So we need to install additional library for hashing passwords. I highly recommend you to use decrypt library. This is the most popular library, as you can see, to encrypt your password from this library, we want to use a method hash. Here's the example how to hash password. We're calling decrypt hash. Here is our plane password that we wrote in our forum, and here is the salt solve. This means how many times it will be encrypted, then we just get a callback. So as you can see, this is an asynchronous function, which means we must write it with a weight. Now let's jump into the console and then style be gripped package. So here is, I'm in console yarn AD via decrypt. It is being installed. Now we can jump back inside our editor. And here on the top, I want to import function hash from decrypt. Now here we must use it. And this is important here that we wrote as sink because hash is a synchronous. This is why here we must try await hash. Here inside where bison, this password, what did they actually, this password is the current password that we wrote inside form. Why? Because when we're calling save will have all these fields and we have our password, and we want to override it with the hashed version of our password. And here we also must provide a salt. This is where here I am writing ten. Now let's check if we have any errors. I'm jumping here in the server and as you can see, everything is green. So actually this is our new entity user, which will be stored in our table users, which we will create through migrations in a second. Now it's time to create a migration. And just to remind you, we have some state of our database. Here we can jump in peer scale. And right here, we can see here migrations and texts. Actually at the moment when we will create new migration, our typo room will understand that this is user entity and it's not in the table yet. In this case, we will get this information regarding this user entity in the new migration. So just to remind you, inside package Jason, we have here the command db create. So let's jump inside console and dried yarn, and here will be DB create, and here was previously create tags. Now we can write create users. We're hitting Enter and our migration is generated. As you can see, we are getting message generated successfully. Let's check what we have inside source migrations. We have new files, create users. This is our command. As you can see, it looks really the same like our previous migration. We have here up and down. So down is to roll back. This is y here, drop table users, which means delete. And here is our create table with all our fields. So as you can see, all these fields are fields that we specified already inside our entity. And actually, if you have some questions, what here is happening, for example, you don't know what is create table users or Cyril not null and so on. You can always google some partial part of it was worth Postgres and find lots of information for us. Now it's not that relevant because we will work with our tables and see if something is not correct. But this is of course nice to know for better understanding. Actually, I'll migration was created and now we must execute it because it was not applied here to our table. This is why I am writing yarn db migrate and this master apply all our migrations. First migration is already applied. And here as you can see, we have new code. Here is our create table users, which means our table was successfully generated. Here I can jump now in PSQL and dry the teeth. And as you can see here is our user's table. Here it is, and we can describe it. So check all its schema. And as you can see here, our columns ID, email, biography, image, and password, which means this is exactly what we wanted. Now we're actually almost done. We prepared our table. We have basic code, was our controller here. Let's check this. We have user controller here. We're getting our body from request and we're passing this create user details inside or service. So the only thing that we're missing is inside the service, we must write some code to create our new entity user and save it. Let's do this now we don't need here return detail, but instead we want to create new entity. This is why here we need to write const, new user. In here is new user entity. This user entity where expert mean exactly from our file that we created. In this case, new user is exactly the instance of our user entity. So actually it doesn't have any fields inside what we want to do. Now, we want to write inside this object all fields from create D2L. And actually this is really easy to do with object assign because we want to have this new user as a property and not create a new one. So we really need to do everything mutable and immutable. This is why here I am writing object assign, and here will be my new user. This is what I wanted to overwrite and I'm overriding it with create the Tiana. Actually I don't like the name create detail because here is create user detail. This is why I think create user detail here is better and more clean code. Here we assigned all properties now from create user inside our new user. And actually we can console log it here so we can check what's going on. Let's try it here in New User, and here is our new user. Now we can just jump inside Postman and make our request. So here I'm hitting sand, as you can see this as our previous request. Now we must jump to the console and check it. As you can see this as new users, this is user identity and we have all these properties that we got inside. This is all fine and we just need to save now this user identity. What we want to do here is return a weight because always saved into the database is with a weight because this is a synchronous process. And here we can use this user repository. And just to remind you, what is repository, this is exactly the way how we're working with oil RAM. We already did it inside tech service. Just to remind you here with the constructor, with injection, we must do exactly the same here. So we are writing constructor. And here there's brackets. And inside we have our inject repository. And inside we're biasing now our new entity, user entity because we're working with our user. Here we have our private read-only property, and here will be our user repository. We're saying that this is repository of type user entity. As you can see, code is a 100% the same. We just copy, pasted it and change here the entity and entity inside our repository. Now here we can use this user repository. For this, we're right in here away. It uses repository dot and we can do, for example, save. And this is exactly what we want. So it saves the entities to the database. Entity is our new user. Just this single line, do all magic and saves our user to database. This is why Rams are so awesome. You should not know SQL, you should not understand fully how to make requests to the database. You just use a wrapper and it works like magic out of the box. Let's check if it's working now. I will jump inside postmen and click Send. And as you can see here, cannot send the request. And normally we're getting this error. If something is broken, we must jump and said Sarah, and check what we have. And as you can see here, our problem is that nest countries of dependencies of the user service, which actually means we provided something inside user service, but nest doesn't know what to do with it. And our problem is, of course, this user identities repository because we forgot to add dipole ramp input inside our module. So just to remind you inside our tag, inside tech module, we wrote this line typo REM module for future Tag entity. But inside our user module, we don't have this line and this is exactly the problem here. We must add an import. Here inside we have type or module dot for future, and inside we have array of features and in our case it will be user entity. In this case, we can inject repositories with user entity and use it inside. But for example, Tag entity, we can't use it because we didn't injected it. Now, let's check if it's working. I am jumping and say postmen, I'm hitting sand. And as you can see, this is my answer, which actually means that this is working. This is actually our user from the database that is already saved. Here we have username, email, password, and the password is already hashed, which means we're not storing passwords as plain and we should never do this. Here is our AD. This was generated by database and biography and damage we didn't provide, which actually means all information that we give inside our payload is there. And due to saved, we can of course check it inside database. So here I am inside PSQL and I can write select star, which means all from users. And here I am hitting semicolon and Enter. As you can see, this is our new elements, so we have a D1, here is our email. We don't have anything in biography and damage, and here is our hashed password, which actually means that we've successfully created a user and saved it inside the database. Now, I just want to fix typings a little bit. Actually, let's jump back inside our service. And here, as you can see with don't say what we are getting back. But actually when we hover on this function, you can see that here as an argument where getting create user detail and back we're getting promise of user entity, which actually means user entity is what we are getting back. This was created and TypeScript understands all of the staff, but I highly recommend you to always explicitly say what you want to get back. In this case, you will get an error when it's not like you expected. This is why I am saying that I want back a promise with user entity. Now let's jump inside controller and do the same. So here we specify that we're getting back promise any, which actually is not true here we have promise of user and here is entity. We're specifying everywhere our entities. And as you can see, we don't get any errors. But actually this is not correct. Because if we jump in RSpec and here we can see the response. The response is the object with property user and feels inside. And as you can see here, instead Postman, we just get all our fields and not what we have here. This is one more problem to fix in the next video. 16. Generating jwt token: In this video, we must fix two problems. First of all, as you saw in the previous video, but don't have the correct response because I will response is packed in additional property user. This is not that difficult to fix, but we also have here a token. And what is token? This is a DVT token which is used for authentication. The idea of DVT is that our back-end generates some token and then on front and we're saving it, for example, in the cookie. And then this cookie is being attached to every request. And in this case, our backend nulls What request is coming and what user is making this request. In this case, we can give the correct data or make, for example, forbidden answers if the token is not correct. This is exactly what we will do in this video. So actually the main problem that they see is if you are Google and gt for example, you are getting all articles just about post-purchase, which is kind of a little bit complex and not that low-level. And actually we will build, GET on our own because it is super easy and we don't need any additional dependencies. For this, we will use a package which is called JSON Web Token. This is the most popular package to generate our GVD string. This is why we're jumping inside of our console. And here I am right in yarn, add JSON Web Token. This will install this package. Here we're interested in the methods sign, as you can see here is usage DVTs sign in payload. We can pass whatever bond. Here we have a secret key. The secret key is super important because this is our unique secret key, which nose on our back-end. And then this function will generate for us a string that we must bass bag for our front-end. So let's check here. First of all, as you can see, my package of JSON Web Token is installed. I can jump back inside O controller. Here. We must do this inside our Create User Service, white there, because I don't want to pollute our create user controller. And normally weld right, and all business logic inside our service. So actually we can write this logic directly inside create user function. But this is not good because we want a separation of concerns, which means actually create user function is really super plane. It just gets the duty OR and gives us back user entity and we're not storing inside database attributed token, which means this function is not the best place to write this code. What we can do here, we can create a new function. It's not even a sin k thing. And here we can write build user response y like this, because actually we will build the response for our front-end. And actually inside we can write our code to generate this kind of response. So what I want to get here is a user, and this is our user identity. So this means that this function we will call not inside create user, but inside the controller after we're already get a user, hear back for now, I will just return any and we will fix it in five minutes. What we want to do inside, we want to build our correct response. So here we have our user. And for this we want to merge all fields from the user of width, the token. Why is that? Because this create user function is generating false user entity. So actually all these fields except of the token, which actually means we must spread here all fields and then add token. In this case, I'm spread in here our user. And then I'm adding here our token which actually must be generated. This is where here we already need one more function which will generate for us a token. This is where hear this Generate token. For example, maybe generate GBT. And here inside where bias in our user. Now let's create this function, generate GET, which is getting a juicy. And we know that this is user entity and back it must give us a string because Judy token is just a string. Now this is fine. We have this built user response. Now let's use it inside our controller. First of all, here, we don't want to just return everything. We must first save it inside some property. This is y, here is user, and here of course equals sign. And now we must return here our new function. So this User Service build response. And as you can see, I called it build user response, which actually is exactly what we need. We need here to build a response for our front-end. And inside we're biasing our user, which is a user identity. And as you can see here, we're getting directly and narrow. So the error is the argument of type promise user identity is not assignable to put a meter of type user entity. The main problem is here that I forgot to write here a weight. This is way back inside user. We're not getting user entity, but a promise. And TypeScript really helps to fix such problems. So now let's jump back inside this build user response. And check if it's working actually here, generativity doesn't do anything. So let us return here, for example four. So at least we can see that it is compiling. Here I'm opening Postman and hidden send request. As you can see now we have other structures. So we have here an object with user and all our fields here, which means this is exactly what we wanted. And we even have here a property token, which is a string form. Now we just need to generate Gvd token by using a library. So let's jump back inside our service and dried this generativity. For this, we must use from JSON Web Token this function sine. This is why here I will import the function sine from and here is JSON web token. Now here inside our generativity, we can write return and call here our sine function. The main point is that inside pay load, we can provide whatever we want. And for us it is important to have some useful information here. This is y here I want to write inside. First of all, AD, this is our user AD, then username, because we can render this information on the front end here, this user username. And here maybe an email. Here we'll be user.email. And actually as you can see, we don't have username, which means we forgot to create it inside user entity. But we will fix it in a second. Because here we must for sure use username. And the last thing that we need here is our GBT secret. As you can see here, we have some secret key. So this is the key that we must use and know on the backend, we can write here for whatever you want, but I really prefer to save this stuff inside some conflict. This is why inside source, I want to create new file and call it conflict dot ts. Here we will write all such global properties for our server. Here we can write export const. Here will be the name, for example, GBT secret. Here inside you can write whatever string you want, for example, super secret. So our string is there. Now we can use it instead of just plain stream here. So I want to write here, GET secret. And of course I got my outer input here on the top from AP conflict, which actually means this thing will generate for us as stream. But now we have a problem with this username. But we can't really just write it inside an entity because it's not inside the migration. This is why we actually must create one more migration to add this username property inside our database. This is why I wanted to jump and say user entity. And somewhere here we're creating a new column. And we're saying that this is username and this is a string. Now we must generate in your migration. Here I'm jumping and say Shell and I'm right and yarn db create. And here will be not create users, but maybe add username to users. So we really want the name to be understandable what we're doing inside. As you can see, our migration was generated. Let's check what we have inside. Here we have our third migration and username to users. And as you can see here is on the one line, alter table. Alter table means change table structure. This is why here we have alter table users add username, which means this is correct migrations. And we're adding a new column username here inside our users. Now we must call yarn db migrate to apply our migrations. And as you can see, actually record an arrow. So credit failed and colon username of relation users can tell null values. And before we will start to dig deep inside migrations, I highly recommend you in this case, to just remove everything, the whole database and apply migrations again, this might help. In this case, we're not spending time by the bike and some magic, but simply remove everything. This is why yarn dB drop. This will completely drop the database and then Yan db migrate. We'll add all our migrations. As you can see now, all migrations are working and we don't have any magic errors. And actually this problem was because we already created the inside user and this user didn't have the correct schema. This is why the best way is always to remove your database completely and regenerate the schema. Now let's jump back and say though a Gvd servers and finish it. Here I am opening our user, User Service. And here as you can see, we don't have any error and they actually were successful at generated distributed team. So we simply call a function, we don't do anything. And this function is being called here. As you can see, we don't have any errors. So let's try and create new user. I'm jumping and said Postman, I am hidden sand. And this is our answer. As you can see, this is our new token, which is exactly LGBT generated token. Which means we don't do anything. We simply call a library. We provide there a secret and we're getting back this token. Now we can safely give this talk into the front end. And this is exactly what front-end once. The last thing that I want to fix here is of course our datatypes. So if we are jumping back, as you can see, we have here any and of course n is bad and normally want to create here some interface. So I highly recommend you for all responses to create an interface. In this case, it is easier to understand what's going on. And we don't create here a detail like we did because we're using detours only for payload. What I want to do now here inside the user is created new folded types, where we will store all our interfaces. Now here I want to create new interface for our response. This is why here I have used the response dot interface dot ts. And inside I will export here an interface, user response interface. Now the question is what we're writing inside? The main point is that here actually in this spec, we have inside the entity. And additionally we have here a token, which actually means this interface is a mix of entity and our token. We can solve this problem by some advanced TypeScript. Here we want to say user, this is exactly this part and insight want to merge our user identity with property token. What I want to write here is user entity and this is our class. And here we can write end. And here it is object. We stock in string. Why I'm writing like this. Because actually we want to have new interface, but we don't want to specify the inside all properties from user entity because it doesn't make any sense, then it will be just a duplicate from user entity. So actually we want to have all properties from user entity, but additionally token property. For this, we can use this end which actually merges two types. And this is why we're merging our user entity with the object where inside we have token stream. Now let's try to use this user response interface inside our service. So here I am just paste in that this is user response interface and we need to import it. And as you can see, we're getting directly and narrow. As you can see here, we have a property hash password is missing in type token AD blah-blah-blah. We have all our properties. What is the hash password? If we will open here our user entity. You can see on the bottom before insert hash password, which actually means from our user entity we're getting all properties and hashed password also. But this is only the datatype, which actually means we want to use our user entity but result hashed password. And actually we can do this by creating a new type, but just present this hash password. For this, I will jump back inside of a types and create here user type. Here we can write user dot type, dot ts. So here we want to export our new type and we'll name it user type. What we want to do here is just simply on meat from our user entity one property. And for this n-type script we have Omid. And inside we're passing our user entity. There's a second argument we're passing here string that we want to emit. And this is our hash password, which actually means our new user type is exactly user entity. So all properties but except of hash password. Now we can use this user type inside our user response interface. So we're just removing here user entity and right in here user type. Now let's check if it's working. I am jumping back inside or user service. And as you can see here, we don't get any errors. Because in our case now we know that user response is an interface where inside where merging our user entity with object was talking. But actually from this user entity inside user type were unmetered this hashed password, this is it. And actually by using on meat and then operator, you are using more advanced TypeScript stuff. This is why if you really know TypeScript good, you can write better nest GIS applications also, let's check if we have any errors inside of observer. As you can see now we have the errors inside our user controller because here we didn't use the correct interface. So let's check this out. Here. We're inside user controller. Here we're returning back the promise of user entity. And of course this is not correct because our build user service is returning for us user response interface, which means our response for front-end. This is y here instead of user entity, we must write user response interface. And this is our interface from user entity was talking inside. Here we can of course removed now user entity. Let's check this out. As you can see, everything is green. Now we can open Postman and try once again. As you can see, everything is working exactly like previously. But now we are on the safe side because we typed everything correctly and actually capable use this response interfaces everywhere in the next modules just to show what data where I've been for the frontend. 17. Validation pipes: In this video, you will learn how to validate requests in this chess and actually nest Jess did a good job by implementing the pipes. So what is pipes? The main idea that we can somehow proceed with our arguments inside controller. Normally inside controller we have something from our requests like for example, body, and we want to either validated or transform it. We're doing this through pipes and this is the standard feature of nice chairs. And as you can see, these are built in pipes like validation Pi percent pipe and so on. And actually the most popular from this list is a validation pipe. Because we can use validation pipe together with our detours that we made, for example, for registered request and out of the box in a matter of seconds, we're getting really nice validation. So let's try this out. Here we have our create user request. What we can do after our posts, we can add one more decorator and this called use pipes. Use pipes is common from Nest chest. Now in size here we can say New and here we'll validation pipe. As you can see, it is already there and we don't need to do anything at all. With this single liner. We're bringing the validation to our detail inside our method. And now of course it won't work. Let's see here, as you can see, we're getting the error. The class validated package is missing. This is because this functionality was by act in additional NPM package, which means we're must jump in the console. And right here you can add, and as you can see, the name is class validated. So we can copy this and end here. And class valid data is coming also from less chairs. We just need to install it and restart our web server. And here we must get one more error because this one package is not enough. As you can see here, we have one more error and in our case glass transform. A package is missing. This is the second package that we must install in order to use validation pipes. Here I am writing the yarn ed, and here is our class transformer. It is already installed. This is why we must restart our webserver. And in this case it must work. As you can see, we don't have any errors now and we're good to go. So actually how does it work at Hope, the main idea is that we're using detours. In our case here, we have a create user detailed class. And this create user DTO is exactly what is being checked inside this new validation pipe. And actually in our case now it doesn't check anything because here we can jump inside our detail. Create user DTO, and we don't have any validation rules here. So actually now we can add here validation rules for our payload. First of all, we can say that user's name must be present. Here we can use decorator is not empty. And as you can see that this is outer input from class validated that we installed previously. Now here we can add one more rule is not empty because email also should not be empty and also is e-mail. And as you can see, there are a lot of stuff here, like it's enum is email is empty and so on. So out of the box we're getting a lot of staff for our validation rules. Here is password, we can say here is not empty also because password is mandatory inside our form of registration. What step do we need to do in order to bring validation inside next chess? First of all, we're in style and two additional packages. Secondly, we're using detours, which is just a class. Here we're using class validate or decorators for every property where we need to. Then we're just jumping inside our controller and we're using here use pipes were inside where providing validation pipe, which is the default pipe. Now let's check if we have any errors with don't have any. So let's jump inside of postman and check if it's working. This is our normal request where hidden sand and we're creating the user. This is because in body we're past all data. Now let's try and remove everything from here. So we have just simply user here and we don't have enough data. I'm hidden sand. And as you can see, we're getting an amazing validation errors just out of the box. So here we have status code 400, and here is our message. First of all, here are messages for all our fields that they should not be empty. We also have here that email must be an email. And obviously now it's not correct. And doing if we're paste in everything but here we're just missing password, then we will get the error on further password, which actually means in a matter of minutes, we configured our validation for our registering request. Now, I want to additionally to check if the e-mail and username already exists. And actually it's not related to validation pipe settle because we can't really make a database requests inside validation pipes, which actually means here inside controller book can't validate create user DTO, and we must do it on the level of user service. This is why here I am jumping inside User Service and here is our method create user. What we want now here is to add some rules to check if this email is not used and this username is also unique. And for this, we can easily use our eardrum to check if we have the user with such username and email. First of all, here I want to write user by e-mail. And here we will use a weight. Here we have this user repository and we have here a method find one. You can understand from the name. It finds the single record by some predicate. Here we can pass an object and inside we can write e-mail. And here will be our create user detour dot email. So here we will get back a user if this email is already registered inside our database. Now I want to do this same for our username. Here we can name it user Bye, username. Here we're using find one. Here we want username property. Here is create the tour dot username. So actually here we're getting a user or undefined it. And here also, now we can write here the logic that if user by e-mail or users by username. So if either of them is there, then we want to throw the error that data are not valid. And actually in essence, this is the Mason that you can throw error anywhere and it will be propagated until the front-end, which means until our API. So what we want to do here is to write thrown you. Here we can write HTTP exception. And as you can see, this is from Nest chest. And now inside we can write some message to describe what happened. For example, here we can say email or username. Taken. There's a second parameter we want to write, what status code we want to throw. And they really like photo too, because this is an unprocessable entity. This means that the data of the user did not pass our validation. And actually we don't want to write here photo to like this because we have all these status codes inside NYSE GS and they are statically typed. Here I want to write HTTP status, and as you can see, it's from less chairs. And here we have all the statuses and we can write here unprocessable entity. And as you can see inside, we have four to two, which means that this is an enum that we can use everywhere to throw needed status code. Now let's check if it's working. Here. We don't have any errors. And let's try to create a user. I'm hitting here sand, and as you can see, we're getting our new arrow, so it's not a validation error here we have photo tool and here is our message, email or username are taken. And this is because every single time when we were registering the user here we're using the same credentials with full and full at gmail.com. And actually both of them are already taken. And here of course, when we're checking this and this were getting back a record, which means we're successfully validated that username or email must be unique. 18. Login request: In this video, we will implement login ID of the user. And actually here I want you to try and do it by yourself. And they have a full faith that you can do it on your own. Because actually now you have enough knowledge to do it. And actually I have three levels of complexity for you. First of all, is the difficult. Actually here is what you must implement. As you can see in specification for authentication, we have the URL slash, api slash users slash login. And this is our request, which actually looks exactly the same way Register requests, but here we have only email and password and username. As you can see, it also returns a user, which means we have exactly the same response like previously for our registration. So you can reuse all stuff that we prepared. If you think that you can do it on your own, then I highly recommend you to pause this video and try to do it yourself. If you need a little bit guidance from me. Here is level tool, which is medium. Here is how I'm planning to do this. First of all, as I said, we have a new request and it is related to the user because this is the login, which means we can use exactly the same users module and user controller. Here in CRT controller will want to create a new request, which means we are creating a new function login. And here we will use exactly the same validation pipes. We will have a different URL, and here we'll also need a detour. Here we have detour for create user, but now we need to create a new detour, which is login. User response will be the same like and said registering. And here we will use the new method that we must tried not create user but login user. And actually now inside service we must create a new function which will login the user. The question is, what is login? Actually, we don't need to implement login. We just need to return the user if we can find it by email. This is the basics. If you want to make it more advanced, you can also implement comparing the password. Because actually we want to compare the password that we are getting with the password inside the database. For this, we can use a function be gripped dot compare. Just to remind you, decrypt is the package that we used to hash our password, which actually means our login function simply gets the user from the database. And if it is there, then checks the password and returns the user. Here it is level two for you. If you think that you can implement it on your own, then just pause the video here and try it yourself. Now here is level easy. Let's just implement it together. First of all, I want to jump inside user controller. And as I said here, we must create a new function. And we can name this function login because this is exactly the login process. First of all, here the question is what is login? And this is also post. And as you can see here, we must provide a new URL, which is users slash login. This is exactly what we can see here if we're finding login inside our specification. The next part is to create a function. And actually we can directly write here use pipes. Because in any case, we just want to call this validation pipe on our D2L. Here There's our asynchronous function and we can name it login. Now inside this function, we must get the body. And actually as you saw here, the body is also inside the user. So we can write exactly the same code. Here is body user. And we know that here we're getting our login details of type detour. I will write here any we will create detour in a second. Login details is our argument and we want to specify what we're getting back. Here. We're getting the promise of our user response interface that we used inside registering. So actually as you can see, our code is super similar. Now inside this function, we want to get a user. So here we're using a weight for this user service, and here will be our new method login. And we're passing inside our login details. Just to remind you of this user is user entity, it's not user response interface. This is why here we must use this user service and here build user response that we prepared previously, because this function will automatically add token to our response. Now let's create our login duty on. For this, I will jump inside D2L folder and name it here, Login User dot, dot ts. And actually we can copy, paste everything from create user. But I will just once again, right from scratch so you can see how it is written. Here we want our class and our classes login user detail on. And inside we have only two fields. This is our email and password, and they both need to be presented. This is y here we're right in East, not empty. And here we have our password field, which is redundant. This is why here we don't know the password is a string. And now we need to do the same is no temperature for our password. Here is read-only password and this is a string. And actually as you can see, our detour is always looking the same. You can write it once and then either copy paste or use as an example. So our detail is created, we must use it inside our controller. Here we have our login UTR, and this is login detour that we just implemented. Now we just need to implement this login function inside our service. But first of all, let's check if we implemented everything successfully. I will comment out these two lines and just return here login for example, as any. And then right in here, just for the sake of testing, because if I unmute it, then we're getting the error that we must return here, user response interface and not a string. This is y, here is S any. And now we can console log here, our login duty to check if it is there, a console logged it. Let's check if we have any problems. As you can see here, after restarting, we don't have any errors. Let's jump in Postman and actually create the new route. Here we have slash users slash login will know that this is posted and we must provide our email and password and we don't need username here. And actually I want to save this request. This is why here I am clicking Save As here will be our login inside our collection nets chairs. So now we can reduce our login at anytime. Then hit in here send, as you can see, we are getting back the message login. Now let's check what we have inside console. As you can see, this is our login detail. This is exactly what we expected. Now everything is fine and we just need to implement this login method inside our service. So now I want to jump inside our user service and create a new method here. Note that this will be an asynchronous method because we will speak to our database. This is why here it is. I sink login and we'll know that we're getting login user detail on, which is of type login user TTR, backward getting promise of user entity. And this is important to remember, exactly like in our Create here, we're returning promise of user entities, so we don't return here some response for the front-end but plain database data. This is why here we have promise user entity. Now what we want to do inside is to check if this user exists with such e-mail. This is why here we can say cones to use m. And here we're using over eight. And exactly like we did here to find the user, we can use find one with email. Actually, this is these three lines here. What I can write is a weight, this user repository find one because we assumed that we have only a single record, because we have a validation that our email is always unique. And now here inside where write an email equals login user dto dot e-mail. And actually here we got a user. This means at least that user exists. And if not, then we must throw an error because the credentials are not correct. This is where here I am writing. If not user, which means user is not there, we want to throw our new era. And here we're using HTTP exception like we already did previously. And here let's try it. For example, credentials are not valid. Here we must provide a status code. So here we have again HTTP status dot unprocessable entity, so four to two. Now, if you have a user would want to check the password. This is y here. What I can do is have a comparison. So let's name this property is password, correct. For this, we can use the function compare and compare must be called with a weight because this is an asynchronous function. Here I'm importing compare. This function is from decrypt. This, you can see I don't have autocomplete here for some reason. This is why on the top I will import this function compare from decrypt. And just to remind you what this function is doing, it compares the plane password with our hashed version. We're using decrypt because it is the easiest way to hash password and check if the hair is exactly the same light plain version. This is y here inside our login, we can write compare and inside we must provide the password and encrypted password. This is why here I have login user detour dot password. This is our plane password. And then say user dot password, we have our hashed password. So actually here we're getting true. Then this means that we can authenticate the user. And if it is false, then we must throw an error. This is why here we also want to throw an error if password is not correct, this is why here, if password is not correct, we're throwing new era and this is of course, HTTP exception. Here, for example, again, credentials are not valid. Here we have our HTTP status dot and potential entity. And actually you might ask why we did this if first and then we have some logic and then exactly the same if we could just write it once and here, move this logic to the top. Yes, sure, you can do that. But actually the idea is that if our user is not there, we don't need to execute this code completely. This is why, First of all, I am checking for the user and secondly for correct and password. Here we've drawn our error. Now we just need to return our user from the database, which actually means that login request simply returns the user that is founded in database if fall validation is passed. Now let's check if it's working. Let's jump to our server. As you can see, no errors here. Let's jump and say Postman. And here I'm hitting sand. And as you can see, we're getting back all this information. So user or our fields, password and talking. And actually this is almost good because here we have all fields and also password. And of course don't want to take our password from the database and send it to the front and because it's not secure, but we will talk about it in a second. As you can see, actually, we successfully implemented our login because we did the check at the password is there here. If I'm changing this password on not correct version, then we are getting the message credentials are not valid, which means it is working. And actually we reuse a lot of code between our registration and login. Because for example, this generation of GBT talking we're using inside build user response. And exactly built user response is what prepares for us our response for front-end. So now we just need to solve the problem with this password that we're getting back from our database. And actually this is really easy how we can do it inside nice chairs. We can simply jump inside our user entity and here is our password. And we can say here, select false. What does it mean? It means that in all our requests by default, we're not selecting the password. And actually if we want to select the password, for example, for some check-in, then we must say this explicitly. And let's check this out. Now, I'm hitting here sand. And as you can see, we're getting 500 internal server error, which actually means that our code is not working and we have some problem. As you can see here, when I'm jumping in our web server, we can see the error data and hash arguments are required. And actually this error is with B crypt. Here we can jump inside our service and we're using here be crypt in Logan exactly here. What did the problem? Actually, the problem is that we just said that we don't want to select our password. This is why this password is not inside our user. Let's console log here, our user. You can see the problem here that the user that we just took from our database, and this is the default find one. And actually the default version, we'll just ignore the selection of the password because we defined it inside our entity. So let's jump on our server. We don't have any errors. Here. I'm hitting again. And as you can see, we still get in 500. But here now we have the user. As you can see in our user entity, we don't have a password, how we can fix it? Actually, the idea is that here, when we're selecting find one, we must get a user with the password. Because if not, then we can't compare it. But the main problem with that, we can't really say in find one that we want to select additional password, we can only specify exactly the array of fields that we want to select. So we're using here find one, this is fine, but here as a second parameter, we must provide our options here to the options select, and this is the array of fields that we want to select. We really mass type here, all our fields. And they know that this is not that comfortable, but this is how it is implemented inside type RM. And yes, there are open issues that people want to make it somehow better, but it's not there. But this is fine for us. We can type here a little bit more and dried our list. Here we have AD username, then email. After we need biography, image, and password. Password is important here because only one we are getting here the password, then we can make a comparison. Let's check this out. I am hitting sand once again, but as you can see here, we're getting password exactly back. Why it is happening. Because here inside our login with just using the same user like here to do our check, which actually means we got the user and here we specified the password and we're simply returning it here. And you might actually say why we wrote this select false here because it doesn't make any sense in our case. Yes, in the case of Logan, it doesn't make that much sense, but it is super safe because we will reduce this user entity a lot. For example, also for profiles, this is why we are on the safe side. One by default, we are not returning it. This means that we can't really forget to exclude it because it's not there by default. But what we can do in our case now, here we're getting our check with compare the user. And now what we can do here is simply delete the password. This is why here I will write delete user dot password. And in this case, after this line, I will user won't have password inside. And this is exactly the case only for logging in because most of the time we don't need the password inside our answers. Let's check if it's working. So I'm jumping inside Postman hidden sand. And as you can see that there is no password here, because after checking it here is password correct. We'll remove the password completely from our request. We've successfully implemented our login request, and let's check once again how it is working. First of all, here is our validation pipes, which actually we didn't test. Let's test it now. I will remove here the password completely and just hit Send. And as you can see, we are getting here validation pipes error, that password should not be empty, which means everything is working just fine. Now here we created login duty also were getting it and we're passing it inside. Our new method uses service login. We have here build user response to back our user identity correctly. Now inside this user service, we first of all finding the user. But here we're selecting all our fields because we must select password. Now explicitly, after this, Let's remove this console log. We're checking that our user is there. And if it's not there, we're throwing the error. Then we're checking here our password from decrypt. And here we're checking if password is not correct, we're throwing the error again. And now at the end version moving password because we don't need this anymore and return in the user. If you tried to make login feature on your own and you did it even partial, then you're awesome. And it is really important for your knowledge of nice chairs. 19. Auth middleware: In this video, we will learn such important point from ness chairs as middlewares. This is because now we must implement working with token. As you saw in the previous video, after we're making login or registering, we're getting back this token. So the idea is that front and we'll get this token, store it in local storage or cookie, and attach it to every request. Which actually means then backend can know what requests to what user is belonging. And this is exactly what we want. So actually when we're making some request, for example, getting currentUser, then we will get this token inside headers. This is y. Let's implement getting of current user and parcel of the token from headers. As you can see here, we have the request get current user, which is slushy pie slash user. Here we see that authentication is required. This is the part for other video. It doesn't have anything to do with our middlewares. But here this request must return our user back. What is the idea? Here inside our users Controller? Work creating new request. And as you can see this a slash api slash user. And it will be a GET request. But appointed that we don't have here any body or something that we're passing inside request. We're getting through headers magically, our token, and we will parse it before we will get to our request here. The main point is that we want to get currentUser from this header every single time before were hidden controller. Why? Because it is more comfortable for us. We can just say, okay, we have our request, for example, login, and we know that if this was attached, then we also get this current user already here inside request, which actually means we should not every single time in every controller, in every action, right, request headers take from their token, parse this token, then get user from database. By this token, we will all do this before. And as you already know this use pipes are for our parameters here. So actually we're doing something with parameters before were hidden. Our action inside controller and middlewares is a little bit similar. We're not working with parameters but with request itself. So middleware is happening before our request hits our controller. This is why it is middleware. It's in the middle. This is why we will create a middleware for our authentication where inside verbal bars our token. But as the first step, we must first create here a new function. So here I'm creating gatt and we'll know the tau URL is just use it because it stays here in our spec. Here is our GET request and here we need a sink and let's name it current user. Because this is the request to get the current user normally in front. And we're making this request every single time when we initialize our front end application. Here, we're not getting any parameter here. And we just return here promise of our user response interface. Because as you can see here in spec, it returns our user. Just to remind you, our user is this strange notation with property users. So we need also to build the correct response. This is why this function that we created earlier will be quite handy for us here. For now, let's just return inside, for example, current user. So we can see that this is working and of course as any, because in this case we are saying that this is a promise and this is exactly not a promise. This is just a plain data, but we will change it in a second. Now we must input this get decorator, it's not there. And we also want here to get access to our request. Why? Because they actually nest chairs is a wrapper around express the request, which is the whole request. We're inside, we have some data, for example, our headers, or later our user. And as you can see here that the example from documentation, and we can use the decorator request to get the whole request that we're making. Here we got only body but request will return us the whole request. This is where here I am saying request and we know that this is a decorator and here we must adjust, create a local property request of type request. Now let's console log what is request. So here is our request. Now we must do this request inside postman. As you can see here, we have some error. Request is not defined. So actually this request is coming from expressed directly. This is why I'm importing here request from expressed, not express, serve static core. Of course my autocomplete was not good, but express itself. And as you can see, we don't need to install additional express because it is already inside an SDS. Now let's check if it's working. As you can see, no errors here. Let's jump inside Postman and we want to make a get request for slash user. And now let's hit Send. And as you can see, we're getting back currentUser, which means we successfully implemented our action. And now I want to save this request here where hidden, Save As this is the request for current user. And we're safe in it inside next year's collection. So here it is. Now every single time we can hit send and we're getting our request. Now let's look inside console, and as you can see here is a lot of logs, and this is actually our full request. And as you can see that there's lots of information here. And everything we can read for us is interesting, is header spot. As you can see, these are all headers that we are getting. So normally our flow is like this. So we're jumping in and said Postman, let's say that we're in our front end application. We're making here our login with our body and where hidden sand. And we're getting back the stock in front and save this token somewhere, and then flaunt and later makes this current user request. And it must attach inside headers new property. This is why here I am hidden on Header and here we can provide and you keep though Q will be named authorization. And here the value will be token space and our token. And now I can hit send. And let's check what we have. And if you are asking why I wrote like this, because in our specification here is information regarding authentication header. So actually if our request is authenticated, we can provide here authorization header and it should look like token space and are talking here. And this is exactly what we did here. So token space and our token. Now if we will jump inside our web server here is our log. Somewhere here we have a new header. So actually if we find it on the top, you can see that here we have our authorization header, and this is our header, which means actually we can inside our controller here, somehow bars this header, get authorization token from it, then get current user, and then return this current user or operate with it. But of course, we don't want to do this for every request. This is why we will create a middleware. Now, what did they did? Actually, the idea is that our middleware will just take this header before our request will hit controller and from this token and get current hearsay and attach it to our request, which actually means here in set current user, we can get our user directly from the request without bothering restocking. So now let's create our middleware. For this insource user, I will create a new folder which is called middlewares. Because actually we are creating the middleware which belongs to the user, because it's related to authentications users and so on. The inside we want to create new file aus dot middleware, dot ts. And in this case, middleware is our entity. And what is Middleware? It is actually a class and this is y. Here will be expert class, our middleware. And the most important is this implements too because we must implement something that nest chest wants from us. This is why here we're saying nest middleware. This you can see after outer input, we're getting here and narrow. So property use is missing in type of middleware, bot is required. This is exactly the point. So our middleware must provide a function use because inside this US, we can do something regarding our request. This is why here I will create the function use. Here we're getting a request response and next. And actually the idea is that we can read all these things here and then do next. And next means that we did everything that we wanted and want to continue with pass in our request to the controller. This is why here I will write out middleware. And actually we're interested only in request headers. And now here we must call next, just like this to say that we're finished with our middleware. So actually this is the basic middleware which doesn't do anything. So our middleware is there. Now we're must registered inside some module. And actually weekend registered for example, in user module. But actually I want to register it inside app module because we want for all our requests all across the application, always decode our token and get current user. This will be easier for us and then we don't need to write additional logic in some requests. And here is how we can provide globally for all our actions. This middleware inside class at module we must write here, configure. This is a function where inside we have consumer and this is middleware consumer. I will open this function and inside we want to write consumer apply. Here we're biasing our OS middleware that we just created. Now here we can say for routes and specify here for what routes we want to apply this middleware. And actually we want to do it for all routes. This is why here the path is Start. And method will be request method dot o, which actually means to all methods. You don't really need to learn this code by heart, you can always find this example in the documentation. The most important point is that you understand that if you want to apply globalism middleware or not even globally inside module, you are right in this configured parent inside consumer apply. Here is your middleware. And you can say for what route you want to apply your middleware. In our case, it is a global middleware. This is why we're applying it here inside at module. Now let's check if it's working. Where jumping here inside the console, we don't have any errors. And now what I want to do is first of all remove console log from user controller because it's too much to see in the console. Now let's check if it's working. So I'm jumping in postmen here, don't forget inside headers we must provide the token which is valid. I'm hitting sand. And now let's check what we have inside console. As you can see here, that the console of middle, this is exactly console log from our middleware. And as you can see here, we're getting exactly the whole request. And we're interested in this authorization token, which actually means our middleware that we've just created is happening before our controller. Now we can do something with the request and then hit Next and then provide updated request inside our controller. Here is one important point. We really want separation of concerns inside of middlewares. We can also throw errors. For example, here, if user is not logged in weekend, throw something here. But I want to separate the logic because we don't want in our middleware to throw something. We just want to decode our user. And if you don't have a geosphere or a header, then we don't do anything and then request that user simply will be now, but we don't want to throw anything here. This is super important because we're attaching this OS middleware to all our requests. Which means if we are throwing something here, then it will be for all our requests. And we don't want this. First of all here, I want to write datatypes and actually request is of type, request and response is of type response. And here next is of type. Next function. We need additionally to add here request and response. Now we need to write some logic to check if we have head or not. This is why here we can write if and here will be request dot headers, dot authorization. So actually we're checking if we don't have this request. Then here we're setting the request user to now, and we're just calling Next. And here we also want a return just to be on the safe side, but I think nest is enough and we don't need to return it here, but it won't do any harm, so I will leave it here. The idea is that in this IV, if we don't have a header, we're just saying in requestUser that our user is now and we don't do anything at all. But here is one problem. As you can see here, property user does not exist on type request. This is actually correct because request comes from Express and we want somehow correctly to set a user inside requests. And for this, we can extend the standard request of expressing. This is why I want to jump in source and create a new folder types. Because here I want to create a global type where we will extend our request. And here I want to create Express request interface Ts. Now inside I want to export new interface and this is express request. Here I'm saying extends request. So actually this request is coming from express. This is y here I'm importing my request from express. Now inside this interface, what I want to do is add the user and this user can be there or not. This is why Here is question mark. Here I want user entity. User entity is our user result token without any additional properties or transformations. This is exactly what we want to use now inside our middleware. So let's jump back inside our user middlewares out middleware. And here instead of request, I will drive our Express request. This is the updated version. Sure, we could write any, for example, but it's not the best approach. The best approach is to extend the request. And now as you can see, we don't have an error because here we're saying that user can be not there. The next step is to get a token. So here we can say that we want to get a token, want to split our string, because we know that they have inside the word token and our token. This is why here we can try to request headers, and here we have authorization. And we want to split it by space because we have only two words. And we want to take the second argument here from our array. And let's console log here token, so we can check if everything is working. Let's save this and look in our web server. As you can see, no errors here. Let's jump inside Postman and hit Send. Now let's see here as you can see that this is our token, which actually means we successfully got talking here from our headers. Our next step is by this token to find a user. But first of all, we're master the code token to get some information from it. And we must always wrap our decoding of the token in try-catch because PivotTable throw a scenario if the token is not valid, this is way here I am writing try-catch. And actually if we have a cache and if we have here an arrow, we want to return here the same code like here on the top request user now, because if we can't parse token, it means that user is not there. Requested user equals. Now, here I want to call next. This is our cage. Now instead, try ****, want to decode our token. So here we have decoded. Here we must call a function verify from JSON web token. So let's import here on the top, verify from JSON Web Token. Here we can now write verify and inside we want to pass our token that we got and our secret. And just to remind you here inside our use of service, we have the code generated DVT, and to generate this GBT will use GET secret. Now to decode it on backend, we always need to use distributed secret. This is why here I am biasing our GET secret. Now let's check what we are getting back inside our console log. So here we have a decode. And they also want here to write next, because in other case, book bond get inside our controller without this next. As you can see, no errors here. Let's hit inside Postman sand. And as you can see, we're getting the error cannot get user when you are getting something like this, probably to have some error inside middleware so you're not hitting the controller. So let's jump in set console. As you can see, we have here stack trace, but for us it's the most important here is the code. So actually we successfully decoded our token and we have inside ID of the user, username and email, which means we can now use this decoding information to work with our user. So the next step here will be to use the code information and to get user from the database. But the problem is that here we don't have access to user repository and they really don't want to inject it here. What we can do is use here user service. What I want to do now is jump inside User Service and create here a new method which will get used by AD. Here I want to create a sync and let's name it, for example, get or find by ID. And we're passing inside AD, which is a number. Now we want back a promise of user entity. And now inside we simply need to return this user repository. Here we can use find one and pass inside our AD. So actually this is just a single line. This is just a wrapper sober avoid using repository inside middleware, but we're using our service. Now we can use this find by 80 inside our middlewares. We can easily inject it here because this is just a class. This is why here we have a constructor here exactly like in the controller. I'm saying private read-only. Here will be our user service of type user service where we wrote our method. Now we can use this user service here to get the user from the database. Here we can remove console log and dry it user where we're calling await because this is the request to the database. And here will be this user service not used but user service dot. And here is our find by ID and inside we're passing decode dot AD. So actually this line will find the user by the CD from the token inside database. And we can simply say here, request user equals our user. Now let's check if it's working. So I'm jumping here, we don't have any errors. Now let's jump inside Postman and hit Send. As you can see, we're still getting the error, unhandled promised rejection. And actually we can debug this code really long time. But the actual problem is here that I forgot to write on the top injectable decorator. Problem with injectable is that you are getting some other errors, but not directly that you forgot to write an injectable. This is why it is super difficult to fix. This is why I highly recommend you to always pay attention if you rolled injectable for your services or middlewares or not. Now let's check if it's working. So let's jump here. As you can see, we're still getting the error. But now this is the other arrow. We have here the error that nest countries of dependencies of the mouth middleware. And we must make sure that user service is available for app module. And the messages here are super important for us. These are potential solutions. First of all, use a service must be a provider of app module, but we don't want this because uses service belongs to our OS module. This is where hear that the second solution, if user service is export it from the separate module, is this module imported inside app module? So let's check this. If I'm jumping inside our app module, you can see that here we're importing our user module. This is fine. This is exactly what we want. The problem is that inside user module, we didn't expert user service. This is why we can't use, uses service outside of our user module. And we want to use it because we registered our middleware inside a module. This is where here we must provide inside experts, our user service. In this case, it will be available outside. Now actually, I solve one more problem inside our middleware. So let's jump inside middlewares. As you can see here on the bottom, we're calling next once again, this is not correct because we don't want and here we have already done next for our if condition and return. And here we have next for our try-catch, which means here we have additional Next and we probably will get some errors because we're calling next more than one time. So let's jump here inside web server, but don't have any errors. Let's jump inside Postman and hit Send. Now we're not getting any errors, but we are getting current user. So first of all, I want here to remove the console log from our middleware. And actually, as you can see, we're not using here response. This is why here we can write underscore to say that this is an induced variable for us. Now let's jump inside our user controller. And what we want to do here is console log, our request dot user here will be current user in controller. Here we want to read our request dot user. And as you can see here, we're getting exactly the same error because it's not request anymore, but express request that were created and extended. Now we don't have an error because here we have a user inside. Here we don't have any errors. Let's jump to Postman hit Send. Now check in console. As you can see, this is our user entity that we successfully got inside our middleware. This is our user that we fetched by talking inside middleware. And now we can use it directly inside our current user request. Which actually means now every single time when inside some action of the controller will need current user, we can get it directly from the request user was out parsing the token. Which means we really did all heavy lifting of working with stalking inside the middle there. Now as we have our currentUser in requestUser, we can just return the data in the correct format here. This is why I will return here, this dot user service, and here is build user response. And we're passing inside our request dot USA because we know that this is our current user. Let's check if it's working. I am jumping inside postmen, hidden sand. And this is our normal user like we wanted. So we have here our token, all these fields. And this is actually the get of the current user that we implemented. 20. User decorator: In this video, I want to talk about decorators inside nice chairs. We already saw a lot of them. As you can see, I'm on the official website of chess and here our program decorator. So these are the curators regarding programs inside controllers. As you can see here, we have requests or wreck were already used this we can also use response next session per gram, body, body world rarely used, and so on and so on. As you can see, there are lots of the curators and we can easily use them and we already did that, but we can also create our own decorators. In this video, I want to create one more decorator, which will be our own custom decorator. As you can see in any of our request, because we created the middleware, we can get current user. And to do this, we are writing here request decorator to get the whole request. And then we're using the request dot user. This is completely fine. We can live with it, but we can of course do better. We can write a custom decorator to get here directly a user and not the request. Let's build this now. For this, I want inside User folder to create a new folder which is called decorators. And here inside we will store all our decorators which are related to use a module. What I want to do here is to create a new decorator user, dot decorator, dot ds. And as you can see here, decorator is our entity. And actually decorator is really different from other entities, for example, like middlewares or services, because we don't need to register it inside next chess. Here we simply create it like just calling a function. This is y. Here I am write an export const and we want to create a decorator user, because this will be the decorator to get user from our request. Here book wants to call create, but RAM decorator. And as you can see, this is a function from less chairs to create a parameter decorator. This means that our decorator will be used only with params. Now inside our Create Parameter decorator, we must provide the function. This function has two properties. First of all, it is data and I will write here any, and they will say why in a second. And here we have our context, and it will be our execution contexts. Now here we have a function and here we can return whatever we want. So we can write here four. As you can see here, to create a decorator, we're using create program decorator. And inside we're passing function and we have access to two arguments and we will talk about them in a second. So the idea of creating pattern decorator is just to return a value. This is where here we're simply return in full. Now let's try to use it. We didn't write any logic now, we just want to bind it. This is why I will jump inside our controller. And here on the bottom where we have our request. We can additionally to our request, use also other decorator which is called user. Here inside were not provided anything. And here I will say user any because we didn't even specify what we're getting back. And now we need to import this user. So as you can see on the top, we're importing our user from decorators, user decorator. So this means that now we just created a decorator and passed it here. What I want to do now is write console log user, and here will be our user from the decorator. Now let's check what value do we get? As you can see here, we don't have any errors. Let's jump inside. Postmen hit Send. As you can see, everything is working, no changes here. But now in the console you can see user foo, which means we got a value from our decorator. So actually all params decorators and our custom one also, I get an access to the full request and can get some information from there. Which actually means decorator is simply a sugar to work comfortably with request. Now let's jump back inside our decorator and dried better logic. First of all, the question why I wrote here data and if we will open here on the right controller, we can provide inside the user decorator some stream, for example, AD. And actually the idea is that here we can get back the whole user. So this is current user. Or we can get specifically only a single value. For example, the AD of this user, which actually means that data can be undefined it if we don't provide something or it can be some value to get from the user. The next question is, what is context? And actually contexts is an execution context. You can see it from datatype. The main point is that from execution contexts, we can get, for example, our request. Here we can write that we have a request. This is our contexts dot here we need to write switch to HTTP. And then dot GET request. This you saw there were also functions to get response get next, which actually means work by flexible here. Now we can do something whatever we want with this request. And actually what we want to do, we can say here, if our request user does not exist, then we want to return here. Now, in this case inside our decorator, we simply get now if we don't have any token over, didn't get the user inside middleware. Now, after this, we can write if we have data, and this means that we specified some property to get it nested from our current user. Then here we want to return request dot USA data, for example, data is AD. Then here we will return a request user ID. And last but not least here we can return the full user. So here will be request dot user, and we don't need this return full. So actually, as you can see, decorators are just sugar for us. We don't want to write all this logic every single time in such controller. This is why we're moving all this logic inside the crater. Here we simply return null or we select some data, or we return our user. Let's check how it works. So here we're jumping back inside or user controller. And as you can see here, I have user. Let's check if it's working. I am running the request inside. Postmen were checking the console and as you can see, regard our user entity from our user. And actually now here we can say that this is our user entity because we're sure that here we will get Houston and they know what you want to say. Now, it is not clear that we will get here. Always say user, because I wrote inside the decorator that we can get here now, and you are totally correct. This is why in the next video, we will talk about gourds. We will make our controller so that here we can't really get now and we can get on user. But this is the topic for another video. So for us it's important that we can write here user, user identity. And instead of request user right here, just user. Now we can reuse our decorator everywhere to get a current user. We can also write here ID just to get on with the ID of the user. So here let's check this. We're starting here, our web server. We're jumping to the postmen. We're not getting all fields because we didn't provide correct information inside service because they got just an AD. As you can see here, user1, where getting here only the number which is NAD, which actually means that we can read directly just a single property if we want to offer our currentUser. But in our case here, of course, we don't need to provide anything and we're must pass our user inside here. Also, we can remove here request because we're not using it anymore and we simply use our user decorator. 21. Auth guard: In one of previous videos, we'll learn about middlewares. They said that there we can do whatever born with requests, and we actually can throw some errors. For example, when a user is not logged in, just to remind you, here is the code of our OS middleware. Actually here we're not throwing anything. If we don't have current user, we simply set it as a. Now, this is completely correct because we're using this middleware everywhere on every single route. But sometimes we want to throw an error. For example, here, when we're talking about our user controller, we have here get current user. And normally if you don't have token, we want to throw an error for 01 Unauthorized. The question is where we want to pack this logic. And the next years we have amazing thing which is called words. As you can see here, we just need this picture. So we have client-side like front-end, then we're here, we should appear request and then we have word before it hits our route handler. You might task, What's the difference then between middleware and weren't? Actually the point of word is simpler to create, can activate function, and nothing more. Middleware is much more flexible because you can do whatever you want there. You can use middlewares as quartz. But I highly recommend you to put the logic regarding roles or access inside girls, because this is exactly the purpose of squares. In this video, we want to create our R-squared, the pointed that we can use it only in the places where we really want to throw the error. For example, here in this request get current user. We really want to throw an error if our user in this request is not logged in. Just to remind you, we have middleware in every single request. Which means the only thing that we want to do inside world is check if we have a user inside the request because gouache will be called after middleware. If we don't have a user, then we're throwing the error. Let's do this now. For this inside source users, we can create a new folder and call it gourds. And here we will have all our boards which are related to our user module. Let's create here our word dot ds. So the idea of this is just to throw 401 when the user is not authorized. Here we want to expert class, and here we have our word. And here we have implements of can activate. This, you can see can activate is coming from Nest chess. And here we're getting that we didn't implement it correctly because we must create, can activate function. And this is exactly the goal of our Lord. And of course here we should not forget our injectable or we will have magic errors. This is why here I am adding it. And now we must create here our can activate function. So here I am writing can activate. And as you can see, we're getting context again. We're already worked with context inside our params decorators. So actually this context is exactly the same. This is our execution context. Now back we're getting Boolean because connective eight regions, either true or false, and false means that we don't have any access. First of all, here we want to get our request just like we did previously. So here is our request, and here we have contexts, then switch to HTTP. And here we have GET request. But the problem is here that GET request will return the request of the Express and we want our updated request. So here we need to provide a correct datatype and we can provide here are express request. In this case inside request we will have our user. Now here we can write if request dot user, so we have a user, then we're returning here through this, you can see we don't need to do anything with requests because we already have used inside because middlewares I have been in before our can quiet. Now, if we don't have user would want to throw an arrow. Here will be thrown new HTTP exception. And inside we're passing our message, for example, not authorized. And as the second parameter, of course, our status code here will be http status dot on the thrust. And unauthorized is 401, which is exactly what we wanted. And actually we're already implemented the whole world fast. This quite checks if we have user inside request. If we have it, then we're returning true. If not, we get an error. Now, we must registered inside every module, where inside controller we want to use this squared. This is y here we must registered inside our user module. So here inside providers, I am right in our world. Now, we just need to use it inside our controller. So let's jump back in. User controller here is our get and we can write here and you decorator use gourds. And inside we must provide our outward. This is y here I'm simply write an outward without round brackets, just like class, and then just save it. And as you can see on the top, I have input from USC words and import of my outward. This is exactly the line how we can add our guards to this route. In this case, first of all happens middleware to get current user from the token. Then we have here u squared and this u squared inside will either return true, so we're coming here, or we simply throw an error. Let's check if it's working. I'm jumping in our web server would don't have any errors. Now let's try our postman. I'm hidden sand, and as you can see, we're getting back our request as normal, which means we're past our GE worth and everything is fine. But if I will break this token, for example here I can remove token completely hidden sand, as you can see where getting status for 01 unauthorized. This is exactly correct because we're born for our request to return 401 if we're not log-in because we don't have token sober control the return current user data. As you can see inside NESDIS, we have a lot of different entities that are already prepared for us and we can just tune them a little bit. Then our code is really super easy to support and understand. As you can see in a matter of seconds, we can first of all protect our route and not only here, but in every place of our application. And then if we have our user, we can use it and get it with our decorator user. 22. Updating current user: In this video, we will implement the last method of our user module, and this is updating of our currentUser. Let's have a look here. We have our spec update USA and our request is slash api slash user. This is put because we're updating it. And here is our request. Actually inside we have a property user. As always, here are only three fields that we can update. Email, biography, and image. As you can see, authentication is required and we're returning back user. And I think that this is a nice small feature that you can try and implement on your own. And as always, we have three levels. First of all, is hard if you just want to try it by yourself without my help or guidance, just pause this video and try it. Now, the second level is medium. So here are some of my advice is actually what do we need here? We will create inside our controller, new method was put to update our current user. The most important part here is the line authentication required. This actually means that we can simply use your squareds outward because this is the word for our authentication and visit. We really know that only authenticated people can come to our request. Secondly, verb date in here, current user, which actually means we don't need to get a user from the database because we're already getting it through this user decorator like we did previously inside get. But of course we must create a new method inside those service where we will update our user. And last but not least, we must create a new DTO for update. Already created a detail or four create user. And here for update we have another D2L. If you want to try and create this feature on your own, then pause this video now. And here is the easiest level. We will just create it together. First of all, let's start with creating our DTL. This is why I will jump in user slaves DTO. And here we have our create user detail. In this case, you can actually copy paste almost all fields on our new update user detour because it will look exactly the same. And actually I will copy paste everything because I don't want to type it again. We're already did that. You already saw how we're creating it. So our idea that here I have expert class and here is update user determine. The question is, what fields do we meet here? First of all, is of course, username, email, password, password we don't need. And here we also need read-only filled for biography. And this is a string. And last but not least is of course, image. But here is an important point. As you can see here, accepted fields are e-mail, username, password, image, and biography. But they're actually not required. And it doesn't say here that we have any validation. Here we don't need any checks for is not empty because we won't validate our detail. Here. We simply have our update user details with these four fields which are specified here. And they actually, as you can see here, we don't have a username, but in all APIs that I saw previously, username is also implemented. For example, here in Angular railroad diode. This is my settings. This is exactly the update of my current user. Actually this second field use the username. Here. Obviously I can update my username. Passwords should not be blank. We must provide the correct password. This is how it works on the real front-end. Now, let's create our controller method. This is why I will jump in our user controller. And here on the bottom group wanted to create new method. And we'll know that this is a put and this is a route for slash user. This is why here we have slash user. And now we want to use here our required for authorized access. So here we're just providing our GVD and we're good to go. Now here we have our method and we can name it, for example, update or update current user. I really like longer names because it brings you some understanding because we will update. It's not clear what we're updating. Here inside. We're getting two things. First of all, we want to get our decorator user. This is to get our current user. And here we have our user, which is our user entity. So this is the first parameter that we need. The second parameter is our form, which means detour, which means this stuff that we will send inside the request. Here we want to say that we want body and from the body would want to read our user and would did exactly this here on the top. For example, when we created user and here we have create user detail here inside body where bison, that this is update user details. Of type update user detail that we just created. And we know that bank who wanted to get our normal user response. This is why here I am writing this promise of user response interface. Let's close that for now and save. As you can see, we don't have any errors except all of that. We don't have any body here inside our function. Now, the question is what we will implement here? And actually the idea is exactly the same like with grade. We're calling update, update returns for us a user. And then we want with the help of build user response to get the correct response. Which means here is our user. And we have a method way to this user service. We will create a 22nd and inside, for example, update user. And actually as you can see here, my method is called not update current user but update user. Which means we can prepare this method is really reusable. We can update any user opposite, and it actually makes sense. But this means that we don't need the full user here, but just NAD, because here we are getting our AD, for example, current user ID. And we know that this is a number. Now inside here whereby sin ID and our update user do turn. In this case, we're building our function not just for current user, but for any user that we want to. We can update any user by this CD and these details. Now after this, we of course want to return our user service dot built user response and we're biasing inside our AD. So as you can see, our code inside every single action is looking really similar. Now we just need to create this additional method update user inside our service. So let's jump here in User Service. For example, here somewhere on the bottom. For example, before generativity, we can create new method update user will know that here we're getting user ID number and here will be our update user details of type, update, user duty on back, we're getting our promise of user entity. And our user entity is the same user as always. Now what we want to do inside is first of all, find the user by d and secondly, updated with our user detail. Here we can write that we need to use and we can call here a weight, but we're already created method find by ID. So we actually can use this method or directly this user repository find one. It doesn't make any difference. But if we already created the method, let's use it. This is why this find by ID. And inside we're biasing our user AD. This line will return as a user, but actually of course we need to write here, I think in other case, it won't work. Now we've got our user, and here we want to overwrite properties of this user with our update user detail. For this, we can use object assign. Here we're passing. First of all, our target will be user and our source will be update user detail. Because first of all, is the object wherever we want to update the fields. And secondly, what fields were born to update. This mutates our user. So we're not creating the UE user, but we're mutating this object. Now, the only thing that we must do is to save our user again. Here we are updated all fields, and now we can save this user and return it back. This is y, here is a weight, this user repository, and here we have dot save wherever biasing our user. And actually this safe, we will update our user. And for this we of course must have inside ID. As you can see, we implemented our whole update user method in stream lines of code, which actually means type eardrum is super strong together with Nest years. Now let's check if it's all working. As you can see here, we're getting some errors inside user controller, can't find name ID. Let's jump here in our controller on 57th line, and here is of course not ID, but current user ID. So this is the correct name. Now we don't have any errors here actually, we must import put on the top who didn't do it before. Let's jump now here as you can see, everything is green. Now let's create a new method. So actually here we already have three of them. Now we want to make a put for our user and we must provide here a token because in other cases were born bit logged in. Now we must also provide a body, because in body, we're providing what we want to overwrite. For example, let's override here a field biography. This is why I'm providing here biography. This is my biography. And I'm hitting sand here. And as you can see, if we got back our new updated user, we got all information like your should be also restocking, which is important for us. And here inside biography, we're getting this updated biography, which means our code is working correctly. And in thrill lines, we implemented on your service method where we can update any user that we want. And actually this we're all methods that we must implement inside our user module. 23. Creating article module: In this video, we will start a new section of our project because we fully finished our authentication module. Don't use section is article. Actually we have a lot of stuff to do regarding article. We can create article update, article, delete article, like dislike articles and so on. So there is a lot of stuff to implement. But in this video, we'll need to create our basic molecule and service for our new module. This is y. Let's jump inside our editor and create here in source new folder where we will store our article. Here is our folder article, this is our new module and all logic regarding our article, we will pack here. First of all, we must create article module.js if you don't remember how to create modules. So controllers, you can look in our old code or for example, user or 10. First of all, here we must expert our new class. This is article module. Here on the top we need our module, sorry, not in g, But just a module here inside. We must provide our controller later. But for now we can simply say that we don't have any controllers. The next step is to register our article module inside app module. This is why we're jumping inside app module and here inside in birds, where input in our new article module. And don't forget to import it on the top. So our module is there. Now we need to create a new controller. Here let's create a new file, article dot controller dot ds, where we will have all our actions regarding our article. So let's jump here and we want here to expert article controller. On the top, we want here a decorator controller. The most important for us that all our requests with political, our starting with the word article here in our schema, we can check how it looks like. So here is a single article. As you can see, we have lots of fields and all these fields we must implement inside our entity. Here we have a lot of APIs like slash, api slash articles to get a list. And as you can see here, we have a lot of query parameters. Then we can get a feed of the article as single article with the slug create article. But the most important for us that always we have this prefix of articles. This is why we can set it once here inside controller and NADH inside every action. Now let's add this controller inside our module. Here, insert controllers, we must register our article controller. Controller is there. Let's create at least one action. We want to implement it just to test that everything is working. What I want to create here first use, of course, creating of the article. Here we can say that this will be post request because this is the Create. And here we will have a cin grade. We won't try it any parameters here or what we're getting back here, I will simply return create article. In this case, we can check the tau code is working. And of course we must import here our post. So let's check, first of all, in web that everything is working. And actually here we must seal logs for our new route. And as you can see here, we have an article controller and mapped slash article post, which actually means everything is working. But let's test this for this, I will champion set postmen. Here we have a new URL, so it will be articles URL and it will be post request here I want to save it and the name will be create article. And it will be in our collection as chess. Let's save this. Now we have District west, this is opposed, and here is our body. And actually if we check here, as you can see, for example, for create will always pack all our data inside the additional article property, exactly how we did previously with user. So here we will have our article and here we can pass whatever because for now we just wanted to check that our controller is working. As you can see here, we're getting back great article, which means everything is buying this successfully. Now, I also want to create a service, because for sure we must create a service for article in the same way how we did for user to write all our business logic inside the service. This is where here I will create our article services.js. So let's jump inside and here we want to export our new class article service. Don't forget that we must write our injectable decorator here on the top. In other case, nothing will work. What we can create here is our new method. We can name it creates article won't implement it, but just return some string just for testing. Here I want to return create article from service. Now we can register this service and use it inside our controller. First of all, inside our article module, here we're masked inside providers use our articles service. So here is our service. Now let's use it inside article controller. For this, we must provide here a constructor, and here we have our private read-only article service. This is of type article service. Now instead of this great article we can use here, this dot article service create article. Now let's check if it's working. We don't have any errors here. Let's jump inside Postman and hit Send. As you can see, we are getting message create the article from service, which means we'll configure service correctly. Now, we must create an entity for the article. And as you can see, this is how our normal article is looking like. So we have lots of fields here like slug, title, description and so on, and even relations. But we will talk about relations later. For now, we will create all these fields except of favorited and awesome. For this, let's create a new file, article dot and dot ds. And just to remind you, we need to export here our article entity. And on the top we must say that this is an entity. Here we're providing additional name for our table name. And here we want to have not article but articles. Now inside we can create all our columns. And of course we're starting with AD. This is y here, there is primary generated column, and this is a DIY of type number. Now the next one will be our first column, which will be slung. The second will be one more column, and it will be our title. And title will be also of type string. One more will be description. Here we can use parameter default, and here will be an empty string. So we already used the default here. We can say that the default value inside this column will be empty string. Here now we have our description of type string. One more will be body. So here we have column default, again will be empty string. And here we have our board is string. And if you are asking from where I am taken all this columns, this is our specification. We're describing all these columns. So after body we have created at and updated it, there is a special notation for a typo RAM to use these two fields. Because actually we want inside to write timestamp of when we created the article. This is why we're writing like this. So here we have a column and here will be created at this is y here we're setting type timestamp. And next we need here to provide default. Default for us will be the default value because actually we don't want to provide it by ourselves, but it will be auto-generated, which is exactly what we want. Here. We want to return current timestamp. In this case, for this column will be used the default timestamp, which means that time when our entity was created. Here we can say that we have filled created ad and it will be of type date, exactly the same we will use for updated at. Here we have timestamp, current timestamp, and here we have our updated at. The next thing that we have is our array of tags. So as you can see here, we have add tag list, and this is array of strings, which means we can provide now a single article when we're creating it, this list of tags. This is y here what we want to do, we want to create new column. Here we can say simple array. This means that inside we will provide some values as an array. Here we can say that we have deg list of type string array. For example, if you don't know how to write some column or what type of data do you need? You're always can open the documentation of types of RAM and check their water possible types you have for columns. And what you can use here was our simple array. And the last one for us will be favorites count. Here we have column and it will be with default. The default will be 0. So y that this is the default number of people who liked this article. Here we're right in favorites count, which is a number. Let's check. We implemented all these fields except a favorited and awesome. Now I want to do one more thing. This is regarding update the tet, and we're already did this code inside our user entity. Here we used before insert. And actually we can do something when we're doing insertion, for example, in this case, we wanted to hash, our passwords, were also want to do here something but with updated at actually every single time when we're updating the record, we must update updated at filled and it won't happen on its own. We must provide it here. So this is why we're saying before update. And this will be a Kohlberg. When we're updating the record inside, we want to provide update timestamp. We can name it how we want because this is just a function. And inside we want to say this updated ad, this is our property equals new date. We're just saving current date inside our updated at at the moment when we're date in the record. This we're all fields that we need for our article. Now, it is time to generate migration and check if our table will be created. Just to remind you, we can always jump to package JSON and check our scripts. Here we have dB drop to be created db migrate. Actually to create a new Migration, we need db create. This is y. Let's jump to the console and try it here, yarn db create, and here will be our name. And actually here we can name it create articles. Let's hit Enter. And here is our new migration. As you can see, it analyzes the migrations and our tables that we have and create a migration. Let's check what we have here, resource migrations and here risk create articles. As you can see here is our Create Table articles with all properties that we created. Here is of course, drop table articles if we want to revert it. Now let's try and apply this migration for this, we need to write Young db migrate. And actually we should not get any errors because we don't have this table at all. As you can see, we don't have any errors. And here this code was executed. So create table articles, In which means we're getting in your article table. Let's check this out inside PSQL here I can write d t, and you can see that we are getting your table articles and here we can write d. So describe articles to check what fields were having inside. Here is ID, slug title, description, body and so on. And we can see that for created at and updated at, we have here timestamp, result Time Zone. This is exactly what we wanted. So actually we successfully created our base module off article, and now we can implement new methods. 24. Creating article method: In this video, we will fully create, create article method. And actually it will be super similar to our method of create that were used for registration of the user. We need a method inside controller, will need a service method that we'll do insertion inside our database. And of course we need our detour to have a payload of creating an article. Here I will jump insights source, article controller, and here is our create method. But we have here something interesting. Actually, if we will check the specification, you can see that for create article or authentication is required. So actually this means that we will have here user ID and result this user ID. We can't really create an anticoag because article must belong to one user. Which actually brings us to the topic of relations, wire relations, because we have now relations between tables. First of all, we have the table of the users where we have, for example, NAD and the name of the user. And we have a table with the article. When we're creating an article which should not only write their ID of the article and some information, but additionally, we must store in every record of our article, the user ID, which is the owner of this article. This stuff is called relations and normally ORMs somehow give us possibility to implement this quite easy. And actually in last year's will also have relations. Let's look how we're doing them. First of all, we must inside our article entity and user entity describe this relations. Let's start with our user entity. We must jump inside user and here we have user entity. Here we have before insert and after, we want to describe that one user can have many posts because one user can create a lot of posts. But actually one single post can have only one owner. This is why only one user. This is exactly what we want to write here. And actually I must say here that what we are writing now with relations is the part of typer room. And it's not written in Super understandable way. You just need to accept this. And maybe it could be based from documentation every single time when you are writing relations. This is how it looks like. So here we have a relation, one too many. Why? Because here we are inside user and we have a relation with one user and many articles. Now inside as the first parameter, we must have an arrow function here. And we're returning our article entity. With such notation, we're saying that our user can have multiple article entities. Here as the second parameter, we have article as an argument, and here we're returning article dot awesome. So actually now inside every single article, we can write article.org to get our awesome. This is really convenient when you don't want to really additional every single time, find the user by ID that we will store in a second. But we can simply write article dot author. And because of the sugar of type I error, we will get it back. Now here what we can write is articles and here is to go entity. So actually this is how you are creating the relation from one-to-many. So you have one user, a lot of articles. And actually I can't say that this all notation is super clear for me. I just took it from documentation and used in all my projects. You can simply always google typo RAM relations here reserve official documentation and as you can see, where interested in one to many. And when we are jumping here, we can see exactly this examples, how we're writing it now from the side of his overwrote everything. Now we need to define it inside this side of our article. This is why we're jumping inside our article entity. Here on the bottom. We'll also must define it here. So what we want to say is many-to-one, because we have a lot of articles and they are belonging to a single user. Now inside here we also have an arrow function where we're returning user entity. So actually our user entity is an ulna. Now here we have this user as the first parameter and we're returning here user dot articles. And now here we can name this field for example, or some, and this is user entity. In this case, we can say inside every single article, article dot or so, to get a user. Or inside the user, we can say user dot articles to get all articles of this user. So this is how you are creating relations between two entities. And as we made our changes for both entities, we're must create a new Migration. This is why I'm jumping here inside console and then write in Yandi be Create. And here we can name it. For example, add relations between article and user. Yes, the name is quite long, but actually from the name, we can really understand what is it about. Here. As you can see, we are getting on your migration. So let's check how it looks like here inside source migrations. This is our new migration. And as you can see, this is the most important line for us. So alter table articles and also ID integer. This means that now inside article table we have a new column and it is called author ID. This is why in every single record that we're creating, we're must provide this also ID because we have this relations. Also important part for us here is that now we have a foreign key or society and reference to use a table. Also, as you can see here, we didn't provide any actions ON delete or an update, but actually we can do this and then Postgres will automatically fast do something between these references. So our relations are there. Now we must do migrations. This is why Yan db migrate will make great our database and bring it to the latest state. Now let's check what we have inside our DB. The interesting part here is to write, describe articles. And as you can see here, that the main difference we have here in your property, which is author ID integer, which means now when we're creating an article, we will store here are awesome for us is also important that here we have a foreign key author ID, and it references users ID. You don't need to do anything with it. But this is how it's looking inside Postgres. Now, we're really ready to create our action inside controller. Let's jump here back inside source article, article controlling. And here we have our create method. And actually if we will check here in the documentation of great article, you can see that we again have somebody lot, which actually means we must create a new duty or file for this payload. This is why here I will create a new folder DTO, exactly how we did previously inside users. Here I can say Create article dot d t dot ds. And here we can create our new detail, our class. So here we have our class. This is great article detail on the inside we have four fields actually titled description, body tag list. And three of them are mandatory title, description and body. So it stays here, which means we can say that they are required. This is why here we have a read-only title and this is strain. Now here we want to use a decorator is not empty. Now here we also have these not empty. And here we have a read-only description of type string. And one more will be is not empty. And here we will have our read-only body of type string. And the last one is not mandatory. This is why we're not using here a decorator, but just saying here read-only tag list. And here I want to put question mark because this is not mandatory. And here we have array of strings. This is our article create detail, and now we can use it inside our controller. So let's jump back inside our article controller, and here is our create method. So first of all, we can say here that this action is really requiring authentication. Here under both, we can say use words like we did previously, and here will be our R-squared that we created already in previous video. This year's acquired means if we don't have token, this token can't be parsed, then we're getting 401 unauthorized. This also means that we can safely after the squad use here user from the request because we're sure that we will get one. This is y here inside. Great. First of all, I want to read our user. And actually we don't mean the whole user but just NAD, because when we're creating an article, we need to write inside our user ID. This is y. Here we're using our user decorator. And here we're reading ID, and this will be current user ID. Then not talking a lot about this code because we wrote exactly the same code inside user in previous module. Here we successfully got our current user ID and this is number. The second part that we want to do is parse our body. This is y here will be body. And we want from body to get article property because just to remind you here inside body we have an article. And this will be our create article D2L. Here Let's name it, create article D2L. Actually not with big letter. Here is create article DTO of type create article later on. And actually we didn't create an interface here of our response. For now, I will simply write here any, but we must of course create here a valid response. And dissolve is just to remind you been where hidden on article we have here strange notation. So actually this is our article entity, but we must packet in additional property article. Actually it makes sense to do exactly the same like in previous module and have additional function builds response, which we'll back our article identity correctly. But for now we simply want to pass inside our great article, the AD. So here will be current user ID and dour create articles UTR. This is exactly what we want, but of course here we need a wait to get back an article because here will be a synchronous process. Now let's jump inside the cytosol service create article. As I already said here we have current user ID and this is number. And we have create article duty on of type create articles. And actually back, as always, we are getting promise of our article entity. So just to remind you, we are getting here plain data from database where not normalizing them for front-end. Now here we need to create a new article entity. And if you don't remember here inside the user service, we did exactly the same. So here we have a method create user. And as you can see here, we also had detail. And here first of all, we created new entity, then made object assign, and then simply use this user repository save. We want exactly the same logic, nothing new here. First of all, here we must write a constructor and inject here our repository. Here I am writing inject repository and inside I am right in our article entity. Now this will be our private read-only property, article repository. And it will be a repository of type article entity. Let's close our constructor. Now we have this article repository and we can use it inside created article. So first of all, here we want to create a new article entity. So let's name it article and we're just colon here and your article entity. This will create for us an empty article. Now we want to assign all properties from detail inside this article. This is why we're using again object assign. And here is our empty article, and here we have our create articles UTR. We simply add all properties from create article detail. But the problem is here that our task list can be undefined because it's not mandatory. This is why here we must try that if we don't have article dot doc list, whoop, want to create one which will be empty. This is why here we can simply say article pick list equals empty array. This will create tick list if we didn't pass one. The next thing that we want to do before we will save the article is adding a user ID inside, and we can do it in different ways. First of all, we can simply assign article dot yesterday, but secondly, we can make it easier. So actually we passed here current user ID, but a one just now to change it to current user. Here we can say that current user is actually our user entity. Now let's jump back inside the article controller and change here user ID just to play in user. So here we will have rarely current user or user entity. Now we can directly set this currentUser inside our article here we also need to remove current user ID to current user. Let's jump back inside our great article. Here we have current user and we can say here, article dot or so. And this is the property that we created to make a relation equals. And here will be our currentUser. Why this code is better than just assigning user ID. Because actually here we're leveraging our usage of relations and type RM. Because here we're working with DOT author that was automatically created for us by typer RAM. And we're set in here full current user. And actually type or RAM will save everything correctly fast. Here we saved our author and now we want to save an article. This is why here we can return and here will be weighed. And we're using here are articles repository dot save and bison inside our article that we want to save. Also, there is one more important thing that we didn't do. We must register this type or RAM inside our article module. Let's jump inside article module. And here we must provide in birds and inside we must registered type where a module here is for future. And inside we have an array and web bison inside article entity because we're using it inside. Let's now jump inside console and check how it's working. As you can see here, we're getting an error inside controller that we wrote just any. But here maybe we wanted promise any. And actually this is a valid point because here we have a weight, which means we're getting back a promise. Let's try it for now. Promise any, and we will create a response later. Let's check this out. Here is our web server and it works and we don't have any validation errors. Let's now jump inside postmen. Here is our post for great articles. And here I am just hit incent. As you can see, we're getting 500, which means something is broken. Here to the problem. We have a null value in column slug. And the problem is here that he has, we have a property slog, but we're not passing it from outside. And actually what we want to do, we want to create our slug inside the service. But here I don't want really to implement it in this video. We will do it in the next video. This is why let's just say here articles slug equals four and we will change it later. This is just for testing. Now what we want to do here, we want to make our correct requests. And actually let's jump in create article here is our request, so I will copy it completely, open Postman and paste it here because this is exactly what the valid request. Now let's hit Send, and as you can see, we're getting back the correct data. So here we have titled description, bar detect list. This is what we provided. Here we have our slug that we didn't generate yet. And here we have our author, which actually means that our relation was correctly bind it. And now we have here author. Also we have ID and here are our created at updated at which adjust a normal timestamps. Now let's check in database how it's looking like. So I will jump in pH scale. And here we can dry it, select star from articles. And as you can see, actually the output doesn't look that great and we can't really read it. And actually there is a pretty print inside PSQL. We can say here slash x, and it will enable expanded display. Now let's try again, select star from articles. And as you can see, it is looking much better. So it's not looking like table, but like columns. Here we have our first record and we can see that everything is correctly stored for us. The most important part is here is also Id1, which actually means that this line that we wrote here was correctly processed by type and type where I'm saved inside database on this id of awesome. Now we can always get all articles of how author, or we can get the author of our article. 25. Polishing create article: In previous video, we successfully created our new method, great article, but we're missing here two important things. First of all, we didn't implement inside controller. I will return interface because we have here any. And secondly, inside our articles service, we have this placeholder articles slug, and they actually were must generate here a unique slug. In this video, we will finish these two problems. First of all, let's talk about article controller and this premise. And actually we want here to return the data for the front-end. This is why we need to take this entity. And as you can see here, create articles returns for us article entity. And then we want to just wrap it in additional article property. And we can do it exactly in the same way like we did inside user. Just to remind you, here inside user insert controller, we use the law to this, this user service built user response. So actually we have a dedicated method to build a front-end response. And we can do exactly the same here. But first of all, we must create here and you type, this is y here inside types folder that I just created, we can create an article response interface TS. Just to remind you, I'm trying to make all interfaces in the same way we had user response inside the user module. Here is article response. When naming things are the same. Now inside we simply need to create a new interface and it will be our article response interface. And inside we just want to pack our entity inside the additional property article. This is why we're saying here article is article entity and this is all that we want. Now we can use this article response interface inside our promise, any insight controlling. And as you can see, we are getting here and narrow because this is article entity not article response interface. What I want to do here first is create constant article because secondly, we must create additional function where we will build our response. Here we can return this article service, and here we will create a new function built article response, and we will pass inside our article. Now let's set this function. So let's jump inside Service. And here somewhere on the bottom, we can create a function build article response. Here we are getting as an argument our article, which is an article entity and backward returning our article response interface that we just created. And inside the simpler returning an object with property article, this is it. So actually we could write this code inside controller. No worries. But the point is that we will have a lot of actions here, and actually all our actions must return the same format. So here we have created, we will also have update or get or get filled. All this stuff is returning the article back in additional article property. This is why it makes sense to create an additional function here. And of course we must resolve here article response interface and import it here. We covered all our datatypes correctly and we're good to go. Now we must implement our problem with slugs. So actually, as you can see, an article service here we have articles slug. The point is that we don't want to provide article slug from the frontend. We must generate it on the backend after creating an article exactly here. But the problem is what is slug normally it is dashed or underscored version of our title, for example. And actually I highly recommend you to use a popular package and not reinvent the wheel. This is y. Here is the package slightly phi, as you can see, it's really popular. And the main idea is that it correctly transforms strings inside slugs. And actually we should not worry about other languages or career like for example, symbols, UTF eight, whatever you can imagine, you simply use Liquify, you throw inside some title and then you are getting back a slug. Also here we have some options. For example, we can convert everything to lower, or we can replace spaces with dashes or underscore or whatever we want. And of course we can save here located. But for us it's really simple. We just want to use it and transform to lowercase. But the main problem is here That's liquefy, doesn't know anything about uniqueness of our slugs. And actually every slug in our project must be unique because this is how a unique identifier. This is why we need to extend it a little bit. First of all, we must install this package. This is why I am champion and said console and try it in yarn adds log of phi. So this will install our package. The next step is to chump inside our articles service tiers because we want to use it here. So here we're in Bertin slug e phi for Rome sluggish Phi. This is fine for us now we must use it. But the main problem, as I said, that it must be unique. And the question is how we can make it unique? And actually we can just generate some unique theme and add it to our string that was generated by slightly fine. This is why I wanted to show in the console how I want to do it. First of all, we can use here math random. And as you can see, Math.random is given us back a flawed, which is actually unique but not exactly what we want. We want to multiply it on math Po. And here we have 366. If you don't know what mass policed, It's a power, which means it returns a value of the number to the power that we gave. This is why here we have four and the power of three. Here we have 36 and the power of six. The main idea is that here we are getting really large number because we want to get here the int. And we can get it by using bitwise, OR this is where here I have pipe 0. And as you can see, we're getting here nice integer which is completely random. No worries if you don't understand this code exactly, you can simply reuse it everywhere. And this is the way to generate unique IDs. And the last step that we want to do with this integer is just to wrap it inside brackets. And right here, two string here, for example, will be 36. As you can see here, we're getting a nice string which is really unique and regenerated this with the help of math random. So I will copy paste fully this line and actually create here additional method that will generate for us unique slug. Here we can say private because actually we don't want to reuse this method outside. This is just for our service. Here, Let's name it, get slug and inside where bison title and the D string and backward wanted to get also a string. Here we can write return and we're using here slightly phi. And we just need to pass a title to this Liquify. So here we have title and some options. I want to make it to lowercase. This is y, here is lower true. Now we want to concatenate it with dash. And then with our magic string. Actually solidify will generate for us nice slug from the title and it will be lowercase. Then we have a dash, and then we have our unique stream. Now we can simply use this function in this place where we're generating articles slug. Here we will have get slug and we're biasing inside from the TOR create article utah dot title. Let's check now if it's working at all. So here we have our web server, no arrows here. Let's jump inside. Postmen is you can see here we provide a lot of information and our title here is how to train your Dragon. Let's hit Send. And as you can see here, we have a slug. We have here how to train your Dragon. This is slug defy. Then we have dash and our unique ID, which actually means our slugs are looking really nice now and they are really unique. 26. Get article by slug: In this video, we will implement getting of the single article. They really think that you must try and do it by yourself because it's not that difficult and we prepared a lot. So let's check what we want to implement. As you can see here, there's our specification and we have get article URL. Here is good for slash api slash articles slash slug, which actually means that this is not a static URL. But here we have a dynamic parameter slug, no authentication required here, and it will return a single article. And you also didn't know how single article is looking like. This is exactly what we want to implement. The hard level for you is just to pause the video and try to implement it on your own. The second level, which is medium, is with my guidance. So actually the question, what do we need here? We want here inside our controller to implement and new method, and here will be get method to get our article. And the only interesting part that we didn't do previously here is getting programs from the URL. Actually before all our programs were stateless. And now we have this parameter slug and we must read it from this URL. And actually inside nest chairs we have a decorator which is called params. When we need to get such parameter which is dynamic from the URL. As you can see inside the creditor per gram, we can simply provide the name and actually it will read request dot params like we have for example in Express were written this program and then by this slug, we can get our article. So actually this means that in our service we must create a new method that will fetch our article from database by slug. If you want to try it by yourself and they highly recommend you to do it, then just pause the video now, and here we have the easy level. Let's implement it together. So actually here we want to create a new method. So we know that this has a getMethod. So we're right in here. Get decorator would don't need any words. And this is just a sinc function to get a single article. This is why I will name it single article or actually get single article. It doesn't really matter what we want inside. We must read a parameter from our URL. This is why here we will get per gram decorator and inside we will pass slug by slide because actually here we have this unique slug part. But now of course the question how unless JS knows that this is dynamic parameter and actually we must provide it inside get. To do this book can provide inside get colon and then slug. In this case, we're saying that our URL is slash articles because we defined it in our controller. And after articles we have slash slug because here we provided colon slug. And then this params slug is exactly what we provided here. Here we've got our slug and we can say that this is our slug of type string and we'll know that back. We're getting our article in the same format like always. So here we have our premise of article response interface. So it is wrapped inside in additional property article. Now inside here we want first of all, to get our article. And for this we need one more method from our articles service and we can name it, for example, find by slug inside wealth by sin, our slug. This line we will create in a second. But afterwards we want to use our this article service built article response variable bias our article. So actually this line we're already used instead create nothing new here. We just need to create find by slug method here. So let's jump inside our serous and here for example, after Create, create a new method. And it will be find by slug. Now inside we must provide our slug, which has a string back. We will get as always promise of type article entity because we will get our article entity from the database. Now here we can use find one method to find something biofield. What we want here is returned a weight. Here we have our article repository and again we're using find one. We already did it previously. Actually inside find one, we can throw their AD directly or we can throw the object and pass here some fields. For example, we can write here slug field. And this means that we want to find one single record by this slag that were provided. And actually slug is a column inside our articles table. So actually this single liner will return for us a single article from database. If slug is not unique, then it will take the first article that is possible. Now let's check if it's working. So let's jump in. Our web server is you can see we have the error roofer Gordon side controller to import get. So let's jump back inside article controlling. And here I will import our GET. Let's check again. As you can show, a server is restarting and I think we don't have any problems. So now let's check our postman. For this. We want to create a new URL. So here will be slash, articles slash, and here must be a slug that exists. And actually I will take our slug that we just created and paste it here because this is the unique slug and they also want to save this request. This is why Save As and here is get single article and we're saving it in our collection nest Jess, Here is our request. This is of course get and not post body doesn't really matter. Here we're hitting send regard our article which is backed in additional property article. Here are all our fields from database that we saved, which means we successfully implemented our get's single article request actually in a matter of minutes because it was usage of type eardrum and nest js, we can implement our API really fast. 27. Deleting the article: In this video, we will implement deleting of the article. You might think that all our actions actually really similar and yes they are. But sometimes we have something interesting, for example, in our delete method. So actually if we check our documentation, so here we have delete article, which is a delete method for slash api slash articles slash slug. First of all, we have here our dynamic part, This is our unique slug, but the most interesting part here is that our authentication is required. So actually this means that on the login user can do this request, but it's not. All. The point is that only the author of the article is allowed to remove this article. Which actually means that inside a method inside service, we must check if current user is rarely the author of this article. In other case, we don't need to allow this. Let's implement it now. I will jump inside our article controller, and here we will create a new method which is deleted. And this just saw here we have a delete slash, api slash articles slash slug. This is our base euro, so we just need to implement slug for delete. This is y here we're saying slug. And as you can see, actually we have here get with the same string as here, delete. And it's not a problem at all, just because here we have delete and get, which actually means these are two different routes. One with the method get and second with the method delete. Now inside, Let's create an async method and let's name it, delete article. Now the question is what we want to get inside? First of all, current user and secondly, this slug parameter from the URL, this is y here, exactly like here, we will use per gram and user decorator. First of all, we need user ID. This is y, here is user ID, and this will get for us our current user ID. Here I have current user ID and this is a string. And the second thing that I need here is per gram of slag, and this will be our slug of type string. Now the question is what we are getting back? And actually it's not specified here. And normally people are not wait in something here in return, but actually we will specify it later. So here I will just open our function and actually our function is ready. The second important part is to use here a word. Here we want USC words. And here we will have our outer world, which will check for unauthorized. Now inside we just want to call a method from service as we did previously. And actually here I will just simply return the result of this service. Why? Because actually here inside span, we don't have any specification what we want to return. The easiest way. It just not to think about normalization of the data and just throw out what we are getting from our type ramp. This is where here I will return a weight because this is a long process. And here we will have this article service and let's name it delete article. Now for delete article book wanted to provide insight, first of all our slug and then current user ID. So here we have our slug, current user ID. Let's jump inside our articles service. Here. It doesn't really matter where I create a new function. So it will be a sinc function delete article, and inside we first get our slug and second current user AD. And actually back, we're returning here promise of delete result. You may task what is dilute result? As you can see, I'm outer importing it from typo around. And actually it returns an object returned by Delete query builder execution, which actually means that this is the response of type or RAM when we're deleting the record. And you will see how it looks like in a second. But actually this is exactly what type or RAM returns for us when we're deleting something. The next step here is to find that article. You might task why we need to find the article if we already know that slug is unique and we can just remove a record by slug. You are totally right, but we must fetch an article. First of all, to check that this article exists at all. And secondly, to check the author of this article. This is why here I will write article. Here. We can use this fine by slag. And just to remind you, we already created this method before, this is simply find one by slug. Here is our article and the first if here will be, if we don't have the article, then we want to throw new error. Here as always, we have should it be exception? Here we can provide some stream. For example, article is not found or does not exist. And second livable provide here status. So here we will have HTTP status dot naught found. It will be 404. So this was our first check. Our second check is to compare our current user ID with author ID, and this is really easy to do. We just need to compare here article dot or dot ID. This you can see actually here we have directly author on the article, but for some reason it's not there. Let's check this out. If we will jump in article entity. Here we have this many to one relation, and here we have user articles. So this was for user. Now when we're jumping back, here, we have our relation between user and article. But the point is that by default, if we're just getting an article from the database, which just get an article with don't get article with all relations. This is why we actually can specify here inside configuration that we want to always get an author when we're get an article automatically. First of all, this is really convenient for us. And secondly, if we will check all responses, for example, here inside article, you can see that we always get an bag, this also part, and actually this part is our relation. And this is really easy to do. We simply need here after the second parameter. So here we have many-to-one first function, second function, then here is coma. And we're saying here, eager through this option means that we will always load automatically or so for our article. And actually you even don't need to open documentation. You simply can highlight here, award and check what is it about. So as you can see here, eager relations are always loaded automatically. This is exactly what we want in this case. As you can see, our error is not gone at all, which actually means I wrote something not correctly. We're getting here the problems that it does not exist on type promise article entity. Actually here I simply forgot to write a rate. This is why here we didn't get back our article entity, but we got previously a promise. So this was actually the problem. But in any case, this eager true when need for all our API responses. This is why it's good that parotid. Now here actually we need to write not a rate, but simply IV article author ID equals. And here we will have our current user ID. We simply compare these two ideas. And as you can see, author exists on type article and this is our user entity. This is exactly what we want. So actually if they are not equal, in this case, we want to throw the error inside. If I will simply copy paste this throw because we just wanted to throw an exception. And inside we can write u, r naught and awesome. Here we of course will throw forbidden because in this case we want 403 and not 404. So actually we checked all are exceptions and now we can simply allow to remove an article for this weekend. Return here a raid because we're making the request. And here we have our this article repository and here is the method delete. And as you can see, we can give insight accurate area or NAD. In our case, it doesn't really matter because we have both here inside article, we have an AD or we can delete by slug. Actually here we can write like this and this will be removing by slug. And here inside we can provide whatever options we want. But for us, slug is unique identifier. This is why it will work correctly. One more problem that I see here, I forgot to write here that current user AD is actually a number. Now, we wrote everything correctly and now we can jump back inside our controller. So as you can see, inset controller, everything is working here with our delete article. As you can see, we're passing in set current user ID and it is read and it is red because here we specified that it should be number inside. But here for some reason I wrote the string. Of course, current user ID is always a number because all a decent sized portraits are numbers. Let's check if it's working. As you can see, no errors here. Let's jump inside postmen. Here we have an article with our slag, so it exists. Now, I want to make here delete and make of course save as here, we will have our delete article. Let's save it inside our next chess collection. Here I'm saving it. We have delete. We should not provide anything except of headers. Here the token is important because we must be login. Now let's hit Send. As you can see, this is our response. Here we have raw and effect. It actually affected means how many items were deleted. And actually for our delete, it doesn't really matter if we give any response or not. But here it was easier to simply specify the same stuff, but we are getting from typo RAM. And as you can see inside Service, this delete result is exactly what we got here, so it was wrong and affected. Also, let's check if, for example, our board is working correctly, or at least any of other code. Here, I will simply type something so our slug is not valid. Now I'm hitting sand and as you can see, we are getting the message status code for 0 for message article does not exist. As you can see, our condition here is completely correct and we're throwing an error when our slug is not found in the database. 28. Updating an article: In this video, we will implement updating of the article. And actually it will be super similar to our great article and delete article. This is why I highly recommend you to try and build it on your own because it is super beneficial for you. And as always, we have here three levels of complexity. Level one, you are just implemented by yourself. So let's check this out. Here is our spec update article. We have a PUT request to slash api slash articles, and here is our unique slug. This is the example of the request, and as you can see, it is a little bit different to our Create because here it didn't provide all fields. We simply provide a single title. And as you can see here, authentication is required. We're returning updated articles. So the same response as always. Here are optional fields, title, description, and body. So actually this means that we should not provide even all fields if we don't need to, but just optional fields that we want to update. The main problem is here that I really think that this is a bad approach because this is really bad for the front-end. Why? Because normally you have a form in front of you and you're creating an article and you are getting this validation messages, this is completely fine, and it is exactly how it is inside spec. Then when you are inside update form and you are removing fully, for example, a title, then you are hidden update and you don't see any validation. It simply closes the form and show you the article which was not updated. This is not a good UI because from my perspective and from all normal projects, your grade form should be consistent with update form and actually all validation messages must stay the same. This is why here we will implement not optional fields, but all fields are required in exactly the same way how they are required for create. And actually it won't make any significant difference. And all front-end projects will work correctly. If you want to try and do it by yourself, just pause the video now. Level two is my guidance. So actually, as I already said, were born to make all fields mandatory. Already created in D2L, this create articles deuterium. And as you can see, this old fields are already there. So these three fields like titled body description are already mandatory. Actually, we can either rename this dto or simply use it for create article, the same detour for update and implement creation. So as always, we must implement new action and new method inside service. And actually for us, the interesting part, first of all, we must through this slug. Secondly, we must read a current user ID because authentication is required and we must check if we are allowed to update this article. And of course we need to get an article body which will be detailed. If you want to try and implement it by yourself, just pause the video now and try it. And level three, of course, let's implement it together. First of all, I will jump inside our controller. This is article controller. And here we want to create update article. This is y, here will be put and here I will also write slop because this is our dynamic parameter. Also we must use here u squared because this action is only for registered users. Inside we're passing our outward. Now we have here a sinc function update article, and we need several things. First of all, user ID, because we must get a current user ID, we're doing exactly the same like we did for example in delete. The second one is slug. So here we have our program and here is our slug, and we will create a local parameter slug of type string. The last one here will be our body. So our detail, and we can write here update article detail on here. I will simply write great article Detroit. And it may sound like a little bit not valid because we're using detour for create inside update. If you don't like this approach, you can always rename this great article duty to, for example, persist article. So it will be genetic between create and update, but it doesn't really make any difference because this is simply our class for validation. Now what I want to do inside is first of all get our article. Actually the result of our update method is as always, our article. Then we want to pack it inside our normalizer function built article response. So we're creating the correct response for our front-end. This is why here we have our article and we're calling await this article service. And let's create new function update article where inside we must provide first of all, slag, secondly, update article detour and of course, our current user ID. And after this we can call here a weight, this article service, build articles response. And we're bison inside an article, exactly how we did previously. Let's save this and jump inside our article service. Here we have our delete. Let's create a new function and it will be our update article. First of all, we're passing here our slug. Then secondly we'll have update article details of type create article detail on. And last but not least is of course current user ID, which is actually a number. And I again wrote it like string, I think. So let's check this out. Here is our current user ID. Yes, I wrote here number, everything is fine. So these are our arguments and back we're getting our promise because it is a weight. And inside we have our article entity, which will be our updated record. And actually here we can copy paste code from our delete. Because actually we want to get an article from database by slug to check if it exists and to check if we're an awesome because only an author can update the article. This is why we can simply copy paste these three lines because they are identical. Here. First of all, we're fetching this article from database. Then we're checking if it exists. If not, we're throwing the error and then we're comparing the author ID with our current user ID. The last step here is to update our article and save it. This is why we can write here object assign, like we already did previously. And here we're calling assigned method, and here will be our article and we want to override some properties with update article determine the main point is here that we don't care what properties are inside, which actually means both variants are fine for us, either optional fields. So these three fields are just what we passed or all fields it will work in any case. Here we updated some fields inside our article and now we want to save it again. So here we are returning a weight and here is article repository dot save, and we're passing inside our article. So this will update our article correctly and return our article entity. Now let's check if it's working. So I'm jumping here. As you can see, we have some error. Cannot find name put inside our controller. For sure I forgot to import it. We are jumping here. I remembered to input. Let's check once again, as you can see, we don't have any errors. Let's jump inside Postman and try to remove an article. The main point that I think I don't have any articles. Let's check this inside database. So here is my PSQL, I am right and select stuff from articles. And as you can see here, we have one article and the slug is full, so we still have one article that we can update. This is why I'm jumping in and said Postman, here we have slash articles slash foo. This will be pulled and they want here to Save As update article. Now here let's save it inside nest GS collection and dried correct body. Just to remind you how body is looking like, this is article field width for example, title, and we made actually all fields mandatory. So let's check this out. I will jump here inside, right, Just article. And inside of article we have, for example, simpler title. Here I will write bar. Let's hit Send. And actually we are getting here update, which means we didn't validate all our duty or that were created. And this is totally correct because we didn't try it. Validation of detour here inside our pool. Just to remind you here inside Create we have a validation pipe. Actually we forgot to write it completely. This is why here we have only Guan's button, not a validation pipe. And for sure we want to validate our request, like create and update. This is why here I will write use pipes and inside we must provide new validation pipe. And let's just call it out with round brackets. And we need the same code inside our update, for example, under guards. Let's check it once again. Here everything is fine. I'm jumping into Postman and hidden sand. And as you can see again, no validation. I really miss something. Yes, I can see here what, as you can see here, we use two decorators to get a user and to get a parameter. But here we didn't write any decorator, which means actually this code is not providing a tone. This is why it's not working. What we want to write here is our body, because we want from our body to read article property. And in this case, it must be correct. So as you can see, no errors here. Let's check again. I'm hitting sand and here are our error messages. It is super important that you are getting correct information from the URL. As you can see here, we have all three validation errors because this has the same fields, like inside Create. Let's provide them now here we have our title. I don't know what title was there, but I think not this. Then we want to update our description. Here we have, for example, bar description. And the last one will be body, which is Barr body. Let's check this out. I'm hitting sand and as you can see, we don't have any errors. And inside we have our new title, new description and new body, which actually means that we successfully implemented our update and of the article barred, you should be really careful when you are right and thins inside controller because it is really easy to miss a decorator and then it just stops working. 29. Creating feed: If you've watched all previous videos in this course, then you probably already mastered create an update and removing entities and finding them. So actually you have enough knowledge to create your own modules, your own actions, and create tables for this entities. This is why starting from this video, we're going in more advanced stuff. And in this video, I want to implement our feed. Let's have a look. Here. We have the URL slushy by slash articles. And actually this URL just returns the array of our articles starting from the recent articles. But there are a lot of query parameters. First of all, we can filter them by tag and actually just to remind you, but already created tags, then we can filter by author, will already have author. We can filter it only by favorited user. We don't have this functionality yet. Then we have of course, limit and offset to handle how many articles we want to return and what offsets and skip would have. Also authentication here is optional, which means we can return this request for not logging in users. Now the question is why I am thinking that this request is interesting because we can't really implement it easy. We simply using repository like we did previously, because we have here a lot of different parameters and we can't write a simple usage like for example, find the find one because a lot of conditions here. And normally if you want low-level stuff where you can configure everything we're using for this select query building. As you can see, this is the link to the recommendation of types of RAM. And as you can see here, I opened select using query builder. So actually the idea is that what we're using this type of program to select the data is query builder. So we're building our queries for database. Let's have a look on a simple example as you can see here, we have connection then Git repository. Here we're calling Create Query Builder. We're not using repository as previously, but we're creating query builder. And after we're calling this function, we can use a lot of different stuff. For example, where when we want some condition, in this case we're saying here where user ID equals AD and here we're bias in the data. Here, then we have such SQL query. And of course this is really nice if you understand the scale queries. But the idea of typography is that we're thinking less about our SQL queries because we have a nice wrapper, just risk plane methods where we can define what we want to get. This is why we will use here Create Query Builder to make this request. So let's get started. First of all, we are jumping inside our article controller. Here on the top, I will create the new function y on the top because they actually, this is the first function. This is find all OR gates and feed. Actually here we have a get and this is good for our articles. Now inside, let's create the function find all here. First of all, we want to get user ID. The beginning. We don't need current user, but later we need to understand if we would like to the article in the list or not. This is why I will from the beginning pass here our user ID because we need it later. This is our current user id of type number. And the second part that they want to get here is query. What is square? This is an object result very params, as you can see here, we're working with queries. This is why here we have this question mark. Everything that is going after question mark is query parameters. To get query parameters where using query decorator, we're simply type in here query and then we're getting the object with all our parameters. And of course we can get a single parameter if we will provide it inside. But actually in our case here, we want to get all parameters. This is where here I am creating local property query and they actually it is of type any. And actually book could type our query because we really can't specify what query parameters are allowed. But for now I will simply write here any, because actually people can throw any parameters that they want inside here. Now back, we must return in your response. So actually let's check what we are getting back here. I'm hitting multiple articles. And as you can see, the idea is that we don't have here property article, but articles, and this is the ray. So this means that here we want to create how you interface and let's name it articles response interface. Now inside we must call a function from our service. But the point is that service will give us the data in this format. As you can see, first of all, we have here articles property and this our articles. And after we have articles count, this is our total articles count which we need for pagination. And actually here we will create a method that will already normalized and prepare data. Because here we won't have additional function like we had here with this built articles response. This is why here I will directly write a weight and here we will have our this article service. And now let's create here, for example, find all function wherever bison our current AD and query. The next step is to create this articles response interface. For this, I will jump and say types and create articles response dot interface, dot ds. Here let's create our new interface. And this is articles response interface. Now inside we have two properties. First of all, it has articles. This is the array of our articles. Here we have article entity, an array. And after this we have our articles count, and we'll know that this will be a number. This is how in your article response interface, let's use it inside controller. I am outgoing button it, and we're good to go. Now we just need to implement this method, find all inside our service. So let's jump inside our articles service. And here, create this function. We have here a sink, find all, and we'll know that we're getting, first of all, current user ID and this is number. And secondly, we are getting here query of type any. And the back we will get our promise of type articles response interface. Now the question is what we will write inside? And there's already showed you here in the example. We will use Create Query Builder. How we can create it. Actually here I will create a property query builder. To create it. We can write here Git repository. And as you can see, Git Repository Function is a new function from topos or RAM. Inside we must provide an entity, as you can see here we provided inside, for example, user. In our case, we want to provide insight article entity because we're working with article. The next one is dot Create Query Builder. As you can see here in the description, we can provide an alias here as a string. This is exactly what I want to do because then it will be easier to build our query. Here I want to write ILS articles just because our table is named articles. And in this case, when the standard better what we are talking about, the next thing that we must do here is Lord our awesome. Just to remind you here inside article entity, we have this relation for author many-to-one. And actually we already used it here when we saved our article. Here we simply wrote article author and it was saved. And actually if we are doing our requests, for example, was find one, then we're getting inside article entity automatically this author, because here we have an option you go through. When we're building our query on our own, we must do it by ourselves because we are building query from scratch. This is why here we have Create Query Builder, and here we must say left, join and select. What is the DEA normally inside Postgres or any relational database. When you want to build some selection of the data based on several tables, you are using giants, which means you have a table one and you are joining to it data of table two. This means that for example, for every record in table one, for example, we are talking about article. We have inside author ID. And by this author id, we're joining all data regarding this awesome, inside our request. This is y here I'm saying left, join and select. This means that we're joined in here and another table. And here we must specify articles.org. This is the field where we want to join it. And here we will have awesome. This is what exactly we will join. As you can see here when I select this function, here are two arguments. First of all, we have here property, and secondly we have here Alice. Actually also is our alerts and articles dot Orissa, exactly what we're selecting. Now let's check that this code is working at all without any additional conditions. What I want here, first of all, I want to get all articles by this request. So here I can try articles, and this will be our array. And here we're saying a rate and we're calling query builder dot, get many. As you can see, get many gets the array. And in this case get one will get unless single record. And we need here an array. So this will return for us an array of article entity. The next part is to get articles count. Here I will create articles count. And here we're using a weight Query Builder. Here we'll get count. So actually it takes this request from the Query Builder and just gets the total. So now we simply need to return this information back. This is why here I am returning articles and articles count, and this is exactly what we specified inside our request. Let's check if this request is working at all. First of all, we don't have any errors here. Let's jump inside postmen. We have slash articles request, and this is again, they want to save as it here. And here will be our feed. If, for example, articles, and we can save it inside our next GS collection. Let's save it and hit Send. As you can see here, we're already getting our data. So we have our array of articles where we have a single article and here is single articles count because we have only one of them. The most important information here is this author. Actually by default we're not getting it. And just because we wrote here this left, join and select who were getting eat additionally. Now let's start to implement our conditions, and let's start from the easiest ones. So actually here we have our request. So let's look for slash articles. And as you can see here are our filters. The easiest here our limit and upset. And if you don't know, the idea is that in the limit where set in how many items we have per page. And offset means how many items we must keep. In this case, offset 0 means that we're on the start. We're showing the items from 0 to 20. If we're on the second page, then we're showing items from 20 to 40 and so on. And actually limit and upset are working out of the box inside type where m, This is why it is super easy to implement. What is the idea? Actually, I want to move this articles request on the bottom and just after articles count, right? My if condition. Why is that? Because articles count must return the total faster. And if we're using limit and offset, then we will get on the specific page. This means after we're using it on our query builder, we can't get total anymore. This is why I am making this request after and then we will get our articles was modified credible. Then what I want here is right, if we have query dot limit, so we're provided limit in our parameters, then we want to say query builder dot limit. As you can see, we're getting out of the box this function limit, and we simply straw inside query limit and it is just working. The same part is coding for our query upset. So we're saying if here we have our query dot offset, then we want to apply our offset. So here we have query builder of set. Here we're biasing our query dot offset. Let's check if it's working. But for this, of course, we need to create more articles. As you can see here we have great article. Let's try to create new one. Of course we're getting some errors. Here. We need to provide a valid title and valid body. Let's name it body and also description. So let's throw here for example, description. Let's hit Send. As you can see, we created new article. I will hit send a lot of times. So we're creating a lot of unique articles and we have a nice pagination. Now let's try if it's working. So we have here slash articles and they want to say here, limit equals to offset equals 0. As you can see here inside our array of articles were getting only two articles because they said here limit to, but in articles count we're getting our total. So in total we have 17 articles. And they are starting from offset 0. As you can see here, our articles have slug full and here slug is GGG and then the slug. If I'm setting here of set six for example, then we have different items. So here we have already different slags, which means we are getting this logic out of the box and it just works. The next step is to apply sorting. Would want to see recent articles on the top. This is where here for example, on the top, we can write this code. We want in any case without any, if you apply this certain, this is why here we have ordered by function and we can provide insight articles, this is our table dot and here we have created at, and just to remind you, created at is our field inside table. Here we can say this sentence. So actually as a second parameter, we can provide either ascending or descending. This you can see here in the recommendation. In our case, just by applying the single line, we're sorting all our articles with descendant. So let's check this out. I'm jumping into Postman and here is offset 0. When I reload the page, you can see here I dynein, which actually means this is the US items. So actually they were sorted. The next thing that we can apply here is filtering by tag. As you can see here, we can provide query tag and then we can simply sort by this ten. What does it mean actually inside every single article we have the list and actually we didn't fill it almost anywhere. But at the first one record, we have this article. This is why here I will say limit 20. And then somewhere on the bottom, as you can see, we have the glutes with React chairs, dragons, and AngularJS. So actually the idea is that we can filter, for example, on the items where inside tech list we have dragons. So the question is how we can write it? For this? We can write here if. And here we're checking if we have query dot tags were provided tag, then we want to use here query builder dot and where, why and where. Because actually rare means that we can provide only a single condition when we're using and where this means that we're throwing new and new where conditions inside our query. This means that we can create several ifs and inside every IV, right? And where this is exactly what we will do. What I want to do here is provide our logic, means that we're applying this logic to our query builder. So here I want to write articles dot tag list. And inside we have like and here we have colon tag. Now here as the second parameter I want to provide an object. And inside I have tagged where I have Atmos crypt six string. So what I want to write here is present and then dollar and inside will be query tank. Now the question is what I wrote at all? So actually if we are talking about Postgres or normal relational database, we can write here for example, some field, for example, articles, text list like and like means that we're finding substring inside our string. And actually tag list is a string because we're storing in our array as a string. If you don't believe me, let's open PSQL. As you can see here, we made the request for our articles. And here our tick list is just comma separated string, which means that this slide will work because we're finding substring inside our string. Here we have our string articles stick list, like means inside, so like concludes, and here we have colon tag. This actually means that we will use this construction inside it. This means that we're not looking for the strict occurrence, but we can also find a part of the string. And actually if you have some questions regarding query builder or how to create queries, you can always jump here in the documentation and look for examples with and where and how you can drive them. Now let's check if it's working. So I will jump here inside Postman and dry it here, result, limit and upset because we're already tested them. Tag equal dragons. As you can see here, we successfully found our articles and here we have only a single article. We're inside, we have task list. This is y here inside we have dragons. There is a match. This is why we're returning here a single article, which actually means that our filter is working correctly. The next is that we can implement is this logic with awesome equals and then the name. And actually it will be really similar to our query tag. Here we can try it if we have query dot author. So we're providing an author and whoop, want to get only the articles of this person. Then here we can write query builder and here n square. And inside we have our logic. So here we have articles, thought awesome ID. Here we have equals and here will be colon ID, exactly like like tag. But here we have really equals. Now here we have an object with our parameters and we need to provide ID parameter, which will be also id. The question is what is author ID? We don't have it here. That this means that if we have this option, we must get an author here. So we must get here a user entity. This is why here I will write const or so we will finish here and author. And here we must write a rate this user repository. And just to remind you, we are inside article service naught in user. This is why here we must also inject user repository if we want to work with it. Here I am writing user repository, and here I want to call find one. And inside we're passing user's name equals query dot. Awesome. We want to find the single user. Here we're finding our author, and then we're passing here inside our request also dot ADD. But the point is that we don't have here user repository and we must inject it here on the top. So actually I will copy paste this two lines, just paste it here, rename article entity to user entity. Here we have then read-only user repository. Here is our repository of our user entity. But it is also not enough because we must provided also inside the module. This is why I will jump in article module. And here we have this typo REM module for future. If we don't provide here our user entity, then it won't work. This is why here we need to write user entity because he was an entity is a dependency. Now of our article module, let's jump back inside our articles service. As you can see now we don't have any errors. Here. We're getting our author and we're biasing it inside our request. Let's check if it's working. So here is our server. Everything is working. We're jumping and say Postman. And here we're saying or so. And actually for now we have just a single awesome and I think this is the ASO full. Let's hit Send. As you can see, we didn't get any articles, so probably I typed our OSCE are not correctly. So let's check the user's name inside Postgres. So here I am right and select star from and here we have users. And these are all users that we have. So we have here email full at gmail.com, then one more time, food gmail.com and so on. Because actually recreated them before we used our validation pipe. So this is why we have duplicates. And actually this is exactly the problem. As you can see here, we have several users with the same username. First of all, it is forbidden in our system. And secondly, we're using here find one because we're thinking that our username is unique. First of all, we must drop our database completely just because this is invalid data. But our problem is that we're finding first occurrence with username form. And probably we found here a user that didn't create any posts. So actually our code is working correctly, but we can't test it. This is why I will jump here inside console and run Yarn dB drop. And this will clean all records inside our database. Now is we don't have a database, we must run our migrations. This is where I'm executing the yarn DB main Create, and it will create all our tables. Now we need to create a new user. This is why I am jumping here inside registered tab. Here is our user, username Fu, password, email. I'm hitting here sand. And as you can see, our new user is registered. Now we must copy a token because this is the most important part files. Now we can jump in and create article and inside header provide a new token because result this token we can't really create our article is you can see the body is fine. Here we have titled body description and here is biography, where hidden sand. And we've got our new article, as you can see now we have here author with id one, and this is exactly our user was username full. And this means that we can jump directly inside our new request articles and provide here Ortho form. Let's hit Send. As you can see now we're not getting the empty array, but a single article that we created, which actually means we had the problem with the data because the data was stale and not without request. And actually our code that we wrote for query author is working. As you can see here, we're finding a single author. And of course our username is unique. And here we're adding to our request to add new condition with our author. Actually there is one more filter favorited, But we will implement it later in a separate video. Just because we didn't implement logic was like and dislike and articles. And this is really related to that logic. As you can see, Create Query Builder, Israeli low-level tool, but don't use it always. But if we really need to tuna or request, for example, work was query parameters, then this is the thing to know and go. 30. Liking articles: In this video, we will talk about like and dislike an articles. This is a topic for many-to-many association inside dipole RAM. So as you can see here, I opened our specification and we have to request, first of all, we can favorite an article and this is a post request to slash API slash articles. Then we have a unique slug. This is our unique part. And then we have slash favorite, this URL we're using to like an article. As you can see here, our authentication is required because we need to build relation between our user and an article and obviously not logged in. User can't like the article. This request must return a normal article as always, and no additional parameters required. We also have the same request but unfavorite article or dislike. We have here a delete on slushy Pi article slug favorite. So actually the request is exactly the same but it is delete. And also here authentication is required and adverse loop we can dislike our article on Lubin were previously liked it. This is exactly what we want to implement. The question is how? Because the main question is how we will store this data. Just to remind you here that the front end of our application, and as you can see, I'm logged in. This actually means that here are some posts that are liked by me. I can hit here like button. And in this moment we're sending this like requests. So favorite article. I can also dislike that article and in this case we will dislike it. So the request is the delete. The question is how we will store it inside database. The main point is that we have now two entities, article and use it. And actually several users can like the same article because for example, two different people created two different accounts and liked the same article. Which really means we can't store this information inside a single article. At least it's not like that in relational databases. And of course we have the same relation but vice versa. It means that this specific user has the array of articles that he liked and we can always get them. So normally we're using for this many-to-many association here to the documentation of many-to-many relation insight type RM. As you can see here, many-to-many relation is when a can contain multiple instances of B and B can contain multiple instances of a. This is exactly our case. We have article and user, and you can have several users that favorited the article. And you can have several articles that are favorited by user. Let's check how we're implementing it. For example, here in the official example, we have a category and we have a question. As you can see here, the question can have multiple categories, and each category can have multiple questions. The main idea, as you can see here, inside entity, we're not writing anything inside category itself. We're writing these three lines inside our question. So as you can see here, we're right in many-to-many, and here is our category. So this is our relation between question and category. Then we're writing the decorator join table. This is extremely important. Here is categories, category, array, which actually means from the question we can write dot categories and get the array of categories where this question belongs or from the category we can do vice versa. As you can see from the entities, everything is looking symbol, but here is how it looks inside Postgres for example, here's our category table here we simply have ID and name. We don't store any information here. Here is our question and we don't store any additional information here also, we have here id, title and text, but typo or RAM automatically when we're writing these three lines, creates for us additional table. This table is question categories. Category. This means that this is the relation between these two tables. This is why here we have questionnaire and category. Here we're writing, okay, we have a relation between a single question and this specific category, which means here we have ID one for example, here is a D2. Then we always know, okay, if we are talking about question, we can get all categories in this table where we have this question a deep, then get all category IDs automatically. This all is working out of the box. But just for you to know this many-to-many relation you have in every ORM, because this is super popular and muted. And we will do exactly the same with liking and disliking. So first of all, for this, I want to jump inside our user entity because exactly here we will write our many-to-many relation. Let's write here exactly how it was written in the documentation. So here we have many-to-many, and here we have a function where we're returning our article entity here that the relation between a user and an article. Now here we have joined. Table decorator. And after this where, for example, favorites. So this will be our property. And later we can write user dot favorites to get all favorited articles. And we know that this is our article entity array. This is all that we must try. The next step is to create migration. So we're jumping here inside console and right and yarn db create here, for example, at relations between article and use it. And we already have this relation because this is how we named it when we made one-to-many. But here we have favorites. So let's name it favorite somewhere. For example, add favorites. Relations between article and user. I'm hidden here enter and as you can see, where have you migration? Let's check the sound. Here is our migrations and here is our long, long name. As you can see here, the most important part for us is that type program created for us new table users, favorite articles. So this is the normal name when we have a many-to-many relationship. Here we have users table and articles table, and here's favorites. This is the name of our property. This is the most important part for us. Now let's jump and said console and dry it yarn db migrate to migrate our database. Now let's check if our table was created. So I'm champion inside PSQL and right in here, D team. As you can see, these are our list of tables and this is our new table users favorite articles. Now we can start here all information about like in our articles. The next step is to create additional methods to like and dislike our articles. And this is related to our articles, as you can see here. This is why we're writing it inside article controller. Here on the bottom, let's implement this function. And by the way, as you can see here, I have a warning, a way it has no effect here because actually our articles service built article response doesn't need an await. It doesn't break anything, but we should not write it here. But this was from the previous video. Here we have our post because we are like in the article, and here is our URL Slug slash favorite and y like this because as you can see here, our articles prefix is on the top of our controller, as you can see here. Now here we simply specify post for slug favorite. Now we also need to use AAC world because it is only for authorized users. This is why here we are, right, and you're squareds, and here is our house quarter that we created previously. Now let's create here, for example, add Article two favorites. Here inside we need two things. First of all, we need NAD of the current user. In this case, we can use it and store it. And secondly, we need a slug of our article. And as you can see, this slug we have here inside params. This is why we can use here, use a decorator and get an ID of current user. Here is current user ID number. And we also want here, but RAM slog to get our slug. So here will be slung as a string. Also, we know that we're returning here the normal article, this is y here is normal article response interface that would did previously. Now inside the mask create a new method inside our service. And this method must return for us article, this is y, here is article and we're calling await this article service. And let's create a new method at Article two favorites. We're passing here slug and current user ID. We know that this method will return for us an article. This is why here I can then return this article service and here is built article response and then sidewalk bias in her article. Now let's implement this function. This is why I am jumping and said service. And somewhere here on the bottom, for example, after fine by Slug, Let's create a new method. Add article two favorites. Here we're getting slag, which is our unique ID, and now user ID, this is a number. And we're getting back as always, article entities because we don't want to get here normalized data. Now the question is how it will work and how we need to save it. Actually, what we want to do is to get current user. And then we can use here user dot favorites. This is our array. Here we can just use push to put some data and then we simply save this user. Then this favorites will be stored correctly in additional table. So let's do this now. First of all, we want here to get an article. This is why here I am getting an article as previously, here is a weight find by slug and we're passing inside slug. The second here is to find our user. And you might ask why I didn't pass the whole user here. The point is that here I want to join the table. This is y. Here I'm writing a rate, this user's repository find one. And here we're passing our user ID. This is totally fine, but we also want here as the second parameter, an option. Here I'm providing relations and then saying here favorites. This actually means that by default, when we're fetching single user, we don't get this relations because we don't need to. But exactly in this specific case, we want to get a user with this relations. Now let's simply return here our article and check what we have inside user. Here I will return our article. We didn't modify it. Here I will console log the user so we can understand with what we're working. Let's check this out. When I'm jumping into the console, we have some errors. Here. We have a narrower in article service, the return type of a sinc function must be a promise. And in our case it's not a promise. Here I forgot to write what promise? This is super important. So here we have a promise of article entity. Let's save this and check this out once again. As you can see here, now it is working. Let's jump to Postman. And here we have in your URL slash, articles slash, and here should be our Slug. Let's take some slug from. Our answer. Here will be the slug and then we have here favorite. Let's check the request slash, api slash articles slash slash, slash favorite. This is exactly it. And here we have a post request and we should not provide here any body. This really doesn't matter. Here. I want to save this request and it will be like article. And we're saving it inside our nest years collection. Let's hit Send. As you can see, we're getting back their articles, so no errors here. And let's check what we have in console. As you can see here, there's our user and the most important part is this favorites array. And we are getting here this array, and this is actually the ray from the giant table because we are not stored in favorites, inside user identity directly, but through additional table. Now here we can work with favorites of the user. What do we want here? First of all, we need to check if our user already favorites is unethical or not. We can write here, for example, cons is not favorited. What we want to check here is use a dot and here we have favorites. Here we can check find index. So actually if index is bigger than minus one, then we have this record there. This is why here I am checking, for example, article in favorites. Here what I want to check is article in favorites dot id equals our article ID. What does it mean? Well, looping through our user favorites and here we're checking if we have this ID. So actually every single article in favorites. And as you can see, this is an article entity has NAD and we're comparing it with our ID that we found here with this line. Here actually, as you can see, we're getting back a number. This is not what we want. We want to get here a Boolean and this find index always return us a number. This is why here I want to compare it with minus one. In this case, if our find index returns minus one, this means that the article is not favorited. So actually if we're making this request and the article is already favorited, we just don't care and will return back an article because we don't need to change anything. But if it's not favorited, then we do our logic. This is why here I will simply write IV. Article is not favorited. Then we must do something. Though. Logic yeast, for example, like this. First of all, we want to push an article inside user favorites. Here we simply write Bush article and we don't care, we should not manage ideas and so on. Typer room does everything fast. So actually this will correctly add in specific table new relations between user and the article. But for us it is looking really easy. We simply push an article insight favorites. The next steps that we should not forget is to change favorites count. Just to remind you, inside article, inside article entity, we have here a property favorites count. This is the counter that returns how many people liked this article. Actually every single time when anybody likes this article, we must increase it. This is where here we're writing an article, DOD favorites count plus, plus. And this will simply increase it. Now we just need to save our user and our article. Here I'm saving First the user. This is why a way this user repository save and we're throwing inside our user. And secondly, the same for the article here, this article repository save. And we're passing here an article. What we're doing here once again, first of all, we are getting this slug end user ID. This is the specific information from the request. Now here we're finding an article and our user with relations and relations is of course important. Here we have is not favorited which returns true or false, depending if we have the nautical inside favorites array. Now here we're checking if our article is not favorited, then we're pushing it inside, increasing the counter and saving both of them. You can see by using oil RAM, our code is super easy and super clean because we're not working with tables directly. Now let's check if it's working. I'm jumping here, as you can see, no errors. Let's test this. Now. I am inside Postman and I'm heat and send. As you can see now we're getting back the article, but we have here favorites count one, which actually means that we modified our article. This means that we saved our relation. Let's check this out for the same champion inside PSQL. Here Let's write select star from users favorites articles to get all records of it. And as you can see here, we have only a single record. And here we have a relation between users ID and articles AD. We now know that this user will say D1 liked the article with A11. And actually this means that our liking of the articles is implemented correctly because we're successfully created this relation, recreated emigration, and now we saved everything inside database. 31. Disliking articles: In previous video, we successfully implemented lichen of the articles. In this video we will implement disliking, which will be exactly the same logic. So let's check this out. Just to remind you here we have to request favorite article and unfavorite. Favorite Walter, the implemented to unfavorite, we have the same URL, but the delete. This is why I will jump inside article controller. Here I have slug favorite. What I want to do here is copy-pasted completely because it will be exactly the same. The real difference is here we have a delete. This is it because we have here slug favorite user acquired. Here we want to name it, for example, delete article from favorites. And here we have user ID, which is our current user. Here we have a slug from the parameter back where given article response interface. So everything stays the same, but also need here and new method. So let's name it, delete article from favorites. And inside we're passing slug and current ED. And here is built articles response. As you can see, this is super similar and just another method and of course delete here. Now let's implement this method inside our articles service. Here I am inside at Article two favorites and let's create now a new method, delete article from favorites. And we're getting here like in previous method. First of all, slag, this is strain, and secondly, current user ID, this is a number. Back we're getting as always promise of article entity. Now what we want to do inside is exactly like previously, we can actually copy paste all this code. Because first of all, we want to get an article, secondly user with the relation. And third, we want to know if article is favorited or not. This is why I will simply copy paste everything here. So here we are getting an article. Here is our user actually here we named it user ID and not current user ID. Let's do the same here. It's a user ID. And then here is not favorited. But they actually here I want to change code a little bit because we need here index to remove the item from the array. Because for us we have the array with items like articles, and we want to remove here an article if we have it. This is why actually want to save in this property not is not favorited But article index. And then here we don't need this Boolean comparison because we really want to get back article index. So actually here we either get a normal index or minus one. And minus one means that this article is not there. This is why here we want to check if article index bigger or equal 0, and this means that our article is there. The next step here inside we want to remove article from favorites. This is why we're right in here user favorites. And here I can use splice, just modify our array directly. What they want to remove here is article index comma one. I want to remove a single element on this index and this modified directly user dot favorite because this is a mutation function. After this, we want to decrease our counter. Here we have article dot favorites count, and here we want minus minus. So we're decreasing our counter. And of course the question is here, if we're not decreasing it to less than 0, and actually here we have a check for article index. This means that it can't be realist smaller than 0. Now we just want to save both user and an article like we did previously. This is y here, user repository save and inside this user here we're saving our article. Here there's articles, repositories, save article. Just to remind you how everything is working, we are getting, first of all an article and secondly, our user was favorite. Then we're finding article index. This will either be minus one or normal index 0 and something bigger. In this case, we know that our article is there. This is why we can dislike it. Because if our article is not there, we should not do anything at all. Now inside we have this logic. If article index is bigger or equal 0, so we have an index, then we're using Splice to remove the article from the array, and then we decrease the counter. And obviously saving these two records. And of course at the end we must return here an article. So here I am returning the article. And if we didn't modify it, then we simply return the same article and would do it. Then here we change to the favorites count and saved it. Let's check this out. We don't have any errors here. Let's jump to Postman. Here is our article will know that this is favorite. This is where here I'm using delete and they want to save the request. So here will be, for example, this like article. Let's save this inside next year's collection so we can reuse it later. And we don't need actually anybody. It doesn't matter if I provide here something, we simply ignore it. Here I'm hitting sand. As you can see, we got back our article. And now favorites count is 0 because we're disliked the article. And this actually means that in our table, we don't have any records. Let's check this out. I will jump inside PSQL and right here, select star from our users favorite articles. As you can see here, we have no 0 roles because they pour RAM successfully removed this single relation. This means that our dislike is working correctly. Which means we successfully implemented like and dislike an article. But here are some things that they want to improve. First of all, just to remind you inside our list of articles. So requests literate past lush articles, we didn't implement previously this filter for favorited. And actually this filter is needed when we want to find all articles that are favorited by specific user. This is why now I want to implement this functionality. Let's jump inside our service and it was feed on the top. Here I will go to the top. This was find all. Just to remind you, here we had different queries like Query Tag, query author, and now we must implement query favorited. This is why here I am write an IV, we have query favorited. Then we want to do some magic. And first of all, we want to find our user with relations because only in this case we can find all favorited articles. So here I have an author of this article, and here we're using a weight of this user repository. And here we have find one because we wanted to find just a single user. And then side I am passing username. And here will be query dot favorited, because this is exactly the unique username that we passed here. Here we found our user. And the most important part that here we want to set some options. Here what we want to do is pass our relations. And here we're saying favorites. In this case, we will not get on where a user, but a user with China table of favorites. Now let's console log what we have. Here. I will simply console log our author. We can debug it and see what it is about. First of all, let's jump in web server, as you can see, no errors here. Then I will jump to Postman and click on getting articles. So this is the request get articles. I am hidden sand, as you can see this as an array of our articles. Now, we want to write here question mark favorited, and here will be our user. Actually, first of all, we need to favorite some article by some user. We have only user foo here. We can check this out. I'm hitting sand. As you can see, we're getting our response. But for us interested in is this console log. As you can see here we are getting the author. This is our user entity, and here this favorites. And it is empty because we didn't like any articles to make it easier to debug. Let's like some article. This is why here I can't use our requests like article. Here we have some article and we'll make an favorite for our currentUser. I'm hitting here sand and as you can see here, there's favorites, count one. Now I'm champion bag inside our articles response with favorited full. I'm hitting sand and looking in the console. And as you can see now, we have this nice array favorites with article entity inside. This means actually that we will have here the array of article entities. We can write some code regarding it. So actually what we want to do here is to add one more condition. And we want to check that every single article that were returned an int, the response is inside this favorites array. This is how we can do it. What we want to do here is first of all, to get the IDs which are favorited. This is why here I am right and const IDs, for example, were taken off the DOD favorites. And here we're making just map. We are getting each element and here is element dot ID. In this case, this is an array of numbers which are IDs of our article entities. Here we got our ADCs, which is array of numbers. We can do now query builder dot n. And here is one more condition. Here I want to write articles stored or so ID in, and here I am right and round brackets then colon dot, dot, dot IDs. And here I will give as a second parameter object with ideas. If you will check the documentation of Topo Program, sometimes we want to check that some property, for example, or society is inside the array. This is how we are writing it, we're writing it within. And this strange construction. And actually in here, it means that this construction and this AD's and ideas that we're providing here is the array. This is why we're checking that this idea of the article is inside this array that we got here. And if it is inside, then we will return it. But here is one small problem that you will get if you will write code like this. And actually this is the problem or a bag of type RM itself. You can't really make this request if you're a DES is empty. This means that we must wrap this logic inside some if condition and check if this is not empty. In other case it will be just broken. This is why here I will write this length bigger than 0. Then I want to do this request. In other case, I don't want to attach anything. But actually this logic is not correct. This just means that if we have lands, so if we have some favorited articles, then we will apply this logic. This is completely fine, but the problem is if we don't have any ideas, in this case, normally we wanted to return for this author, the empty array. But from our logic now, if we are not going inside this array, then we simply return all our normal articles without filtering them by favorited. This is why here we really want to say that we don't need to return anything if we're not inside this IV. Here, I want to say else. And what we want to say here is Query Builder and where here we want to write something that will never happen. In this case, we will get back the empty array. This is why here I am simpler, right, in that one equals 0, this is always false. This is why if we have ids which is empty, then this line will return for us an empty array. Here I am jumping into web server, no arrows here. Let's open Postman and hit full. As you can see here, we're getting just a single article because this is the online article which has favorited by user foo. Now the question if it will work, if we will dislike the article, so we have 0 favorited articles. For this, I will hit dislike article and click Send. So we have no 0 records. Now let's try again. I'm clicking on articles and here I am hitting sand. As you can see, this is exactly what I was talking about here. We're getting a 0 articles. But if we will remove this logic, this else, then we will simply give back all articles that we have. And this is not the correct behavior. Successfully implemented our query parameter favorited. But here is one more small problem that we have. Actually, if we will just scroll here and click on multiple articles, as you can see in every single article we have this property favorited. And the problem is that we have this property everywhere, like in every single request, we have this favorited field, which actually means that in every single request when need to write some logic to attach this favorited property here, because actually inside our article entity, we don't have such property and we're not getting it directly from the database, which means we must calculate it. And they want to show you on the example of our articles request how we can do it. This is really quite easy. We're not doing anything here. I will just remove the console log. But here on the bottom, for example, after all our offsets and limits, before we are getting our articles, we can get the array of favorited and then just normalize it. The main point is this favorited property is only for current users, because actually this is set only for current user. If you are not logging in that it will simply be always false. This is why here I want to create a property with lead favorite ideas. And here we have an array of our numbers. And by default, I will write here an empty array. Here we will write the array of ideas that are current user is favorited. Now I want to check if we have current user ID and if we have it, then I want to get here current user with favourite property. This is why here we are getting our current user with evade this user repository, find one. Here we have our current user ID, and then we have the relation inside relations as previously were, right in favorites. Now here we've got current user ID with favorites, non-book want to get favorite ideas like we did previously. This is why here we have current user dot favorites. Here we have map and for example, favorite. Here I am returning favorite dot ID. In this case we are getting the array of numbers, which is the array of like articles of current user. What does it mean? Here we have favorited these as empty array and this we have also for not logged in user. Now, if we're logged in, we always want to know if we like some articles or not. So here we're overriding this array. With array of liked articles. Now here when we are getting our articles, we can add an additional property to every single article afterward getting them from our database. Here we can create after articles, articles with favorited. And here I want to map through our articles and here I have each article and they want insight to find the favorited. Here will be favorited. I'm just doing favorite ideas. This is what we created previously and we're checking here includes to check if we have this ID inside the array. Here I'm checking article dot ID. Actually we simply looping through all our articles. And for each article we're checking if it is favorited or not. And after this, I want to merge our article with property favorited. If we're not logged in, then this favorite to that property will be everywhere false. And before I logged in, then we will check it. And as you can see here, now, this is not the article entity. This is the array with all fields of our article entity plus favorited Boolean. This is extremely important because this is what we want to return back inside our request. Now here instead of articles, I want to return articles with favorited. Here is a really super strange thing because as you can see here previously inside articles, we have an array of article entity. This is where everything is working out of the box. But as you can see here, it's not article and it anymore, this is just an object because TypeScript just took all properties from our article entity. But here we're getting a narrow actually that property update timestamp is missing. The question is what is update timestamp and actually went bad champion inside article entity, we have here update timestamp function. And actually previously it worked because we were returning here directly, article, entity and TypeScript didn't scream. But in our case now this is not article entity anymore. This is why this function is not there. This actually means that we must use our types a little bit in the same way like we did with the user. And just to remind you, here we have the user and we had types. And here we created user type where we're unmuted from user entity hashed password. And now we must do exactly the same for our article type. This is why I will copy this code and jump inside our article types. And we can create here article type dot ts. I will jump inside here. We don't need this input and they will rename this type user types to our type article type. Now here I want to use Amit article entity and they want to admit here this function. And as you can see, the name of this function was update timestamp. So let's write it here. Update timestamp. This is now article type, and now inside our response of articles responds instead of array of article entity, we can use article type. So let's import it and remove here article entity. In this case, now we're returning here. First of all, articles count as a number, and secondly, article is article type. And actually article type is simply a political entity without update timestamp function. Let's check if it's working now, as you can see, I'm jumping here and we don't have any errors because here we're returning article type array. And in this case this part is exactly article type array. Now let's check if it's working. So here I am jumping inside the web server. We don't have any errors here. And now we can open up Postman and make our request for articles. And it doesn't even matter if we're using here favorited on NADH, we will always get this property which will be favorited. Let's check this out. I'm hitting sand and now we're getting here and new property favorited, which is false or true. And obviously for us this property favorited is false because we dislike the article. So if we want to check it, then we need to like article again. Here I'm hitting sand to like the article. I'm jumping inside our articles, hidden sand. And here we're getting our favourite through because this logic is working correctly. And here we found currentUser AT, then we've got favorite eighties. And here we mapped our articles with favorited for every article. 32. Seeding the database: We're almost finished our module article. There is still one more method to implement, but we can't really do it now because it is related to profiles and following unfollowing the users that would don't implement yet. This is why in this video, I want to show you something important for configuring your nest JS application. I'm talking about seed in your data. What is it about? Normally we're doing a lot of drop databases and migrations, which actually means that every single time when we're dropping the database, we're dropping all records from it. This is not comfortable because every single time after migrations and dropping, I must create users by hands, may be articles, tags, posts, whatever I need to start developing. This is not comfortable and this is just useless work. This is why in normal frameworks you have something which is called seed in the database. You have some predefined data and you just throw them inside the database. Unfortunately, inside nastiest, there is no such functionality, which means we must implement it on our own, but this is not that difficult and in this video you will learn how to do it. So actually the easiest way to do it is just to create a separate migration which will be used for citizen data. Why is that? Because they actually went to where column migration command, it is just execute in some file with logic inside. Here we have, for example, credit runner and everything is good to go. But of course, we don't want to pack our migration for seeding here inside our migrations. First of all, because we are calling our migration's not on development but also on production. This is why we want here additional folder like seeds, and we will have our seed in data there. And also we need an additional command to seed our data. This is why the first step here will be to create additional config for Syrian our data. Here I will create IRM seed config dot ts. This you can see we have already ORM conflict. Yes, I will open it here on the right. And as you can see, this is the whole conflict that we have. We can reuse almost everything from here. What we really don't need is this Migrations folder and Cl live migration directory. The main idea is actually that we will try it in our seat Conflict Migrations folder, but it will be seats. This is what we want to do. Here. We can write const, and here will be config. This is just an object. What we want to do now here, we want to use a conflict. We can import this or REM config. This is export defaults, so without brackets just to have them config from. And here we will have our app slash or a ram conflict, which means we fully take all these properties from the config. Then we spread them here, and then we override several of them, which means we should not type here the whole conflict for Postgres for database user with simpler override several properties. Here I want to write first of all, migrations. Here will be source seeds slash star dot ds. As you can see previously here we had our migrations, which on our normal migrations, but here we will take them from the seeds folder. This is the only difference. Now here we must specify CLI and inside we will have our migrations directory. Here will be source slash seed. Actually this is it, This is our full configuration. Now I want to export defaulted here or a ram seat conflict. Actually these are all these fields with overwritten migrations and migration directory. Our next step is to create this folder and I'll migration inside. Here. I want to create for the seeds and inside a migration. So here I'm creating a new file and important thing that this file mustard with some timestamp. This is why here I have just a random timestamp. You can use this or just copy the timestamp from any of our migration. And as you can see here, the name is seed db.json. Actually the name here doesn't matter. And we will have a single migration where inside we will throw off our code. And actually what they wanted to do. I want to jump in migrations, for example, create tags and copy paste everything from here, and just paste here. So actually we will have almost the same code. But first of all, I want to change the class. So here we have Cdb and then this AD, it doesn't really matter. It should be a unique class and it implements migration interface. This is fine. We'll also need another name. So it is the same name like here inside class. And now we have up and down. The point is that we don't need anything in down at all because we simply won't implemented for us, seeding is just a process that we don't want to revert. This is why empty function down here. Now here inside up, we want to write some R code that will insert our records to the database. So what we can do here, remove everything inside these brackets and write insert into, for example, we want to create some default tags. This is why here I am saying tags. For tags, we have only a name. Now here we're writing values and here we will have several values. For example here whereby sin dragons. And actually this is how we normally make insert inside the database. And of course I missed here letter t. But the point is that we can also insert several records here after values and then round brackets. We can put comma and then one more round brackets. This means that it will insert several of them. For example, here we insert dragons, then we insert coffee. For example, the last one will be at Nest GIS. In this case, we're uncertain in our seed file, three default popular texts. Now let's just test if this work in at all. So what we need to do is jump inside of a package JSON. And here I want to create a new command and it will be, for example, db seed. Then what I want to do here is exactly what we have here. Why? Because as you can see here in topos around with specified conflict source or a ram conflict. Here we must specify different conflict. Actually, I will copy everything from type RM based here and then change this source or a ram config to source or a ram seed config dot ts. And now at the end, I can write migration run because we don't want really to save just the command type RM would want to do here migration run how we're normally doing. But for the seats folder, which actually means for typos and we're saying, okay, seeds is now our migration folder. This is why tapeworm will make great the single seed file files. Now let's check this out. I am jumping into the console, toluene it yarn db seed. And as you can see in this case, it should do one seed. As you can see here, we have the message one migrations were found in the source code. And here is our code with insert into tag, and this is the name. So as you can see, it was done successfully. This is why we can jump inside pH scale and write select star from tags to get old tags. And as you can see here, we're getting three tags that we created inside seed. Our workflow is like this. Normally we're right in the yarn to be dropped. So we're dropping the full database. If we need to change some data or restart everything, then we're right in the yarn db migrate to make create the tables and create them. Last button, at least we're right in the yarn db seed, and it will generate default seed data for us. The most important point here to remember that you can run migrations only ones, because as you can see here, this line will create the record inside migration stable. And this means that a country right here, young DBC it again because it won't do anything, because this migration is already there. If we want to run seed command again, we need first of all to drop our tables completely. As you can see, everything is working and we successfully created our seat command. But now I really want to change it a little bit because just tags is not enough for us. This is why I am jumping here and I want to insert maybe also articles, of course, a user. This is why here we can write a weight and run a query. And here we want to insert the user, this is y here we're right and insert in turn. And here we will have users table, and now here are fields that we want to insert. And first of all, it will be username, then email and password. Just to remind you our password is hashed. This means that what we can do, we can jump here in the console and write select star from users and copy paste all this code, as you can see here now we don't have any user because we dropped our database. To test this, we need to hit on register. Here is our registered request. As you can see, username is full and password is 123. We are sending the request. This is the answer. And now we can copy, for example, this password from the answer. Because this is what we want to store inside citizen data. Here we must provide our values and here we will have first of all, full, this is our username. Then we have full at gmail.com. And last one will be password, and this is our hashed password that I cooperate. And now we can make here a comment for future, so we don't forget our password is 123. The last thing that I want to create here is a single article for testing. This is why here I will write a weight query, ironic query. And here I want inside to create a query for our article. This is y. Here will be insert into articles. And here we have lots of fields. We have here slug, title, description, body and triglycerides. But actually tick list has a problem. We're controller right here tick list because it will be lowercase for Postgres and it won't work for us because inside our entity here, inside article, article, entity, We have here Tag List as camelcase. And actually the correct way to work with it is to rub it in quotes like this in double-quotes. In this case, this will be just a string and this is fine to use it as a column like this because our column is tagged list with big L. In other case, we can't really create the correct column. And also we have here also, I did was exactly the same problem it does CamelCase. This is why we're putting it inside double quotes. Now here are our values here. And just to remind you were right and all values in single quotes. First of all, we have our slug. So here we can write first the article. Now then we have here the title. So let's name it first article. Then we have our description. So here will be first article description. Then we have a body. So first article body, then we have tag list, and in this case we're passing in size string because just to remind you, we're not saving arrays inside our column, we have the string deified column. This is why here we have a string, for example, coffee, coma, dragons. And it will work correctly with nice chairs. And last but not least, of course, here is the AD of our user. Here we are writing one because here we created the first user and for the first user we have index1. Now let's paste here one more articles. So we have several of them. So here we have second article, the name is second article, the description is second article description. Then we have the body, second article body. And then we have, for example, coffee and dragons. This is fine and user ID is one, which means we're successfully prepared all our runners for seed file. Now what we need to do is jump inside console and try once again. So first of all, I will do drop to remove completely our database. Then when it dried yarn db migrate to apply our migrations. And the last one is of course, yarn db seed to add our seed data inside the database. As you can see, our sheet command has an error. And here you can see the query where this error happened. So insert into Users has some problem inside. So let's check this out. Here. I already can see our problem, as you can see after our email, I put coma twice and this is of course not correct. Here we simply need common ones. Now we must do everything once again, first of all, young dB drop then may create and then seed. As you can see now, we don't have any errors and all our inserts were done correctly. This is why we can jump inside of a pH scale and write, for example, select star from users. And as you can see, we already have a user which is successful at registered and it is there, which actually means we should not every single time register a user. We simply can use the user that were already created. And let's check this out. We can simply make login. And here is our full at gmail.com and password 123 where hidden sand and as you can see, we return the user because our data was successfully seated with our seed migration. 33. Getting a profile: In this video, we're starting in your section, and this is working with profiles. And let's check what we have. Here. I am inside specification and as you can see, we have a get profiles request. This is slushy pie slash profiles, and here is a username which is a dynamic and unique part. Here as you can see, authentication is optional and it must return a profile. What is profile? This is the new response. We're inside we have a profile property, and inside we have username