Last active
October 26, 2017 14:28
-
-
Save mtpultz/45a28445a6e710008b9b92c82792122d to your computer and use it in GitHub Desktop.
Express-Validator v4 - Encapsulated Validations Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const router: Router = express.Router(); | |
// ... removed for brevity | |
/** | |
* Create a new example. | |
*/ | |
router.post('/examples/:id', | |
exampleController.validate('create'), | |
exampleController.create | |
); | |
// ... removed for brevity | |
export { router as mineralRoutes }; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Response, Request, NextFunction } from 'express'; | |
import { ValidationChain, check } from 'express-validator/check'; | |
import { BaseController } from './base.controller'; | |
class ExampleController extends BaseController { | |
constructor() { | |
super(); | |
// Bind scope to the public methods | |
this.create = this.create.bind(this); | |
} | |
// ... removed for brevity | |
/** | |
* Create a new example. | |
* | |
* @param {Request} req | |
* @param {Response} res | |
* @param {NextFunction} next | |
* @memberof ExampleController | |
*/ | |
public async create(req: Request, res: Response, next: NextFunction) { | |
console.log('example:create'); | |
this.successResponse(res); | |
// this.errorResponse(res); | |
} | |
/** | |
* Chain used to validate incoming request data. | |
* | |
* @readonly | |
* @private | |
* @memberof ExampleController | |
*/ | |
protected get validationChain(): ValidationChain[] { | |
return { | |
create: [ | |
check('example1', 'Example 1 is required.').exists(), | |
check('example2', 'Example 2 is required.').exists() | |
] | |
}; | |
} | |
//... removed for brevity | |
} | |
export default new ExampleController; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export abstract class BaseController extends Validator { | |
/** | |
* Set the success response. | |
* | |
* @private | |
* @param {Response} res | |
* @param {User} user | |
* @memberof BaseController | |
*/ | |
protected abstract successResponse(res: Response, options?: any): void; | |
/** | |
* Set the error response. | |
* | |
* @private | |
* @param {Response} res | |
* @param {User} user | |
* @memberof BaseController | |
*/ | |
protected abstract errorResponse(res: Response, options?: any): void; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Response, Request, NextFunction, RequestHandler } from 'express'; | |
import { ValidationChain, validationResult } from 'express-validator/check'; | |
export abstract class Validator { | |
/** | |
* Resolve only a single error from the first field. | |
* | |
* @type {boolean} | |
* @memberof Validator | |
*/ | |
public onlyFirstFieldAndError: boolean; | |
constructor() { | |
this.onlyFirstFieldAndError = true; | |
// Bind scope to the public methods used as middleware | |
this.validate = this.validate.bind(this); | |
} | |
/** | |
* Chain used to validate incoming request data. | |
* | |
* @readonly | |
* @private | |
* @memberof Validator | |
*/ | |
protected abstract get validationChain(): { [key: string]: ValidationChain[] }; | |
/** | |
* Validate request data middleware. | |
* | |
* @param {Request} req | |
* @param {Response} res | |
* @param {NextFunction} next | |
* @memberof Validator | |
*/ | |
// public async validate(req: Request, res: Response, next: NextFunction) { | |
public validate(key: string): Array<ValidationChain | RequestHandler> { | |
return [ | |
...this.validationChain[key], | |
this.validator() | |
]; | |
} | |
/** | |
* Run validations on request data. | |
* | |
* @private | |
* @param {Request} req | |
* @param {Response} res | |
* @returns {Promise<any>} | |
* @memberof Validator | |
*/ | |
protected validator(): RequestHandler { | |
return (req: Request, res: Response, next: NextFunction) => { | |
try { | |
// Run the validation chain | |
validationResult(req).throw(); | |
next(); | |
} catch (err) { | |
this.validatorErrorResponse(res, err); | |
} | |
}; | |
} | |
/** | |
* Set the validation error response. | |
* | |
* @protected | |
* @param {Response} res | |
* @param {any} err | |
* @memberof Validator | |
*/ | |
protected validatorErrorResponse(res: Response, err: any): void { | |
// Resolve the first validation error on each field, or all the validation | |
// errors on every field | |
const errorBag = (this.onlyFirstError) ? err.mapped() : err.array(); | |
res.status(422).json(errorBag); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment