Minimalist express/typescript clean boilerplate - inspired from Laravel framework
- This is an express boilerplate based on TypeScript, you can clone it and start coding
- Cover SOLID principles
- Please read Official Documentation
- TypeScript compiler
- Express
- Nodemon watcher (hot reload)
- Active sourcemap for debugging
- TS-lint
- ES6 support
- Mongoose ORM
- MongoDB connection
- Multiple env
- Standard API response
- Middleware configurations
- Basic CRUD
- Clone the repo
git clone https://github.com/binaryk/node-ts-boilerplate.git
cd
to the working directory- Run
yarn
ornpm install
- Run
npm install -g tsc
(to install globally typescript transpiler) - Install MongoDB and run it (
mongod
) - Run
npm watch
- to watch your file updates - Open postman and try
GET: http://127.0.0.1:3000/sample
, you will receive: - Add your MongoDB configuration in
src/config/database.ts
- Add your own routes in
src/routes
- Add your own controllers in
src/controllers
- Add your own models in
src/models
- Enjoy development
config/database.ts
is the configuration file for the database - Default mongo arguments are stored there
- You can leave the black box of the core to configure your application, based on your defined routes and middlewares from the
config/middlewares.ts - middleware object
, or, you can do this manually in theapp.ts
:
this.core = new Core(this.app, {
/**
* Activate global middlewares from the `config/middeware.ts`
*/
globalMiddleware: false
});
this.core.use(bodyParser.json());
// this.core.use(/* other middleware function */)
/*!important, init routes*/
this.core.initRoutes();
- API has a customizable monkey patching, which extends the default
res
express object with a new functionrespond
. This is useful to have aStandard API Response
with the format:
data: data,
message: message,
responseCode: responseCode
- To use this standard it's enough to write:
this.router.get('sample', (req, res, next) => {
res.respond({
foo: 'Standard data from API',
}, `Standard message from API`, 201 )
});
-
- For CRUD
contact
instance you can use thegroup
wrapper - Add prefix with middleware keys to the routes group like this:
- For CRUD
this.router.group({
prefix: 'contact',
middleware: ['session', 'auth:admin']
}, (router) => {
router.post('', this.contactController.store);
router.get(':contactId', this.contactController.getContactWithID);
router.get('', this.contactController.getContacts);
router.post('', this.contactController.store);
router.put(':contactId', this.contactController.updateContact);
router.delete(':contactId', this.contactController.deleteContact);
})
I. You have two options to define a middleware:
- to declare callback function directly:
foo: (req, res, next) => {
console.log('First middle');
next();
},
- Add your file with middleware in
/src/http/middleware*
- Bellow we have an example of an empty middleware:
export class Authenticate {
constructor () {
}
public handle(req, res, next) {
console.log('Authenticate middleware - check if is authenticated');
next();
}
}
| โ | The handle method is required!
II. Declare it in src/config/middleware.ts
export const routesMiddleware = {
auth: Authenticate,
session: (req, res, next) => {
console.log('Local definition');
next();
}
};
III. In the Route
definition, just add the key of the middleware, like this:
this.router.group({
middleware: 'auth'
}, (router) => {
Array of middlewares:
middleware: ['auth', 'session']
IV. Define these two middlewares in a middleware group:
export const groupsMiddleware = {
web: [
StartSession,
Authenticate
]
};
And use it like:
prefix: 'group',
middleware: 'web'
}, r => {
V. Send arguments to the middleware functions from the definition:
this.router.group({
prefix: 'group',
middleware: 'auth:admin,user'
},
- Now I can get my arguments as an array like: ['admin', 'user'] in the
auth
middleware, BUT, there you should implementhandle
function, which returns an middelware signature
public handle(args) {
return (req, res, next) => {
console.log(args, 'Encapsuleted arguments from the route');
next();
};
}
- In
config/middlewares.ts
we have an object for global middleware definitions, allowed format are:
- Class with an handle function
- Simple callback function
- Array of callback functions
export const middleware = {
bodyParser: [
bodyParser.json(),
bodyParser.urlencoded({ extended: false })
],
application: Application,
foo: [(req, res, next) => {
console.log('First middle');
next();
}, (req, res, next) => {
console.log('Second middle');
next();
}]
};
Use express router as default
- In your route definition just use it through
this.router
:
this.router.get('/sample', (req, res, next) => {
res.json({
'data': 'test'
});
});
- Framework will expose the class
Exception
for error handling and HttpErrors catch:
router.get('/funny-page', (req, res, next) => {
throw new Exception('not-implemented', 501, {
data: 'foo'
});
})
The issue list of this repo is exclusively for bug reports and feature requests. Feel free to open a PR of issue.
- Props to Dale Guyen for this article, this project was started based on it arhitecture
Copyright (c) 2018-present, Binaryk (Eduard) Lupacescu