Skip to main content

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.