Best Practices

  • Backend best practices focus on clean code, reusable services, and standardized error handling for scalable applications.
  • Clean Code Principles

    What is Clean Code?

    Clean code is code that is:

    • Easy to read

    • Easy to understand

    • Easy to modify

    • Easy to maintain

    Agar 6 mahine baad code dekho, to bhi samajh aa jaye ✅


    Core Clean Code Principles

    ✔ Meaningful Naming

    ❌ Bad

const x = 10;
  • ✅ Good

const maxLoginAttempts = 10;
  • Small Functions

    • One function = one responsibility

    ❌ Bad

function processUser() {
  validateUser();
  saveUser();
  sendEmail();
}
  • ✅ Good

function validateUser() {}
function saveUser() {}
function sendEmail() {}
  • Avoid Duplication (DRY)

    ❌ Repeated logic
    ✅ Reusable function / service


    ✔ Readable Formatting

    • Proper indentation

    • Logical spacing

    • Consistent style

    Clean Code Benefits

    • Faster debugging

    • Better collaboration

    • Easy scaling

    • Fewer bugs


    Reusable Services

    What are Reusable Services?

    Reusable services are common business logic modules that can be used in multiple controllers or routes.


    Why Reusability Matters

    • Avoids duplicate code

    • Easier maintenance

    • Centralized logic

    • Faster development

    Example – Reusable Service

    email.service.js

const sendEmail = (to, subject, message) => {
  // email sending logic
};

module.exports = { sendEmail };
  • Used in Multiple Controllers

const { sendEmail } = require("../services/email.service");
  • Reusable Service Flow

Controller A → Email Service
Controller B → Email Service
Controller C → Email Service
  • Best Practices for Services
    • No request/response objects inside services

    • Only business logic

    • Return data, don’t send response


    Error Handling Standards

    Why Error Handling Matters

    Proper error handling:

    • Prevents app crashes

    • Improves user experience

    • Helps debugging

    • Keeps API responses consistent


    Standard Error Handling Approach

Controller → Service → Error → Middleware → Response
  • Custom Error Class

    utils/AppError.js

class AppError extends Error {
  constructor(message, statusCode) {
    super(message);
    this.statusCode = statusCode;
    this.status = "error";
  }
}

module.exports = AppError;
  • Throw Error from Service

const AppError = require("../utils/AppError");

if (!user) {
  throw new AppError("User not found", 404);
}
  • Centralized Error Middleware

app.use((err, req, res, next) => {
  res.status(err.statusCode || 500).json({
    status: err.status || "error",
    message: err.message
  });
});
  • Error Handling Best Practices

    • Use centralized error middleware

    • Don’t expose stack traces in production

    • Use proper HTTP status codes

    • Handle async errors properly

    Standard API Error Response

{
  "status": "error",
  "message": "Invalid credentials"
}
  • Best Practices Summary

    • Clean code improves readability & maintainability

    • Reusable services reduce duplication

    • Centralized error handling ensures consistency

    • Follow industry-standard structure

    • Makes your project production-ready