# api-decorator

> Node API Decorator

Latest version **1.0.0** (published 2021-02-22) · MIT license · 0 weekly downloads

## Install

```sh
npm install api-decorator
pnpm add api-decorator
yarn add api-decorator
bun add api-decorator
```

## Health

**Score 30/100 (F)** — status: abandoned.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2021-02-22 |
| First published | 2021-02-20 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=10.0.0 |
| Dependencies | 3 |
| Unpacked size | 251 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 2 |
| Author | Alan Dias |
| Maintainers | alan.dias |
| Keywords | api-decorator, annotations, api, rest, restful |

## Links

- npm: https://www.npmjs.com/package/api-decorator
- Repository: https://github.com/alanaugustodias/api-decorator
- Homepage: https://github.com/alanaugustodias/api-decorator/blob/main/README.md
- Issues: https://github.com/alanaugustodias/api-decorator/issues
- npm.io page: https://npm.io/package/api-decorator

## Dependencies (3)

- [express](https://npm.io/package/express.md) ^4.17.1
- [cosmiconfig](https://npm.io/package/cosmiconfig.md) ^7.0.0
- [reflect-metadata](https://npm.io/package/reflect-metadata.md) ^0.1.13

## Alternatives

- [launchdarkly-js-client-sdk](https://npm.io/package/launchdarkly-js-client-sdk.md) — 2.5M weekly downloads
- [@elastic/elasticsearch](https://npm.io/package/@elastic/elasticsearch.md) — 2.1M weekly downloads
- [@c8y/client](https://npm.io/package/@c8y/client.md) — 15.3K weekly downloads
- [@signaldb/maverickjs](https://npm.io/package/@signaldb/maverickjs.md) — 1.7K weekly downloads
- [@bbc/http-transport-cache](https://npm.io/package/@bbc/http-transport-cache.md) — 1.2K weekly downloads

## Recent versions

- 1.0.0 (latest) — 2021-02-22
- 0.2.0-rc.1 — 2021-02-22
- 0.1.0-rc.6 — 2021-02-21
- 0.1.0-rc.4 — 2021-02-21
- 0.1.0-rc.3 — 2021-02-21
- 0.1.0-rc.2 — 2021-02-21
- 0.1.0-rc.1 — 2021-02-21
- 0.1.0 — 2021-02-20

## README

# Node API Decorator

Elegant decorators that make your API easy and classy.

---

### Table of Contents

**[Motivation](#motivation)**<br>
**[Getting Started](#getting-started)**<br>
**[Configs](#configs)**<br>

## Motivation

Thinking of a cleaner way of developing NodeJs APIs, Node API Decorator was created.

When developing Node APIs using [Express](https://expressjs.com/), some steps are required in order to achive the basic usage of the tool:

-   Creating the router

`const router = express.Router();`

-   Vinculating the API resources

`router.get('my-api-resource', function(request, response) {});`

-   Attaching the router to the server

`server.use('api-base-path', router);`

This is not a difficult thing to do, but in terms os scalability and readability things might get a bit hard to maintain.

When designing the structure of your API, one of the common concerns is: having a simple way to handle routes (resources).

This not only involves declaring the resources, but also receiving the content from a Request and returning to a Response.

That's the main purpose of this library: to help you improving the quality of your code by structuring the basics for you.

---

## Decorators availables so far

| Decorator     | Description                                           | Params           | Mandatory | Default Value |
| ------------- | ----------------------------------------------------- | ---------------- | :-------: | :-----------: |
| `@Controller` | The class serving as prefix for the route endpoints   | `prefix: string` |    No     |     `''`      |
| `@Route`      | The route endpoint for a method on a Controller class | `path: string`   |    No     |     `''`      |
| `@Req`        | The Request parameter for an endpoint method          | -                |     -     |       -       |
| `@Res`        | The Response parameter for an endpoint method         | -                |     -     |       -       |
| `@Body`       | The Body parameter for an endpoint method             | -                |     -     |       -       |
| `@Query`      | The Query parameter for an endpoint method            | -                |     -     |       -       |
| `@Path`       | The Path parameter for an endpoint method             | `paramName`      |    Yes    |       -       |

## Experimental Decorators

| Decorator     | Description                                                      | Params               |              Mandatory              | Default Value |
| ------------- | ---------------------------------------------------------------- | -------------------- | :---------------------------------: | :-----------: |
| `@Injectable` | Put it on a class you want to make it injectable                 | -                    |                  -                  |       -       |
| `@Inject`     | It sets a class's attribute with the ref for an Injectable class | `identifier: symbol` | Symbol for the class to be injected |       -       |

## Getting Started

`npm install api-decorator`

To start using the decorators for the API (resources), you should firstly follow a minimum standard, so that this library can do its best to help you out.


[** Project Sample **](https://github.com/alanaugustodias/api-decorator/tree/master/sample)


### Controllers

I'm calling here *Controllers* the files where you're about to put your resources declarations.

They must export as default a class, which will be instantiated and associated on Express.

- Project structure sample:

```
src
|___controllers
|    |   UserController.ts
|    |   index.ts
|   index.ts
```

- Example of a Controller:

```javascript
// controllers/user.controller.js
import {Controller, Post, Get, Body, Query} from 'api-decorator';

@Controller('/user')
export default class UserController {
    @Post()
    createUser(@Body() user) {
        return this.userService.create(user);
    }

    @Get('/custom-get')
    customGetUser(@Query() query) {
        return this.userService.get(query);
    }
}
```

By declaring the `@Controller` with `'/user'`, we are attaching this route on Express with this prefix.

The same way that when declaring `@Get` with `'/custom-get'`, we are attaching the concatenation of `/user` + `/custom-get`.

After having your controllers created, you should export them in a `index` file, just like below:

```javascript
// controllers/index.js
export {default as UserController} from './user.controller.ts';
```

- Pro-tip:

When writing a Controller, you can return an object of type `ApiResponse`.

This interface handles `status` and `data`, so that you don't need to inject `@Res` just for sending a custom status.

`ApiResponse` shape:

```javascript
interface ApiResponse {
    status: number;
    data: any;
}
```


Now, you only have to tell *api-decorator* where your main controllers exporter is located.

You can create a config file, according to the [Configs](#configs) section.

- Example of a startup file (`index.ts`)

```javascript
import express from 'express';
import {BindRoutes} from 'api-decorator';

async function startup() {
    const app = express();
    const routes = await BindRoutes();
    app.use('/', routes);
    const server = app.listen(this.port, () => {
        console.log(`Server is listening on: ${this.port}`);
    });
}

startup();
```

On the example above, you can see that we are importing `BindRoutes` function from _api-decorator_.

This is the function that, with the help of the configuration file on finding the Controllers, will bind every endpoint we declare to _express's Router_

After having the result of the asynchronous `BindRoutes`, you can just use it with the prefix you want for your API, just like: `api.use('/any-thing-you-want', routesBinded)`.

---

### Injectables

As part of the experimental decorators, we have `@Injectables` and `@Inject`.

- `@Injectable``

This decorator is meant to be used on a class you'd like to use its reference injected on a class attribute.

It uses a service for controlling the instance of the injectables, so you will use them as [Singletons](https://en.wikipedia.org/wiki/Singleton_pattern).

To keep a track on every class injected, we use the name of the class on a Symbol.

Example:

```javascript
@Injectable()
class MyService {
    public getName() {
        return 'Name';
    }
}
```

This will add to the injector service an instance of `MyService` tracked by `Symbol.for('MyService')`,

- `@Inject`

This decorator injects an instance of an injectable class.

You must pass as parameter a Symbol with the name of the desired class, so it will set automatically to the related attribute.

Example:

```javascript
import MyService from './my-service.ts';

class MyClass {
    @Inject(Symbol.for('MyService'))
    private _myService: MyService;
}
```

This will retrieve the instance for `MyService` within the injector controller.

- Pro-tip

In order to maintain the injectables names more legible, you could create a constant for that:

```javascript
import MyService from './my-service.ts';

const Injectables = {
    MyService: Symbol.for('MyService')
}

class MyClass {
    @Inject(Injectables.MyService)
    private _myService: MyService;
}
```


## Configs

You can create a file `.apidecoratorrc` on the root folder of your project, and put there the configurations you need.

Example of a file:

```json
{
    "controllers": "src/controllers/index.ts"
}
```

| Key         | Description                             | Example                    | Mandatory | Default Value |
| ----------- | --------------------------------------- | -------------------------- | :-------: | :-----------: |
| controllers | The path for your controllers exporters | "src/controllers/index.ts" |    Yes    |       -       |

---
_Source: https://npm.io/package/api-decorator · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
