Development
After writing your documentation, you can start implementation.
Listing the dependency
Before implementation, it is always good to list out what dependency you will use.
You may ask:
- Does this new feature relate to any existing
Controller,ServiceorRepository? - Any new third-party library you will use?
- Any sharable logic (e.g. Rate Limiting, Localization)?
Update application container
Adding Controller
In this example, we add a TodoController
@controller("/todo") export class TodoController extends BaseHttpController { constructor(@inject(TYPES.TodoService) private todoService: TodoService) { super(); } @httpGet("/") public async getTodos(@response() res: Response) { const result: DataObject<ITodo[]> = new DataObject( await this.todoService.getTodos(), 200 ); res.status(result.status).send(result.asJson()); } }
We need to add this line in server.ts for the server to read meta data
import "./controller/todo";
Also, we need to load TodoService into AppContainer
export class AppContainer { constructor() {} public async load(): Promise<Container> { const container = new Container(); container.bind<TodoRepository>(TYPES.TodoRepository).to(TodoRepository); return container; } }
Adding Service
Adding Repository
Adding Middleware
Middleware helps to pre-process request object.
In this example, we use LocalizationMiddleware to get current locale (a LocalizedMessage object).
LocalizationMiddleware will use Localization to get a LocalizedMessage, so we need to inject it.
@injectable() export class LocalizationMiddleware extends BaseMiddleware { handler(req: Request, res: Response, next: NextFunction): void { const messageStore: LocalizedMessage = this.localeManager.of( req.acceptsLanguages() ); // Bind it into a TYPES instead of adding it into req object this.bind<LocalizedMessage>(TYPES.LocalizedMessage).toConstantValue( messageStore ); next(); } // Inject Localization object, instead of using a singleton object constructor(@inject(TYPES.Localization) private localeManager: Localization) { super(); } }
After implementing the middleware, we need to load it in AppContainer
export class AppContainer { constructor() {} public async load(): Promise<Container> { const container = new Container(); container .bind<LocalizationMiddleware>(TYPES.LocalizationMiddleware) .to(LocalizationMiddleware); const localeManger: Localization = new Localization("en"); container .bind<Localization>(TYPES.Localization) .toConstantValue(localeManger); const defaultMessage: LocalizedMessage = localeManger.defaultStore(); container .bind<LocalizedMessage>(TYPES.LocalizedMessage) .toConstantValue(defaultMessage); return container; } }
Finally, we can use it in a Controller
@controller("/todo", TYPES.LocalizationMiddleware) export class TodoController extends BaseHttpController { constructor( @inject(TYPES.TodoService) private todoService: TodoService, @inject(TYPES.LocalizedMessage) private messageStore: LocalizedMessage ) { super(); } }