Learn Express.js with me~
Published: 2023-11-29 03:55:11

Today, we will be learning about Express.js using TypeORM with the operations: Create, Read, Update and Delete or CRUD.

To start off, let’s get to know _Express.js_ or simply, **_Express_**, first shall we?

What do we know about Express?

Express.js is a popular web application framework that simplifies building reliable and scalable web applications for Node.js. It is a fast and lightweight framework used majorly for web application development and is majorly responsible for handling the backend part.

------
Before we get on with coding, let us first prepare what we will be needing for this project. 

- We will need to create a folder directory, and it could be anywhere on your computer. 

- Then, open your Postman and pgAdmin _(PostgreSQL)_ applications.

#####pgAdmin#####
Within pgAdmin, create a database to use for this project. To do this, click on the drop down arrow of the _Servers_, then do the same with _PostgreSQL 16_. Right click on the _Databases_, select _Create_ and then _Database_.

![pgAdmin](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4m5lxk5x4ir94jceyk1.png)

Name your database according to what you will use it for, and then save.

![Rename db](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gp9xf7h4ckox6h0bffmy.png)

#####Postman#####
Then, on your Postman, create a new collection by clicking on the _PLUS sign_ on the left and then the _Blank Collection_. 

![Postman](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g9rmb9zwbk2eeyalep8f.png)

You can then rename the collection by clicking the three dots on the right side of the bar or once the panel has opened on the right.

![Rename Collection](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4sek1fv8mjehmxoa99ur.png)

Once created, click on the _Add a Request_ underneath the newly created collection. You can then rename the request once it opened on the right panel.

![Postman Request](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p29kka3sws5ivmy7j3m8.png)

Once everything had been prepared, let us now move on to **VSCode!!** 
_(or whatever platform you use in coding)_

On your VSCode, open the folder that we created earlier or simply _CTRL+K_ then _CTRL+O_

![VSCODE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tuv7fn6ggoaa87f57kni.png)

Once the folder directory has been opened, you can go ahead and open the _Terminal_ or simply _CTRL+Shift+'_

![VSCode Terminal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1xq3oibrmndncbrqbn7f.png)

On the _Terminal_, choose _Git Bash_

![gitbash](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/61ja4vouylbl40nr5p8g.png)

Firstly, we will install Typeorm _globally_, to do that, we'll use:

```
$ npm install -g typeorm 
```

Once that's done, we will then use:

```
$ typeorm init --name express_project --express --database postgres
```
We use this code to automatically install and create packages.

> - `typeorm init` is used to initialize ORM
> - `--name express_project` is used to assign project name. 
_(In this case, express_project is the assigned project name._
> - `--express` is used to install Express.
> - `--database postgres` is used to call upon the database that we will use, which is _Postgres._

At this point, we can now notice the automatically generated folders right here:
![vscode](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y759jl9dzdu085zih6ax.png)

> - **_tsconfig.json_** is responsible in handling typescript rules.
> - **_package.json_** contains descriptive and functional metadata about the project, such as the name, version, and dependencies.
> - **_.gitignore_** tells Git which files to ignore when committing your project to the GitHub repository.
> - **_src_** holds the _.java_ files and stores the whole project's unminified source code.

Now, let us then redirect our **Terminal** to the folder that we are using which is _express_project_ within our **EXPRESS_JS**.
```
$ cd express_project
```
Once you have been redirected to the folder, it should look like this:

![terminal 1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g4npbesfe4oeocy01w5f.jpg)

Now that we have entered our folder, let us then install _Nodemon_. Nodemon monitors your project directory and automatically restarts your node application when it detects any changes, making the development of the node.js applications speedy.

```
$ npm i nodemon
```

After installing, within the root of our directory, let us then create a configuration file for _Nodemon_.

![nodemon.json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yx4nrp7pnhka1391w4or.png)

Within _nodemon.json_, add this:

```
{
    "watch": ["src"],
    "ignore": ["src/**/*.test.ts", "node_modules"],
    "ext": "ts,mjs,js,json,graphql",
    "exec": "npm run build && node ./build/index.js",
    "legacyWatch": true
} 
```
> - `"watch": ["src"],` _watches_ the entirety of the _src folder_. It reruns/restarts the application once changes are applied.
- `"ignore": ["src/**/*.test.ts", "node_modules"],` excludes the src files within the brackets from being _watched_.
- `"ext": "ts,mjs,js,json,graphql",` are the extensions that will be checked during runtime.
- `"exec": "npm run build && node ./build/index.js",` are the commands that will be executed once file changes are made.
- `"legacyWatch": true` enables an older, less efficient file-watching mechanism. This option is used when you encounter issues with the default file watcher.

Afterwards, let us then install *rimraf*. Rimraf command is an executable that is used to clean the installed node packages in a node based project. It basically executes the rm -rf command on the node_modules directory, but is a faster alternative. You can install rimraf by using the below code on your terminal.

```
$ npm install rimraf
```
Moving on, we can now proceed with setting up _scripts_ within our _package.json_. This is how it looks like initially.

![package.json](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q420nwx7gy3zjajrrspl.png)

On the bottom lines *(21-25)* we can find the scripts that we need to edit. 

And since we have installed *Nodemon*, *TypeORM* and *rimraf*, they should be included in the scripts as well for them to test, build, and streamline the needed commands to work with a module.

```
"scripts": {
      "dev": "nodemon",
      "build": "rimraf build && concurrently \"tsc\"",
      "start": "npm build && nodemon src/index.ts",
      "typeorm": "typeorm-ts-node-commonjs"
   }
}
```
> - `"dev": "nodemon",` pertains to the configuration for the recently installed nodemon namely *nodemon.json*.
- `"build": "rimraf build && concurrently \"tsc\"",` deletes old *build* folder and then creates a new one
- `"start": "npm build && nodemon src/index.ts",` this will serve as the command that will be run and restarted by nodemon when a file changes.
- `"typeorm": "typeorm-ts-node-commonjs"` is used to generate migrations.

Upon saving the *package.json* file, there might be a time where it will fail, and if it does, just choose to *Overwrite* it and that should do the trick.

Once the *Script* has been successfully set up, let us then move on to the **Data Source** *(assuming that the database has been prepared)*.

Simply go to *data-source.ts*, which you can find in your *src* folder.

This is where we will be able to connect our database to the express application.

![data-source.ts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fg7yyvu5nlwxyviuyd0y.png)

Initially, this is how the *data-source.ts* looks like however, with a set-up like this, sensitive information might be displayed or uploaded. 

To prevent this, we will use *.env*

To set up, we will need to create a *.env* file into the root of our directory. 

![dotenv](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1pkf9ykwbj78b4z32rjx.png)

The information included here are the ones that we will  not allow to be uploaded into our github. Namely, *host, port, username, password, database, synchronization and logging from data-source.ts.*

![dotenv info](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nigbn3jojxu5qozn55xw.png)

> - `POSTGRES_DB = project_exp` pertains to the name of the database used
- `POSTGRES_PORT = 5432`, pertains to the port number which is also the default.
- `POSTGRES_PASSWORD = admin` pertains to your postgres password
- `POSTGRES_USERNAME = postgres` pertains to your postgres username
- `POSTGRES_HOST = localhost` pertains to the hose
- `POSTGRES_SYNC = true`, pertains to the synchronization of data. True pertains to the permission to synchronize data and any changes made within the *entity* will then be automatically saved within the tables in the database.

Any term/word can be used to name these variables so long as the *.env* file is imported into the *data_source.ts* file. To import *.env*, the below code shall be included within *data-source.ts*.
```
import "dotenv/config";
```

this is now how our data-source.ts file should look like:

![dtsrc](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/204bl7c2a4kq0dk2bia0.png)

Notice that there are some changes on the *data-source.ts* file. On the photo above, a property called *process.env* has been added. ***process.env*** is a property that returns an object containing the user environment.

We include `*process.env*` and call upon the terms/names used from our *.env file*.

```
import "reflect-metadata"
import { DataSource } from "typeorm"
import "dotenv/config";

export const AppDataSource = new DataSource({
    type: "postgres",
    host: process.env.POSTGRES_HOST,
    port: Number(process.env.POSTGRES_PORT),
    username: process.env.POSTGRES_USERNAME,
    password: process.env.POSTGRES_PASSWORD,
    database: process.env.POSTGRES_DB,
    synchronize: !!process.env.POSTGRES_SYNC,
    logging: false,
    entities: ["build/entity/*.js", "build/entity/**/*.js"],
    migrations: [], 
    subscribers: [], 
    
});
```

`*entities: ["build/entity/*.js", "build/entity/**/*.js"*]`

this just entails that every _.js_ files within the build folder will be saved on the database as well as every changes made within the entities. 

Before we run, be sure to install *.env* file into your terminal as well using: 

```
$ npm install dotenv -D
```
If error occurs, kindly check if the *.env* file is saved within the root directory.

Moving on, once every entities have been saved, we will then proceed to ***index.ts***. 

Initially, this is how the generated **index.ts** file will look like: 

```
import * as express from "express"
import * as bodyParser from "body-parser"
import { Request, Response } from "express"
import { AppDataSource } from "./data-source"
import { Routes } from "./routes"
import { User } from "./entity/User"

AppDataSource.initialize().then(async () => {

    // create express app
    const app = express()
    app.use(bodyParser.json())

    // register express routes from defined application routes
    Routes.forEach(route => {
        (app as any)[route.method](route.route, (req: Request, res: Response, next: Function) => {
            const result = (new (route.controller as any))[route.action](req, res, next)
            if (result instanceof Promise) {
                result.then(result => result !== null && result !== undefined ? res.send(result) : undefined)

            } else if (result !== null && result !== undefined) {
                res.json(result)
            }
        })
    })

    // setup express app here
    // ...

    // start express server
    app.listen(3000)

    // insert new users for test
    await AppDataSource.manager.save(
        AppDataSource.manager.create(User, {
            firstName: "Timber",
            lastName: "Saw",
            age: 27
        })
    )
    await AppDataSource.manager.save(
        AppDataSource.manager.create(User, {
            firstName: "Phantom",
            lastName: "Assassin",
            age: 24
        })
    )
    console.log("Express server has started on port 3000. Open http://localhost:3000/users to see results")

}).catch(error => console.log(error))

```

Since we will be using repositories, let's just simplify our *index.ts* into this: 
![index.ts](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l8j3z645l92grikig4se.png)

> - `AppDataSource.initialize()` initializes the AppDataSource along with the server. Simply put, once the server starts, the database will also start along with it. *AppDataSource* (*data-source.ts*) connects our files into our database. 
- `const app = express();` creates express application.
- `app.use(bodyParser.json());` is a *middleware* that is used to prevent errors with .json requests and responses.
- `app.listen(3000);` entails to which port you will use into your app.
-  `console.log` is used to output a message into the terminal for us to be able to see if the project is working. 

Once *index.ts* has been prepared, we will then be creating folders. 

![folders](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1hwa5y6lbd31hjk58xi.png)

From the package that we installed earlier, the following folders shown in the photo are the folders that were generated. But since we will be arranging these items in a corporate standard, other files/folders should be removed.

The _migration folder_ which is located within the src folder along with the *routes.ts* file should be removed. This is because there will be folder/files that we will include separately later during this lesson.

![migration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l4xdudvr7kumg27mszry.png) 

![routesdel](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lqwm4qhcun9p1c3637xz.png)

Now, within the *src* folder, let us then add folders to which we will name: *routes, services and repositories* individually.

![routes, services and repositories](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5urq7rglexfzmixrqg78.png)

In the *repositories* folder, we will need to create a file where all the entities that we will connect and declare within the database will be added. Let's name it *UserRepository.ts*.

![user repo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rvu3tsvf6rb0mbbn6zl8.png)

Then, within the **UserRepositories.ts** file, encode this:

```
import { AppDataSource } from "../data-source";
import { User } from "../entity/User";
import { UserService } from "../service/userService";

export const userRepository = new UserService(
    AppDataSource.getRepository(User)
);
```
> - `export const userRepository = new UserService(` The export statement allows developers to make parts of their modules available to other modules. 
- ` AppDataSource.getRepository(User)` this is used to call upon the data source within the controller.

Then, within the *services* folder, let us create a file and name it **UserService.ts**

![UserService](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j8xjtijaijclfjkerj2g.png)

Within **UserService.ts**, this is where we will declare methods that will handle all of the so called business logic that will happen in this project. 

Let us then encode this:

```
import { Repository} from "typeorm";
import { User } from "../entity/User";

export class UserService {
    constructor(private readonly userRepository: Repository<User>){}
    async findAll(){
        const users = await this.userRepository.find();
        return users;
    }
```

>- `export class UserService` we export the UserService class for it to be accessible to other modules in this project.
- `constructor(private readonly userRepository: Repository<User>)` we put constructor within the UserService to prevent it from constantly initializing the repository. 
- `async findAll()` Async simply allows us to write promises-based code as if it was synchronous and it checks that we are not breaking the execution thread.
- `const users = await this.UserRepository.find();` the **await** function is interconnected with **async** wherein await prevents responses to be made within the _UserRepository_ so long as the *promise* has not been fulfilled yet. 
- `return users;` 

With the use of the codes above, our *UserRepository.ts* is now connected to our database.

After this, we can now proceed to our UserController.

This is the generated _UserController.ts_:

```
import { AppDataSource } from "../data-source"
import { NextFunction, Request, Response } from "express"
import { User } from "../entity/User"

export class UserController {

    private userRepository = AppDataSource.getRepository(User)

    async all(request: Request, response: Response, next: NextFunction) {
        return this.userRepository.find()
    }

    async one(request: Request, response: Response, next: NextFunction) {
        const id = parseInt(request.params.id)


        const user = await this.userRepository.findOne({
            where: { id }
        })

        if (!user) {
            return "unregistered user"
        }
        return user
    }

    async save(request: Request, response: Response, next: NextFunction) {
        const { firstName, lastName, age } = request.body;

        const user = Object.assign(new User(), {
            firstName,
            lastName,
            age
        })

        return this.userRepository.save(user)
    }

    async remove(request: Request, response: Response, next: NextFunction) {
        const id = parseInt(request.params.id)

        let userToRemove = await this.userRepository.findOneBy({ id })

        if (!userToRemove) {
            return "this user not exist"
        }

        await this.userRepository.remove(userToRemove)

        return "user has been removed"
    }

}
```

Clean it up into this:

![ucontroller](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8bra8anovnz4t6hl9x3.png)

> NOTE:
Within the **UserRepository.ts**, the *UserRepository* initializes repositories and instantiates the *UserService*. 

> Wherein, the *UserService* within the **UserService.ts** was injected upon by the dependency: `(private readonly userRepository: Repository<User>)` _(or what they call dependency injection)_. 

> And since the dependency has been injected, we use *`this.UserRepository.find();`* instead to call upon the *UserRepository*.

> Then, within the **UserController.ts**, instead of calling upon the *UserRepository* in another ways, we use `UserRepository.findAll()` instead. 

> You can find `findAll()` from the **UserService.ts**.

Controller accepts/receives user requests to which it will then transfer into service. All business logics happen within the service folder.  

Moving on, let us then proceed to create a ***.ts*** file within the **routes folder**. 

![routes.ts] (https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cd2pnhogyv0rfhqzmz14.png)

In the new **UserRouter.ts** file, we will then include this:

```
import { Router } from 'express'
import { UserController } from '../controller/UserController'

const userRouter = Router()

userRouter.get("/users", UserController.all);

export default userRouter;
```
`UserRouter.get("/users", UserController.all);`
>- `*.get*` seeing as the command that was used from our _UserService_ is `findAll`, we will be using _get_ as the HTTP verb.
- `"/users"` is the specified routing where the HTTP verb will proceed.
- `UserController.all` to connect the routes into the controller. 

Having these codes encoded will not make our program functional just yet, to proceed with that, let us then go to our *index.ts* file first and include this:

![index upd1](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qqq64t0j8ujluunxtk3i.png)
*see the highlighted part on line 11* 

Using this, we will be able to view the **entirety** of the data we have which is its limitation. What if we wanted to just view a single item from a single ID? 

To be able to do that, let us go back into our **UserService.ts** and use the below code right underneath our `*findAll*` command.

```
async findOne(id: number){
        const users = await this.userRepository.findOne({ where: { id } });
        return users;
    }
```
Replacing `findAll` with `findOne` will limit our scope specifically into the ID which is the primary key.

Right after setting up our **UserService.ts**, we can then again proceed into our **UserController** to connect the latter.

```
static async findOne(request:Request, response:Response){
        const id = Number(request.params.id);
        const data = await userRepository.findOne(id)
        return response.send(data);
    }
```

> - `static async findOne(request:Request, response:Response)` Copying and pasting the first set of codes we used from our **Get**, we will just replace the `findAll` with `findOne`. 
- `const id = Number(request.params.id);` this part dictates which ID we wanted to fetch from our data.

Of course, right after connecting **UserService.ts** and  **UserController.ts**, we will then need to connect those with **UserRouter.ts**.

![UserRouter](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hoohwt92jvd6k8sb906s.png)

Using: `userRouter.get("/users/:id", UserController.findOne);`, take note of the added parameter `:id` which we will then access into the controller.

What we just concluded was the HTTP verb **GET** which also means **Read** or to view the fetched data.

After that, we can now proceed to the remaining HTTP verbs such as (Get, Post, Put, Patch...)

The next HTTP verb we will be tackling is the **POST** verb or **Create**.

Let us then go back to **UserServices.ts** and encode this:
```
async createUser(newuser: User){
        const user = this.userRepository.create(newuser)
        await this.userRepository.save(user);
        return user;
    }
```
> - `async createUser` similar to what was stated earlier, async function allows functions to be defined in a sequential, synchronous manner and *createUser* then deals with the creation of items within the User.
- `(newuser: User)` is a parameter; Parameter is a variable used in a function to refer to one of the pieces of data provided as input to the function.
- `const user = this.userRepository.create(newuser)` Creates a new instance of User. 
- `await this.userRepository.save(user);` await is used to unwrap promises by passing a Promise as the expression.
- `return user;` return statement ends the execution of a function, and returns control to the calling function.

Afterwards, we will then proceed into our ***UserController.ts*** file and connect it with ***UserService.ts***; to connect them together, we will use:

```
static async create(request:Request, response:Response){
        const data = await userRepository.createUser(request.body);
        return response.status(201).send(data);
    }
```
We use the status code 201 as it shows that a data has been created. 

And then of course, the next step is to connect the two to the **UserRouter.ts**, where we will just add `userRouter.post("/users", UserController.create);` into the previous codes we encoded beforehand.

We use **Post** as our HTTP verb because we want to be able to **Create** items.

![post router](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/502s447t7054hdc64pji.png)

The logic is fairly similar, if not the same, to the previous steps and codes we have done and encoded before. 

The data we are sending can be found in our **User.ts** file within our entity folder.

![entity](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/alv1jn5o0q11emj1ppun.png)

The `firstName`, `lastName` and `age`, which can be interchangable depending on what use you need it to. Furthermore, ID does not need to be sent seeing as it is a primary key and is autoincremented. 

Do make sure that the data that will be encoded in the Postman is the same as the data in the entity, including the format and casing.

By this point, we are now able to view and create data. To test the waters, let us then open our terminal, and run the codes.

```
$ npm run dev
```
Once successful, the bottom lines of the terminal will show this:

![1strun](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/46a0cjqhl4mb4lx4md4d.png)

Go ahead and copy the highlighted part and paste it into your Postman using the *request* we have created at the beginning of this lesson. 

This is what your Postman would look like:

![postman1] (https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6gjaii6h521kyebewgq2.png)

Firstly, copying and pasting the highlighted parts on your terminal will not show the results of the project. We will need to add *public* into the link first: `http://localhost:3000/public/users` 

If we try to view our data using **GET**, this is what Postman will show:

![Postman 3](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cax52j71lb768ss6554y.png)

See the **open and closed brackets '[]'** on the console at the bottom part. This is shown because no data has been encoded into our database just yet. 

Similarly, pgAdmin will show an empty output due to the same reason.

![pgadmin](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xo0t1gnndg44croxz01b.png)

To be able to successfully **GET** data, what we will be doing first is to create data using the HTTP verb **POST**. 

To do that, choose *POST* on the dropdown menu on the left most part, then look for *Body* and choose *raw* and lastly *JSON* on the right most as shown on the photo below. 

![postman 2] (https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tbnyf7oomzxib085h6uw.png)

On the panel right below, we can now encode our data basing on the entities that we have from our *User.ts* file within our *entity* folder. 

![data entry](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xmhmdy483j4m41nvml1a.png)
```
{
    "firstName": " ",
    "lastName": " ",
    "age": 
}
```
Using this format, we can now add our data by clicking on SEND.

![postman POST](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/f3v2pah9opy1eesw6vxb.png)

The panel at the bottom shows the contents of our database. Note that the ID has already been generated. _(Normally, the ID starts with #1 but since I have deleted the previous contents, mine started with #12 instead.)_

We can then view the contents of our database using **GET**. To do that, simply go to the left most part beside the URL, choose **GET** from the dropdown menu and then send.

To individually view our data, we can call on their ID's by simply adding `*/id number*` at the end of the url link.

Here's an example:

![indiv get](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jhki4s3m7n6m5giccqpq.png)

after clicking send, Postman will then show this result:

![indiv get result](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vyxa2ibfge0wzslu1xu9.png)

The bottom panel then shows the data with the ID number 12.

Moving on to the next HTTP verb, we will be learning **PUT & PATCH** which means to **Update**.

As usual, let us first open our **UserService.ts** and encode this:

```
    async updateUser(id: number, data: Partial<User>) {
        const user = await this.userRepository.findOne({ where: { id } });
        if (user) {
            this.userRepository.merge(user, data);
            await this.userRepository.save(user);
            return user;
        } else {
            return { message: "User not found"};
        }
    }
```

> - `async updateUser(id: number, data: Partial<User>)`: similar to fetching specific data, to update, we will also need an identifyer which is the primary key: `id:`.
-  `const user = await this.userRepository.findOne({ where: { id } });`: we use `findOne` to identify the _user_ that needs updating.
- `if (user) {`: if statement refers to a condition that will be answered by the else statement.
- `this.userRepository.merge(user, data);` : this part merges the original data with the updated one.
- `await this.userRepository.save(user);` : saves the newly updated data. 

Afterwards. we will then proceed once again to **UserController.ts**.

```
static async update(request: Request, response: Response) {
        const id = Number(request.params.id);
        const data = await userRepository.updateUser(id, request.body);
        return response.send(data);
    }
```
> - `const id = Number(request.params.id);` similarly to what was included within UserService.ts, this parameter is needed to fetch the id that sent the request.

Next, let us then proceed to **UserRouter.ts**.
![PUT ROUTER](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/b9uqgqtgx05cgxwxtxi2.png)

By this, we can now update our data in our database. 

![postman upd](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7cz8iui7xelvfad5sp3q.png)

Within Postman, we can update data using the HTTP verb **PUT** and indicating the ID number right at the end of the url link.

```
{
    "firstName": " ",
    "lastName": " ",
    "age": 
}
```
To update, similar with **POST**, we will just need to encode the above code. Of course, updating data is not limited to all of the entities included within our **User.ts** file, we can update even one entity or two depending on what was needed.

Here is an example:

![PUT EXAMPLE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/23mcotyiffxm03p8f9yc.png)

Above is ID #12's original data. 

I will then be updating ID #12's data into this:

![PUT EX 2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s9wuoaz591mi0afqkt6b.png)

Here is the result shown after submitting the request:

![PUT RESULT](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/glc87otyehktb6c0eb3y.png)

ID #12's last name and age have been updated as per request using **PUT**.

By this, we can now move on to the final part which is **Delete**. 

Within **UserService.ts**, we will use:

```
async delete(id:number){
        const user = await this.userRepository.findOne({ where: { id } });
        if(user){
            await this.userRepository.remove(user);
            return { message: "User Successfully Removed" };
        } else {
            return { message: "User not found"};
        }
    }
```
> - `return { message: "User Successfully Removed" };` return message is optional but it helps to indicate if the request has been fulfilled.

Then, in our **UserController.ts**, we will then use:

```
static async delete(request: Request, response: Response){
        const id = Number(request.params.id);
        const data = await userRepository.delete(id);
        return response.send(data);
    }
```
By copying and pasting the codes on the previous verbs that are quite similar to how the Delete function works, we can now move to **UserRouter.ts**.

![router delete ey](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5zozr24zk8ad09l56x8c.png)

After saving, we can now proceed to Postman~ 

![DELETE POSTMAN](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r1bcpr00vtvgxaiyrxt4.png)

Simply choose **DELETE** on the drop down on the left most part AND adding the ID number at the end of the url will result to this:

![DELETE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gh8jkykt0rvxo5adqf3s.png)

---

With this, we have learned how to operate CRUD using Express TypeORM.