Initial API Architecture. Contains a basic and must-have set of modules, services and configurations.
Use Express Middlewares in order to split functionality and have logically separated parts. Each router/endpoint may have a chain of middlewares to validate data, load data from data sources, map data, check permissions and perform the main business logic.
Each Middleware function should have the same name through the whole chain set.
Example: If a new request of user creation process passes multiple middleware functions, all of them should have the same name (createOne(req, res, next)
)
*Exception: unrelated 'helper' middlewares
Example:
appRoute.get('/:userId',
authMiddleware.isAuthenticated,
acl.getOne,
validator.getOne,
loader.getOne,
controller.getOne,
);
./app/middlewares/
Chain items to perform own specific functionality.
Checks if the current request may reach a business logic. This layer may check if a logged in user has permissions to perform this request.
Example:
async getOne(req, res, next) {
if (mainAcl.isAdmin(req.user)) {
return next();
}
const userIdRequested = req.params.userId;
const userIdCurrent = req.user._id.toString();
if (userIdRequested === userIdCurrent) {
return next();
}
return next(new Forbidden());
},
Maps Outgoing/Incoming data for further processing by another function.
Example:
updateOne(req, res, next) {
delete req.body.password;
delete req.body.confirm_password;
return next();
},
Validates incoming data according to installed rules to prevent invalid data from handling.
Example:
deleteOne(req, res, next) {
req.assert('userId', 'Valid user id should be provided').notEmpty().isMongoId();
mainValidator.handleValidationResult(mainValidator.validateErrorsSync(req), res, next);
},
Loads/Gets required by business logic entities/objects from available data sources. The system may retrieve users or related entities from a database or process a data.
Stores and passes loaded entities in a special object inside the req
(request) object. The Entity Loader Service should be used to sed all of the entities and pass within the request object.
Example:
async getOne(req, res, next) {
try {
const userFound = await UserService.findOne({ query: { _id: req.params.userId }, options: { lean: true } });
if (!mainHelper.isObjectValid(userFound)) {
throw new NotFound('user not found');
}
MainLoader.setEntities(req, { user: userFound });
return next();
} catch (err) {
return next(err);
}
},
./app/services/
Services perform single-minded focus functionality to be invoked inside the application for handling business logic.
./commands
Visit https://nodejs.org for installation details.
Node Package Manager, should come bundled with node.
Install MongoDB https://docs.mongodb.com/manual/installation/
$ git clone <package url> .
$ npm install
config/env/env.local
file and copy data from config/env/env.local_example
config/env/.env.test
file and copy data from config/env/.env.test_example
$ npm run start:[environment]
Example: $ npm run start:local