Although the bulk of the validation logic has been abstracted into a separate module, the request handler is still processing the results of the validator, interacting with the database, and sending back the response; it still does not comply with the single responsibility principle.
The request handler's only job should be to pass the request to an engine, which will process the request, and respond with the result of the operation. Based on the result of the operation, the request handler should then issue an appropriate response to the client.
So, let's create a new directory at src/engines/users and add a create.js file; inside, define a create function and export it. This create function will validate our request and write to the database, returning the result of the operation back to the request handler. Since writing to the database is an asynchronous operation, our create function should return a promise.
Try implementing the create function yourself, and check back here for our implementation:
import ValidationError from '../../validators/errors/validation-error';
import validate from '../../validators/users/create';
function create(req, db) {
const validationResults = validate(req);
if (validationResults instanceof ValidationError) {
return Promise.reject(validationResults);
}
return db.index({
index: process.env.ELASTICSEARCH_INDEX,
type: 'user',
body: req.body,
});
}
export default create;
Then, in src/handlers/users/create.js, import the engine module and use the result to generate the response. The final file should look like this:
import ValidationError from '../../validators/errors/validation-error';
import create from '../../engines/users/create';
function createUser(req, res, db) {
create(req, db).then((result) => {
res.status(201);
res.set('Content-Type', 'text/plain');
return res.send(result._id);
}, (err) => {
if (err instanceof ValidationError) {
res.status(400);
res.set('Content-Type', 'application/json');
return res.json({ message: err.message });
}
return undefined;
}).catch(() => {
res.status(500);
res.set('Content-Type', 'application/json');
return res.json({ message: 'Internal Server Error' });
});
}
export default createUser;
Run the tests to make sure that they all still pass, and then commit these changes to Git:
$ git add -A && git commit -m "Ensure Single-Responsibility Principle for handler"
Fantastic! We have now refactored our code to be more modular and ensured that each module is decoupled from the others!