1.0.0 • Published 3 years ago

api-decorator v1.0.0

Weekly downloads
341
License
MIT
Repository
github
Last release
3 years ago

Node API Decorator

Elegant decorators that make your API easy and classy.


Table of Contents

Motivation Getting Started Configs

Motivation

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

When developing Node APIs using Express, 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

DecoratorDescriptionParamsMandatoryDefault Value
@ControllerThe class serving as prefix for the route endpointsprefix: stringNo''
@RouteThe route endpoint for a method on a Controller classpath: stringNo''
@ReqThe Request parameter for an endpoint method---
@ResThe Response parameter for an endpoint method---
@BodyThe Body parameter for an endpoint method---
@QueryThe Query parameter for an endpoint method---
@PathThe Path parameter for an endpoint methodparamNameYes-

Experimental Decorators

DecoratorDescriptionParamsMandatoryDefault Value
@InjectablePut it on a class you want to make it injectable---
@InjectIt sets a class's attribute with the ref for an Injectable classidentifier: symbolSymbol 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

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:

// 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:

// 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:

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 section.

  • Example of a startup file (index.ts)
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.

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

Example:

@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:

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:

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:

{
    "controllers": "src/controllers/index.ts"
}
KeyDescriptionExampleMandatoryDefault Value
controllersThe path for your controllers exporters"src/controllers/index.ts"Yes-
1.0.0

3 years ago

0.2.0-rc.1

3 years ago

0.1.0-rc.6

3 years ago

0.1.0-rc.3

3 years ago

0.1.0-rc.4

3 years ago

0.1.0-rc.2

3 years ago

0.1.0-rc.1

3 years ago

0.1.0

3 years ago