How to solve REST API routing problem with decorators?
Tags: node, typescript, javascript, express
Published: 2022-03-23 17:43:13

#### Decorators Introduction:
A Decorator is a special kind of declaration that can be attached to a class declaration, method, accessor, property, or parameter.


We’ll be using Method Decorators to develop routesDecorator.
#### Method Decorators:
A Method Decorator is declared just before a method declaration. The decorator is applied to the Property Descriptor for the method and can be used to observe, modify, or replace a method definition. A method decorator cannot be used in a declaration file, on overload, or in any other ambient context (such as in a declare class).

The expression for the method decorator will be called as a function at runtime, with the following three arguments:

- Either the constructor function of the class for a static member, or the prototype of the class for an instance member.
- The name of the member.
- The Property Descriptor for the member.

Definition referred from typescript official site, Check more details about [Method Decorators here](https://www.typescriptlang.org/docs/handbook/decorators.html#method-decorators)

> **NOTE: Decorators are an experimental feature that may change in future releases.**

---

Decorators use the form **@expression**, where **expression** must evaluate to a function that will be called at run-time with information about the decorated declaration.

##### Prerequisite:

- Make sure you have installed the latest Node.js
- Basic knowledge of javascript, typescript, node.js, and express.js
- Code editor (vs code)


#### Step 1:
Open the terminal and run the following command
```javascript
mkdir decorator-routes //create directory
cd decorator-routes
```
---

#### Step 2:
Initialize the Node.js project using the following command from the terminal
```javascript
npm init
```
Your package.json will look like this.
###### package.json:
```json
{
  "name": "decorator-routes",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
```
---

#### Step 3:
Install dependencies using the following command.

```javascript
npm i express --save
npm i typescript @types/express -D
```

_**Note:** -D marks things as “used for development” while --save (which is the default, and therefore optional) means “used by the program when it is deployed”._

**@types** packages provide type information to TypeScript, but they are not used when your code is running/deployed.

**Tip:** **npm i** is a shortcut for npm install, and **-D** is a short for --save-dev.

###### package.json
```json
{
  ...
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {
    "@types/express": "^4.17.13",
    "typescript": "^4.6.2"
  }
}
```
---

#### Step 4:
Add tsc and start scripts in the package.json

###### package.json
```json
{
  ...
  "scripts": {
    "prestart": "tsc",
    "start": "node ./dist/server.js"
  },
  ...
}
```
---

#### Step 5: 
Create tsconfing.json and enable experimentalDecorators

Create a text file called **tsconfig.json** in your root folder, put below code in it:
To enable experimental support for decorators, you must enable the **experimentalDecorators** in your **tsconfig.json**

###### tsconfig.json
```json
{
    "compilerOptions": {
        "module": "commonjs",
        "lib": ["ES2018"],
        "target": "es2017",
        "noImplicitAny": true,
        "removeComments": true,
        "preserveConstEnums": true,
        "outDir": "dist",
        "experimentalDecorators": true,
        "sourceMap": true
    },
    "include": [
        "src/**/*"
    ],
    "exclude": [
        "node_modules",
        "**/*.spec.ts"
    ]
}
```

---

#### Step: 6

- Create a src the directory in your root folder
- Create subdirectories(controllers, decorators) inside src.
![How to make REST API’s using Node.js, Express.js & Typescript Decorators](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/52swrcczjkoew81hg7pg.png "How to make REST API’s using Node.js, Express.js & Typescript Decorators")

---

#### Step: 7 
Create a text file called **routes.decorator.ts** inside src/decorators folder, and add below code in it:

###### src/decorators/routes.decorator.ts
```javascript
import { Router } from 'express';
export const appRouter = Router();

interface IOptions {
    path: string;
    method: 'get'| 'post'| 'put' | 'delete' ;
    middlewares?: any[],
}

function routesDecorator(options: IOptions) {
    return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {
       (appRouter as any)[options.method](options.path, target[propertyKey]);
    };
}
export default routesDecorator;
```

##### Create a index.ts inside src/decorators folder, and add below code in it:
###### src/decorators/index.ts
```javascript
export * from './routes.decorator';
```

##### Create a Users.controller.ts inside src/controllers folder, and add below code in it:

###### src/controllers/Users.controller.ts
```javascript
import { Request, Response } from 'express';
import routes from '../decorators/routes.decorator';
export class Users {
    @routes({
        path: '/users',
        method: 'get'
    })
    getUsers(req: Request, res: Response) {
        res.send('Typescript Decorators are awesome !!!');
    }
}
```

##### Create a index.ts inside src/controllers folder, and add below code in it:

###### src/controllers/index.ts
```javascript
export * from ‘./Users.controller’;
```

##### Create a server.ts inside src folder, and add below code in it:

###### src/server.ts
```javascript
import * as express from 'express';
const app = express();
import './controllers';
import { appRouter } from './decorators/routes.decorator';
app.use(appRouter);
app.listen(3000,()=>{
    console.log('Server is running on port 3000');
});
```
---

#### Step: 8
Run the following command from the terminal
```javascript
npm run start
```
Open browser or any REST client and go to
```javascript
http://localhost:3000/users
```

---

![](https://media.giphy.com/media/IaumTNeJTOtIYf5jSZ/giphy.gif)

#### Live Example: [Demo](https://stackblitz.com/edit/rest-apis-using-node-js-express-js-typescript-decorators)

Got any questions or additional? please leave a comment.

Thank you for reading 😊

--- 

### Must Read If you haven't

{% link  https://dev.to/devsmitra/3-steps-to-create-custom-state-management-library-with-react-hooks-and-context-api-1bfh %}
{% link  https://dev.to/devsmitra/how-to-cancel-javascript-api-request-with-abortcontroller-36cm %}
{% link  https://dev.to/devsmitra/getting-started-with-solidjs-a-beginners-guide-5af4 %}



### Catch me on
{% user devsmitra %}
<p>
{% cta https://www.youtube.com/@bit-buddy?sub_confirmation=1 %} Youtube {% endcta %}
{% cta https://github.com/devsmitra %} Github {% endcta %}
{% cta https://www.linkedin.com/in/rahul-sharma-18b8b374 %} LinkedIn {% endcta %}
{% cta https://devsmitra.medium.com %} Medium {% endcta %}
{% cta https://stackblitz.com/@devsmitra %} Stackblitz {% endcta %} {% cta https://devsmitra.hashnode.dev %} Hashnode {% endcta %}
{% cta https://hackernoon.com/u/devsmitra %} HackerNoon {% endcta %}
</p>