Backend Standards
Controller Structure
Controllers should be consistent, simple, and predictable:
export default class UsersController {
static async createUser(req, res, next) {
try {
const newUser = await UsersService.createUser(req.body);
return next(newUser);
} catch (error) {
return next(error);
}
}
}
General Controllers
Prefer shared controller patterns instead of per-feature custom controllers.
General Services
Use general services where possible.
Do not use findUserById or similar custom helpers when a shared service exists.
const {doc: company} = await GeneralServices.findOne({
model: CompaniesModel,
query: {_id: id, agent: req.jwtToken.user.id},
});
if (!company) {
return next(CompaniesErrorsFactory.companyNotFoundErr());
}
Validation
Always validate on the backend using schema/model validation.
Example (Mongoose):
const userSchema = new mongoose.Schema({
email: {type: String, required: true, match: /.+@.+\\..+/},
age: {type: Number, min: 18, required: true},
});
Route Ordering
Define static routes before :id routes to avoid conflicts:
PATCH /users/forget-password
PATCH /users/:id
Example conflict:
PATCH /users/:id
PATCH /users/forget-password
The second route is treated as :id = forget-password.