Client is an entity that interacts with your application using HTTP or any other request methods.
Controller is a gatekeeper to a Facade.
It manages or directs the flow of data between the Client and a Facade.
Example of the Controller which has methods
getOne(req, res)
getMany(req, res)
createOne(req, res)
updateOne(req, res)
deleteOne(req, res)
const {
withDefaultCRUD,
withDefaultErrorProcessing
} = require('nodester/controllers/mixins');
const countriesFacade = require('#facades/countries');
module.exports = function CountriesController() {
withDefaultCRUD(this, {
facade: countriesFacade
});
withDefaultErrorProcessing(this);
}
Facade is a wrapper around model.
Example of the Facade which has methods
getOne(params)
getMany(params)
createOne(params)
updateOne(params)
deleteOne(params)
const {
withDefaultCRUD
} = require('nodester/facades/mixins');
// Model.
const Country = require('#models/Country');
module.exports = function CountriesFacade() {
withDefaultCRUD(this, {
model: Country
});
}
Filter is a set of rules on how to process Client's input.
Model is a high-level definition of a database table.
// ORM.
const DatabaseConnection = require('#db');
// Definition (nodester).
const defineModel = require('nodester/models/define');
const city = defineModel(DatabaseConnection, 'City',
(DataTypes) => ({
id: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
primaryKey: true,
autoIncrement: true,
_autoGenerated: true
},
country_id: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: false,
},
name: {
type: DataTypes.STRING(255),
allowNull: false,
}
}),
{
// Allow only "soft" delete.
paranoid: true
}
);
city.associate = ({ City, ...models }) => {
City.belongsTo(models.Country, {
foreignKey: 'country_id',
as: 'country'
});
City.hasMany(models.Area, {
foreignKey: 'city_id',
as: 'areas'
});
}
module.exports = city;
Marker is a functional condition that returns true | false
, based on data in request/response.
Markers are more powerful indicators than simple route definitions, as any parameter in request/response can be used.
For example: our application has 2 domains:
admin.awesomeapp.com
api.awesomeapp.com
You add markers and handlers specifically for those domains:
app.add.marker('ADMIN', (req) => req.get('host') === 'admin.awesomeapp.com');
app.add.marker('API', (req) => req.get('host') === 'api.awesomeapp.com');
And then use them:
app.only('ADMIN').route('get /payments', <handler/>);
app.only('API').route('get /payments', <handler/>);
// Or:
app.only('ADMIN').use(<handler/>);
app.only('API').use(<handler/>);
Router is a built-in middleware.
const Router = require('nodester/router');
const controllersPath = <path_to_controllers_directory/>;
const router = new Router({ controllersPath });
router.add.route('get /books', function(req, res) { ... } );
// Or:
router.add.route('get /books', { controlledBy: 'BooksController.getMany' } );
router.add.route('get /books/:id', { controlledBy: 'BooksController.getOne' } );
You can add custom middleware which will run when a specific route is requested.
const Router = require('nodester/router');
const controllersPath = <path_to_controllers_directory/>;
const router = new Router({ controllersPath });
const subscriptionPass = require('#middlewares/subscriptionPass');
router.add.route('get /books', {
before: subscriptionPass,
controlledBy: 'BooksController.getMany'
});
You can also provide an array of middlewares:
const middleware1 = require('...');
const middleware2 = require('...');
router.add.route('get /books', {
before: [ middleware1, middleware2 ],
controlledBy: 'BooksController.getMany'
});
Set specific Filter middleware before request hits Controller:
const Filter = require('nodester/filter');
const traverse = require('nodester/query/traverse');
const City = require('#models/City');
const filter = new Filter(City, {
attributes: [
'id',
'country_id'
'name',
],
statics: {
attributes: {
country_id: 17
},
}
};
function cityFilter(req, res, next) {
const resultQuery = traverse(req.nquery, filter);
req.query = resultQuery;
return next();
}
...
router.add.route('get /cities', {
before: cityFilter,
controlledBy: 'CitiesController.getMany'
});
const nodester = require('nodester');
const router = require(<path_to_router_definition/>);
const app = new nodester();
app.use(router());
Provider manages interactions between application and other APIs. Other APIs include:
- Third-party APIs;
- API of node_modules;
- API of modules inside your application.
Util is a self-sufficient code snippet.
You can find all available utils under nodester/utils
.
Copyright 2021-present Mark Khramko