Thresh
Decorative implementation of Express with TypeScript and dependency injection
Table of Contents
Installation
Install with npm
npm install thresh --save
Or yarn
yarn add thresh
Usage
Basic
The most basic implementation with no dependencies or middleware. This is an Express app listening on port 3000 for GET requests on '/hello'
. As a note /hello
could
also be a RegExp, Express path expression or an array containing any combination of
those.
; @ @ { res; } ;
Services
Services are created as singletons and are available and provided for in the decorator @Thresh
. They are immediately available in the constructor of the class that provided them, as well as the constructor of all nested routers.
The ExpressService
and RootService
are available to the root application and every nested router. ExpressService
notably contains the app
variable which is the Express Application/Router. RootService
is the ExpressService
for the root application.
; public foo: string = 'bar'; @ { console; // true thisesapp; } @ // GET http://localhost:3000/hello { res; // { foo: 'bar' } } ;
Routers
Routers are essentially identical to Apps and are also declared with @Thresh
. They will inherit services from their parents.
; public foo: string = 'bar'; @ {} @ // GET http://localhost:3000/foo/hello { res; // { foo: 'bar' } } @ {} ;
Router Scope
Services provided in routers will receive their own singletons isolated from the router's parents.
; public foo: string = 'bar'; @ { console // 'bar' thisfsfoo = 'banana'; } @ // GET http://localhost:3000/foo/hello { res; // { foo: 'banana' } } @ { thisfsfoo = 'apple'; } @ // GET http://localhost:3000/hello { res; // { foo: 'apple' } } ;
Middleware
Middleware like routes, can also be chained by passing no parameters to the class method and returning an array of middleware.
; @ @ { reqqueryname = 'Peter Parker'; ; } @ { // ^-- No Parameters return { console; ; } { reqqueryname = 'Doctor Octavius'; ; } ; } @ { res; // Hello, Peter Parker! } @ { res; // Oh no, it's Doctor Octavius } ;
Params
Parameter interceptors are assigned via the @Param
decorator. Pass in a
string with the parameter you want to intercept and act on.
; @ @ { reqqueryname = name + 'awesome'; ; } @ { res; //Hello [name]awesome! } ;
HTTP Methods
All HTTP verbs that Express supports, Thresh does as well. They can either be typed out
as a string or imported by the MethodTypes
constant. If @Method
is not defined, the
route will default to GET
.
; @ @ @ // POST: http://localhost:3000/hello { res; // Hello, world! } @ @ // PUT: http://localhost:3000/helloall { res; // Hello, everyone! } ;
Hooks
Several lifecycle hooks are available to modify the App/Router creation.
In Order:
- onInit: Express and Services initialized, but no routes/routers/middleware added yet
- afterInit: Just after the child Routers, routes and middleware have been added
- onStart: Just before Express.listen is called, only called on the root application
- afterStart: Just after Express.listen is called, only called on the root application
; @ implements afterInit @ { res; } { console; // List all routes app; // Serve public files } ;
Route/Middleware Ordering
If compiled to ES2015+ (ES6+) Routes and Middleware are applied exactly
how they appear in the class from top to bottom. Compiling further back
than that doesn't guarantee object property ordering
ECMA-262.
To overcome this a static $order: string[]
can be provided with the exact
order to apply routes/middleware in. Any @Routes
or @Middleware
not declared
in $order
will be applied after those in $order
.
; @ implements afterInit static $order = 'appliedFirst' 'appliedLast'; @ { res; // With $order: Hello, Peter Parker! // Without $order: Hello, undefined // This is because appliedLast is applied first as // it comes first in the class definition } @ { reqqueryname = 'Peter Parker'; ; } ;
Still in Development
- Providing Services within Services