This package has been deprecated

Author message:

This package was moved at https://www.npmjs.com/package/adr-express-ts . Major bugs were also fixed in the new version

express-adr-dependency-injection-typescript
TypeScript icon, indicating that this package has built-in type declarations

2.4.2 • Public • Published

Express ADR Dependency Injection Typescript

EADIT CI EADIT-CLI CI

This package is a dependency injection for express with typescript using decorators and the Action–Domain–Responder pattern.

Getting Started

Create

Use my CLI to create the application. Instead of "myFolderName" you can add "." to install it in the current directory. Always use npx to use the latest version of the CLI.

npx eadit-cli create myFolderName

Template Check

You will be asked to choose a template. For this one you have to select Express

? What template do you want? (Use arrow keys)
❯ Express
  Discord.js

Path Check

You will get the following question:

? Is the path correct? ('/my/path/to/application') (Y/n)

If the path is correct respond with Y or press Enter

Yarn Check

If you have Yarn installed, the CLI will ask if you want to use it, if you say N npm will be used.

? Yarn was detected on your system, do you want to use Yarn? (Y/n)

Dependency Selector

For the next part you can choose if you need more dependencies (They will be automaticly injected). Question 2

Dialect Selector (Only for Sequelize) and complete extra information

If you choose Sequelize, you will also be asked to choose which dialect you want and to complete the connection information. Question 3

Check if directory is empty

If the directory you want to create the application is not empty, you will be asked if you want to remove all files from it. If you don't remove the files the project will not be created.

? The current directory is not empty, do you want to clear it? (y/N)

Finish

After everything is installed, you should see the following output. Final

About Action–Domain–Responder

  • The action takes HTTP requests (URLs and their methods) and uses that input to interact with the domain, after which it passes the domain's output to one and only one responder.
  • The domain can modify state, interacting with storage and/or manipulating data as needed. It contains the business logic.
  • The responder builds the entire HTTP response from the domain's output which is given to it by the action.
  • The entity is the model for the database

Project structure

/src

# Here you define the tests, there are default tests defined.

- /**tests**

- /actions

# Here you define the route and the methods (get, post, put, delete)

# Are automatically injectetd!

- - action.ts

- /app

# Here you start the server (app.listen) and other checks before/after starting.

- - Server.ts

- /domain
- - /entities

# Here you define the entiry (They are accessed with @Retrive('Entity.NAME') or from your ORM)

# Are automatically injectetd!

- - - entity.ts

# Here you define the domain (They are accessed with @Retrive('Domain.NAME'))

# Are automatically injectetd!

- - domain.ts

- /middlewares

# Here you define middlewares (as classes).

# You inject them manually

- - middleware.ts

/public

# In public (depends on the Configuration made in index.ts) you have the front-end,

# all routes point to index.html (i made it so it can work with React)

- - index.html

- /responders

# Here you define the domains (They are accessed with @Retrive('Responder.NAME'))

# Are automatically injectetd!

- - responder.ts

# Here you inject classes, middlewares, variables, functions, server, router, etc.

# And you have to call Injector.ready(); when you finished all your injections.

- index.ts

Configuration

Injector.inject(
  'Configuration',
  {
    root: __dirname,
    restPrefix: '/api',
    debug: {
      log: console.log,
      error: console.error
    },
    renderEngine: {
      path: '/',
      directory: ['public']
    }
  } as Configuration,
  InjectType.Variable
);

Entity Model

This model is for Mongoose.

@Inject
@Entity('User')
export default class UserEntity implements InjectedEntity {
  @Retrive('Mongoose')
  private mongoose?: MongooseClass;

  async onLoad(): Promise<void> {
    if (!this.mongoose) {
      return;
    }

    const { ObjectId } = Schema as any;

    this.mongoose.model(
      'User',
      new Schema({
        id: ObjectId,
        email: {
          type: String,
          min: 3,
          max: 255,
          required: true
        },
        password: {
          type: String,
          min: 8,
          required: true
        }
      })
    );
  }
}

Responder Model

import { Inject } from 'express-adr-dependency-injection-typescript/lib/Injector';
import { Responder } from 'express-adr-dependency-injection-typescript/lib/Router';
import { Response } from 'express';

@Inject
@Responder('Demo')
export default class DemoResponder {
  public success(res: Response) {
    return res.status(200).json({
      success: true
    });
  }

  public demo(res: Response, status: number, output: any) {
    return res.status(status).json(output);
  }
}

Middleware Model

import { Request, Response, NextFunction } from 'express';
import {
  Inject,
  MiddlewareClass
} from 'express-adr-dependency-injection-typescript/lib/Injector';

@Inject
export default class AuthentificationMiddleware implements MiddlewareClass {
  public async middleware(
    req: Request,
    res: Response,
    next: NextFunction
  ): Promise<any> {
    (req as any).myData = 'My custom request data!';
    return next();
  }
}

Action Model

import {
  Action,
  Get,
  Post,
  Put,
  Delete,
  Request,
  Response
} from 'express-adr-dependency-injection-typescript/lib/Router';
import {
  Request as ExpressRequest,
  Response as ExpressResponse
} from 'express';
import { Retrive } from 'express-adr-dependency-injection-typescript/lib/Injector';

import DemoResponder from '../responders/DemoResponder';
import DemoDomain from '../domain/DemoDomain';

@Action('/demo', ['MiddlewareHere'])
export default class DemoAction {
  @Retrive('Responder.Demo')
  private responder?: DemoResponder;

  @Retrive('Domain.Demo')
  private domain?: DemoDomain;

  @Get('/demo1', ['MiddlwareHere'])
  public findAll(
    @Request req: ExpressRequest,
    @Response res: ExpressResponse
  ): any {
    return res.send({
      success: true,
      test: (req as any).myData
    });
  }

  @Post()
  public async saveX(
    @Request req: ExpressRequest,
    @Response res: ExpressResponse
  ): Promise<any> {
    const dataFromDatabase = await this.domain!.test('parameter from action');
    return this.responder!.demo(res, 201, dataFromDatabase);
  }

  @Delete()
  public async deleteY(
    @Request req: ExpressRequest,
    @Response res: ExpressResponse
  ): Promise<any> {
    return this.responder!.success(res);
  }
}

Domain Model

import { Inject } from 'express-adr-dependency-injection-typescript/lib/Injector';
import { Domain } from 'express-adr-dependency-injection-typescript/lib/Router';

@Inject
@Domain('Demo')
export default class DemoDomain {
  public async test(someParameter: string) {
    return {
      success: true,
      data: 'Data from database',
      someParameter
    };
  }
}

Server.ts Example

import {
  Inject,
  InjectedClass,
  Retrive
} from 'express-adr-dependency-injection-typescript/lib/Injector';
import { Application } from 'express';
import { Configuration } from 'express-adr-dependency-injection-typescript/lib/Configuration';

@Inject
export default class Server implements InjectedClass {
  @Retrive('ExpressApp')
  private application?: Application;

  @Retrive('Configuration')
  private config?: Configuration;

  @Retrive('Middlewares')
  private middlewares?: any;

  public async onReady(): Promise<void> {
    try {
      if (!this.application || !this.config) {
        return;
      }

      const log = this.config.debug.log ?? console.log;

      this.application.listen(4000, '0.0.0.0', async () => {
        log('Server started %o', '0.0.0.0:4000');
      });
    } catch (e) {
      const error = this.config?.debug.error ?? console.error;
      error(e);
    }
  }
}

Package Sidebar

Install

npm i express-adr-dependency-injection-typescript

Weekly Downloads

20

Version

2.4.2

License

MIT

Unpacked Size

105 kB

Total Files

31

Last publish

Collaborators

  • npm