Workstation Logo
ਉਤਪਾਦ
AI ਲੈਬਜ਼OpenAI ਏਜੰਟClaude ਏਜੰਟGrok BotWorkstation CRM (WSL CRM)ਮਾਰਕੀਟਿੰਗਸਾਰੇ ਉਤਪਾਦ
AI ਹੱਲ
AI ਵਰਕਸਟੇਸ਼ਨAI SME Packagesਪ੍ਰਾਈਵੇਟ AIGPU ਕਲੱਸਟਰਐਜ AIਐਂਟਰਪ੍ਰਾਈਜ਼ AI ਲੈਬਉਦਯੋਗ ਅਨੁਸਾਰ AI
ਸੇਵਾਵਾਂ
Platform ModernisationDigital EngineeringData Foundations & AIAutonomous OperationsAI ਸਲਾਹDevOps ਆਟੋਮੇਸ਼ਨਸਾਈਬਰ ਸੁਰੱਖਿਆਸਾਫਟਵੇਅਰ ਵਿਕਾਸਏਜੰਟ ਨਿਰਮਾਣMLOps ਸੈੱਟਅੱਪ
ਸਾਡੇ ਬਾਰੇ
ਸਾਂਝੇਦਾਰਗਾਹਕ ਕਹਾਣੀਆਂ
ਲੇਖ
ਦਸਤਾਵੇਜ਼
WSL ProxyRing Promoter
ਬਲੌਗ
ਸਾਡੇ ਨਾਲ ਸੰਪਰਕ ਕਰੋLogin
Workstation

AI workstations, AI Multi Agentic Software, GPU infrastructure, and intelligent agent solutions for modern businesses.

ਯੂਕੇ ਦਫ਼ਤਰ: 77-79 Marlowes, Hemel Hempstead HP1 1LF - Directions - Take Junction 20 off M25 Outer London
Company No: 11641870
Mon - Fri: 9:00 AM - 6:00 PM GMT
+44 7515 356 146

ਬੈਲਜੀਅਮ ਦਫ਼ਤਰ: Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, Brussels
BE 0751.518.683
Mon - Fri: 9:00 AM - 6:00 PM CET
+32 492 45 67 46

ਭਾਰਤ ਦਫ਼ਤਰ: #159 Sector 9, Pocket 1, DDA Flats, 110077 Dwarka, New Delhi
+91 98881 98841

ਉਤਪਾਦ

ਸਾਰੇ ਉਤਪਾਦWSL ProxyRing PromoterAI ਲੈਬਜ਼OpenAI ਏਜੰਟClaude ਏਜੰਟGrok BotWorkstation CRM (WSL CRM)

AI ਹੱਲ

AI ਹੱਲAI ਵਰਕਸਟੇਸ਼ਨਪ੍ਰਾਈਵੇਟ AIGPU ਕਲੱਸਟਰਐਂਟਰਪ੍ਰਾਈਜ਼ AI ਲੈਬਸੇਵਾਵਾਂ

ਸਰੋਤ

ਲੇਖਦਸਤਾਵੇਜ਼ਬਲੌਗSearchਸਾਈਟ ਮੈਪ

ਕੰਪਨੀ

ਸਾਡੇ ਬਾਰੇਸਾਂਝੇਦਾਰਸਾਡੇ ਨਾਲ ਸੰਪਰਕ ਕਰੋ

© 2026 Workstation AI. ਸਾਰੇ ਹੱਕ ਰਾਖਵੇਂ ਹਨ

ਗੋਪਨੀਯਤਾ ਨੀਤੀਕੂਕੀ ਨੀਤੀਸਾਈਟ ਮੈਪ

Loading blog...

Home / Blog
WebFrontendReact

Node.js ਅਤੇ MySQL ਨਾਲ ਮਜ਼ਬੂਤ ​​ਬੈਕਐਂਡ ਸਿਸਟਮ ਬਣਾਉਣਾ

Node.js, Express, ਅਤੇ MySQL ਨਾਲ ਸਕੇਲੇਬਲ, ਸੁਰੱਖਿਅਤ ਬੈਕਐਂਡ APIs ਨੂੰ ਡਿਜ਼ਾਈਨ ਅਤੇ ਲਾਗੂ ਕਰੋ

Balinder Walia27 ਮਈ 202512 min read

Node.js ਅਤੇ MySQL ਬੈਕਐਂਡ ਸਿਸਟਮ ਬਣਾਉਣ ਲਈ ਸਭ ਤੋਂ ਭਰੋਸੇਮੰਦ ਅਤੇ ਲੜਾਈ-ਜਾਂਚ ਕੀਤੇ ਸੰਜੋਗਾਂ ਵਿੱਚੋਂ ਇੱਕ ਹਨ। Node.js ਇੱਕ ਇਵੈਂਟ-ਸੰਚਾਲਿਤ, ਗੈਰ-ਬਲਾਕਿੰਗ I/O ਮਾਡਲ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ ਜੋ ਸਮਕਾਲੀ ਬੇਨਤੀਆਂ ਨੂੰ ਕੁਸ਼ਲਤਾ ਨਾਲ ਸੰਭਾਲਦਾ ਹੈ, ਜਦੋਂ ਕਿ MySQL ਰਿਲੇਸ਼ਨਲ ਡਾਟਾ ਅਖੰਡਤਾ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ ਜਿਸਦੀ ਵਪਾਰਕ ਐਪਲੀਕੇਸ਼ਨਾਂ ਦੀ ਮੰਗ ਹੁੰਦੀ ਹੈ। ਇਕੱਠੇ ਮਿਲ ਕੇ, ਉਹ ਇੱਕ ਬੁਨਿਆਦ ਬਣਾਉਂਦੇ ਹਨ ਜੋ ਸਟਾਰਟਅੱਪ MVPs ਤੋਂ ਲੈ ਕੇ ਐਂਟਰਪ੍ਰਾਈਜ਼ ਪਲੇਟਫਾਰਮਾਂ ਤੱਕ ਹਰ ਰੋਜ਼ ਲੱਖਾਂ ਬੇਨਤੀਆਂ ਨੂੰ ਸੰਭਾਲਣ ਲਈ ਸ਼ਕਤੀ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ।

ਇਹ ਗਾਈਡ ਇੱਕ ਪ੍ਰੋਡਕਸ਼ਨ-ਗ੍ਰੇਡ ਬੈਕਐਂਡ API ਬਣਾਉਣ, ਪ੍ਰੋਜੈਕਟ ਢਾਂਚੇ, ਡੇਟਾਬੇਸ ਡਿਜ਼ਾਈਨ, ਪ੍ਰਮਾਣੀਕਰਨ, ਗਲਤੀ ਨਾਲ ਨਜਿੱਠਣ, ਅਤੇ ਤੈਨਾਤੀ ਨੂੰ ਕਵਰ ਕਰਦੀ ਹੈ।

Express.js ਪ੍ਰੋਜੈਕਟ ਢਾਂਚਾ

Node.js + ਐਕਸਪ੍ਰੈਸ ਬੈਕਐਂਡ ਆਰਕੀਟੈਕਚਰ

ਮਿਡਲ

20 Lar ਪ੍ਰਮਾਣਿਕਤਾ (JWT)ਪ੍ਰਮਾਣਿਕਤਾਦਰ ਸੀਮਾCORSHelmetTAG37TAG37XTAG37TAG37TAG39XTAG37 ਲੋਅਰਬ੍ਰਾਊਜ਼ਰ / ਐਪAPIਗੇਟਵੇ/api/v1ਐਕਸਪ੍ਰੈਸਰੂਟਸ XTAGPO/GTAG55STX X6PO/GTAG5PETXਕੰਟਰੋਲਰਬੇਨਤੀ ਹੈਂਡਲਿੰਗਸੇਵਾਵਾਂਵਪਾਰਕ ਤਰਕMySQLਰਿਲੇਸ਼ਨਲ DB X7XTAG570X ਰਿਲੇਸ਼ਨਲ DB X7XTAG572XHTTPਰੂਟਕਾਲਕਾਲਪੁੱਛ-ਗਿੱਛTAG93 XTAG92 ਸਫਲਤਾ ਲਈ ਜਵਾਬ: XTAG93 ਮੈਟ ਸਫਲਤਾ ਲਈ ਸਹੀ,ਡੇਟਾ: [...],ਪੰਨਾ ਨੰਬਰ: {...}}ਪਾਈਪਲਾਈਨ ਨੂੰ ਸੰਭਾਲਣ ਵਿੱਚ ਤਰੁੱਟੀਜਾਂ

108XRXTAG10100XasyncHandlerਐਰਰਹੈਂਡਲਰਕੇਂਦਰੀਕ੍ਰਿਤ, ਇਕਸਾਰ ਤਰੁੱਟੀ ਜਵਾਬ

ਦਾ ਸੰਰਚਨਾ ਚੰਗੀ ਤਰ੍ਹਾਂ ਬਣਾਈ ਰੱਖਣ ਯੋਗ XTAG24 ਦਾ ਪ੍ਰੋਜੈਕਟ-ਐਂਡ ਬੈਕਐਂਡ ਹੈ। ਚਿੰਤਾਵਾਂ ਨੂੰ ਸਪਸ਼ਟ ਤੌਰ 'ਤੇ ਵੱਖ ਕਰੋ ਅਤੇ ਸੰਮੇਲਨਾਂ ਨੂੰ ਜਲਦੀ ਸਥਾਪਿਤ ਕਰੋ।

project-root/
  src/
    config/
      database.js
      environment.js
      logger.js
    middleware/
      auth.js
      errorHandler.js
      rateLimiter.js
      validator.js
    models/
      User.js
      Product.js
      Order.js
      index.js
    routes/
      auth.routes.js
      users.routes.js
      products.routes.js
      orders.routes.js
      index.js
    services/
      auth.service.js
      user.service.js
      product.service.js
      email.service.js
    utils/
      ApiError.js
      asyncHandler.js
      pagination.js
    app.js
    server.js
  migrations/
  seeders/
  tests/
  .env
  .env.example
  package.json

ਐਂਟਰੀ ਪੁਆਇੰਟ ਐਕਸਪ੍ਰੈਸ ਨੂੰ ਜ਼ਰੂਰੀ ਮਿਡਲਵੇਅਰ ਨਾਲ ਸੈੱਟ ਕਰਦਾ ਹੈ:

// src/app.js
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const morgan = require('morgan');
const { errorHandler } = require('./middleware/errorHandler');
const routes = require('./routes');

const app = express();

// Security middleware
app.use(helmet());
app.use(cors({
  origin: process.env.ALLOWED_ORIGINS?.split(',') || 'http://localhost:3000',
  credentials: true,
}));

// Request parsing
app.use(express.json({ limit: '10mb' }));
app.use(express.urlencoded({ extended: true }));

// Logging
app.use(morgan(process.env.NODE_ENV === 'production' ? 'combined' : 'dev'));

// Health check
app.get('/health', (req, res) => {
  res.json({ status: 'ok', timestamp: new Date().toISOString() });
});

// API routes
app.use('/api/v1', routes);

// Error handling (must be last)
app.use(errorHandler);

module.exports = app;

RESTful API ਡਿਜ਼ਾਈਨ

REST ਸੰਮੇਲਨਾਂ ਦੇ ਬਾਅਦ ਆਪਣੇ API ਅੰਤਮ ਬਿੰਦੂਆਂ ਨੂੰ ਡਿਜ਼ਾਈਨ ਕਰੋ। ਸਰੋਤਾਂ ਲਈ ਨਾਂਵਾਂ, ਕਾਰਵਾਈਆਂ ਲਈ HTTP ਵਿਧੀਆਂ, ਅਤੇ ਇਕਸਾਰ ਜਵਾਬ ਫਾਰਮੈਟਾਂ ਦੀ ਵਰਤੋਂ ਕਰੋ।

// src/routes/products.routes.js
const router = require('express').Router();
const { authenticate, authorize } = require('../middleware/auth');
const { validate } = require('../middleware/validator');
const { createProductSchema, updateProductSchema } = require('../validators/product');
const productController = require('../controllers/product.controller');

router.get('/', productController.getAll);
router.get('/:id', productController.getById);
router.post('/',
  authenticate,
  authorize('admin'),
  validate(createProductSchema),
  productController.create
);
router.put('/:id',
  authenticate,
  authorize('admin'),
  validate(updateProductSchema),
  productController.update
);
router.delete('/:id',
  authenticate,
  authorize('admin'),
  productController.delete
);

module.exports = router;

ਕੰਟਰੋਲਰ ਪਤਲੇ ਹੋਣੇ ਚਾਹੀਦੇ ਹਨ, ਸੇਵਾ ਕਲਾਸਾਂ ਨੂੰ ਕਾਰੋਬਾਰੀ ਤਰਕ ਸੌਂਪਦੇ ਹੋਏ:

// src/controllers/product.controller.js
const productService = require('../services/product.service');
const { asyncHandler } = require('../utils/asyncHandler');

exports.getAll = asyncHandler(async (req, res) => {
  const { page = 1, limit = 20, sort = 'created_at', order = 'DESC', search } = req.query;

  const result = await productService.findAll({
    page: parseInt(page),
    limit: Math.min(parseInt(limit), 100),
    sort,
    order,
    search,
  });

  res.json({
    success: true,
    data: result.products,
    pagination: {
      page: result.page,
      limit: result.limit,
      total: result.total,
      totalPages: result.totalPages,
    },
  });
});

exports.create = asyncHandler(async (req, res) => {
  const product = await productService.create(req.body);
  res.status(201).json({
    success: true,
    data: product,
  });
});

MySQL mysql2 ਨਾਲ ਕਨੈਕਸ਼ਨ ਪੂਲਿੰਗ

2XMySQL ਕਨੈਕਸ਼ਨ ਪੂਲ ਆਰਕੀਟੈਕਚਰਐਪਲੀਕੇਸ਼ਨਸਮਕਾਲੀ ਬੇਨਤੀਆਂਬੇਨਤੀ ਬੇਨਤੀਬੇਨਤੀ ਥ੍ਰੈਡ 2ਬੇਨਤੀ ਥ੍ਰੈਡ 3ਬੇਨਤੀ ਥ੍ਰੈਡ 4...ਬੇਨਤੀ ਥ੍ਰੈੱਡ Nਕਨੈਕਸ਼ਨ ਪੂਲ (mysql2)ਕਿਰਿਆਸ਼ੀਲਨਿਸ਼ਕਿਰਿਆ XTAG1818 XTAG1818 XTAG1818 — ਕਿਰਿਆਸ਼ੀਲਕਨੈਕਸ਼ਨ 2 — ਕਿਰਿਆਸ਼ੀਲਕਨੈਕਸ਼ਨ 3 — ਕਿਰਿਆਸ਼ੀਲਕਨੈਕਸ਼ਨ 4 — ਨਿਸ਼ਕਿਰਿਆXTAG19 Id5 XTAG19 ਕਨੈਕਸ਼ਨ — XTAG195ਕਨੈਕਸ਼ਨ ਸੀਮਾ: 10 | waitForConnections: trueenableKeepAlive: true | ਕਤਾਰ ਸੀਮਾ: 0MySQLਡਾਟਾਬੇਸ ਸਰਵਰਡਾਟਾ ਸਟੋਰ ਵਿੱਚInnoDB ਇੰਜਣTAG230XTAG230ol ਕਨੈਕਸ਼ਨਾਂ ਦੀ ਮੁੜ ਵਰਤੋਂ ਕਰਦਾ ਹੈ, ਪ੍ਰਤੀ ਬੇਨਤੀ

ਕਨੈਕਸ਼ਨ ਪੂਲਿੰਗ ਪ੍ਰਤੀ ਬੇਨਤੀ ਨਵੇਂ ਬਣਾਉਣ ਦੇ ਓਵਰਹੈੱਡ ਤੋਂ ਬਚਣਾ ਕਾਰਗੁਜ਼ਾਰੀ ਲਈ ਮਹੱਤਵਪੂਰਨ ਹੈ।mysql2ਪੈਕੇਜ ਤਿਆਰ ਸਟੇਟਮੈਂਟਾਂ ਅਤੇ ਬਾਕਸ ਦੇ ਬਾਹਰ ਕਨੈਕਸ਼ਨ ਪੂਲਿੰਗ ਦੇ ਨਾਲ ਇੱਕ ਵਾਅਦਾ-ਅਧਾਰਿਤ API ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ।

// src/config/database.js
const mysql = require('mysql2/promise');
const logger = require('./logger');

const pool = mysql.createPool({
  host: process.env.DB_HOST || 'localhost',
  port: parseInt(process.env.DB_PORT) || 3306,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
  database: process.env.DB_NAME,
  waitForConnections: true,
  connectionLimit: parseInt(process.env.DB_POOL_SIZE) || 10,
  queueLimit: 0,
  enableKeepAlive: true,
  keepAliveInitialDelay: 30000,
  timezone: '+00:00',
  typeCast: function (field, next) {
    if (field.type === 'TINY' && field.length === 1) {
      return field.string() === '1';
    }
    return next();
  },
});

// Test connection on startup
pool.getConnection()
  .then(conn => {
    logger.info('MySQL connected successfully');
    conn.release();
  })
  .catch(err => {
    logger.error('MySQL connection failed:', err.message);
    process.exit(1);
  });

module.exports = pool;

SQL ਇੰਜੈਕਸ਼ਨ ਨੂੰ ਰੋਕਣ ਲਈ ਹਮੇਸ਼ਾ ਪੈਰਾਮੀਟਰਾਈਜ਼ਡ ਸਵਾਲਾਂ ਦੀ ਵਰਤੋਂ ਕਰੋ:

// NEVER do this
const query = `SELECT * FROM users WHERE email = '${email}'`;

// ALWAYS use parameterized queries
const [rows] = await pool.execute(
  'SELECT id, email, first_name, last_name FROM users WHERE email = ?',
  [email]
);

ਸੀਕਵਲਾਈਜ਼ ORM

ਗੁੰਝਲਦਾਰ ਡੇਟਾ ਰਿਸ਼ਤਿਆਂ ਵਾਲੀਆਂ ਐਪਲੀਕੇਸ਼ਨਾਂ ਲਈ, ਸੀਕਵਲਾਈਜ਼ ਇੱਕ ਪੂਰੀ-ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ, ਮਾਡਲਾਂ ਦੀ ਪਰਿਭਾਸ਼ਾ ਦੇ ਨਾਲ, ਓ.ਆਰ.ਐਮ. ਇਮਾਰਤ. JWT

ਦੇ ਨਾਲ

// src/models/Product.js
const { DataTypes } = require('sequelize');
const sequelize = require('../config/sequelize');

const Product = sequelize.define('Product', {
  id: {
    type: DataTypes.UUID,
    defaultValue: DataTypes.UUIDV4,
    primaryKey: true,
  },
  name: {
    type: DataTypes.STRING(255),
    allowNull: false,
    validate: {
      notEmpty: true,
      len: [2, 255],
    },
  },
  description: {
    type: DataTypes.TEXT,
    allowNull: true,
  },
  price: {
    type: DataTypes.DECIMAL(10, 2),
    allowNull: false,
    validate: {
      min: 0,
    },
  },
  sku: {
    type: DataTypes.STRING(100),
    unique: true,
    allowNull: false,
  },
  stock_quantity: {
    type: DataTypes.INTEGER,
    defaultValue: 0,
    validate: {
      min: 0,
    },
  },
  is_active: {
    type: DataTypes.BOOLEAN,
    defaultValue: true,
  },
}, {
  tableName: 'products',
  timestamps: true,
  underscored: true,
  paranoid: true, // Soft deletes
  indexes: [
    { fields: ['sku'], unique: true },
    { fields: ['is_active'] },
    { fields: ['price'] },
    { fields: ['created_at'] },
  ],
});

// Associations
Product.associate = (models) => {
  Product.belongsTo(models.Category, { foreignKey: 'category_id' });
  Product.hasMany(models.OrderItem, { foreignKey: 'product_id' });
  Product.belongsToMany(models.Tag, { through: 'product_tags' });
};

module.exports = Product;

ਪ੍ਰਮਾਣੀਕਰਨ JSON ਵੈੱਬ ਟੋਕਨਾਂ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਸਟੇਟਲੈਸ ਪ੍ਰਮਾਣੀਕਰਨ ਨੂੰ ਲਾਗੂ ਕਰੋ। API ਬੇਨਤੀਆਂ ਲਈ ਐਕਸੈਸ ਟੋਕਨਾਂ ਦੀ ਵਰਤੋਂ ਕਰੋ ਅਤੇ ਸੈਸ਼ਨ ਪ੍ਰਬੰਧਨ ਲਈ ਟੋਕਨਾਂ ਨੂੰ ਤਾਜ਼ਾ ਕਰੋ।

// src/services/auth.service.js
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const { User } = require('../models');
const ApiError = require('../utils/ApiError');

const SALT_ROUNDS = 12;
const ACCESS_TOKEN_EXPIRY = '15m';
const REFRESH_TOKEN_EXPIRY = '7d';

exports.register = async ({ email, password, firstName, lastName }) => {
  const existingUser = await User.findOne({ where: { email } });
  if (existingUser) {
    throw new ApiError(409, 'Email already registered');
  }

  const hashedPassword = await bcrypt.hash(password, SALT_ROUNDS);
  const user = await User.create({
    email,
    password: hashedPassword,
    first_name: firstName,
    last_name: lastName,
  });

  const tokens = generateTokens(user);
  return { user: sanitizeUser(user), ...tokens };
};

exports.login = async ({ email, password }) => {
  const user = await User.findOne({ where: { email } });
  if (!user || !(await bcrypt.compare(password, user.password))) {
    throw new ApiError(401, 'Invalid email or password');
  }

  const tokens = generateTokens(user);
  return { user: sanitizeUser(user), ...tokens };
};

function generateTokens(user) {
  const accessToken = jwt.sign(
    { userId: user.id, email: user.email, role: user.role },
    process.env.JWT_SECRET,
    { expiresIn: ACCESS_TOKEN_EXPIRY }
  );

  const refreshToken = jwt.sign(
    { userId: user.id, tokenType: 'refresh' },
    process.env.JWT_REFRESH_SECRET,
    { expiresIn: REFRESH_TOKEN_EXPIRY }
  );

  return { accessToken, refreshToken };
}

function sanitizeUser(user) {
  const { password, ...userData } = user.toJSON();
  return userData;
}

ਪ੍ਰਮਾਣਿਕਤਾ ਮਿਡਲਵੇਅਰ ਸੁਰੱਖਿਅਤ ਰੂਟਾਂ 'ਤੇ ਟੋਕਨਾਂ ਦੀ ਪੁਸ਼ਟੀ ਕਰਦਾ ਹੈ:

// src/middleware/auth.js
const jwt = require('jsonwebtoken');
const ApiError = require('../utils/ApiError');

exports.authenticate = (req, res, next) => {
  const authHeader = req.headers.authorization;
  if (!authHeader?.startsWith('Bearer ')) {
    throw new ApiError(401, 'Access token required');
  }

  const token = authHeader.split(' ')[1];
  try {
    const decoded = jwt.verify(token, process.env.JWT_SECRET);
    req.user = decoded;
    next();
  } catch (error) {
    if (error.name === 'TokenExpiredError') {
      throw new ApiError(401, 'Access token expired');
    }
    throw new ApiError(401, 'Invalid access token');
  }
};

exports.authorize = (...roles) => {
  return (req, res, next) => {
    if (!roles.includes(req.user.role)) {
      throw new ApiError(403, 'Insufficient permissions');
    }
    next();
  };
};

Joi ਨਾਲ ਇਨਪੁਟ ਪ੍ਰਮਾਣਿਕਤਾ

ਤੁਹਾਡੇ ਵਪਾਰਕ ਤਰਕ ਤੱਕ ਪਹੁੰਚਣ ਤੋਂ ਪਹਿਲਾਂ ਸਾਰੇ ਆਉਣ ਵਾਲੇ ਡੇਟਾ ਨੂੰ ਪ੍ਰਮਾਣਿਤ ਕਰੋ। Joi ਇੱਕ ਸ਼ਕਤੀਸ਼ਾਲੀ ਸਕੀਮਾ-ਆਧਾਰਿਤ ਪ੍ਰਮਾਣਿਕਤਾ ਲਾਇਬ੍ਰੇਰੀ ਪ੍ਰਦਾਨ ਕਰਦਾ ਹੈ।

// src/validators/product.js
const Joi = require('joi');

exports.createProductSchema = Joi.object({
  name: Joi.string().min(2).max(255).required(),
  description: Joi.string().max(5000).optional(),
  price: Joi.number().positive().precision(2).required(),
  sku: Joi.string().alphanum().max(100).required(),
  stock_quantity: Joi.number().integer().min(0).default(0),
  category_id: Joi.string().uuid().required(),
  tags: Joi.array().items(Joi.string().uuid()).optional(),
  is_active: Joi.boolean().default(true),
});

exports.updateProductSchema = Joi.object({
  name: Joi.string().min(2).max(255),
  description: Joi.string().max(5000).allow(null),
  price: Joi.number().positive().precision(2),
  stock_quantity: Joi.number().integer().min(0),
  category_id: Joi.string().uuid(),
  is_active: Joi.boolean(),
}).min(1);

// src/middleware/validator.js
exports.validate = (schema) => {
  return (req, res, next) => {
    const { error, value } = schema.validate(req.body, {
      abortEarly: false,
      stripUnknown: true,
    });

    if (error) {
      const errors = error.details.map(detail => ({
        field: detail.path.join('.'),
        message: detail.message,
      }));
      return res.status(400).json({
        success: false,
        message: 'Validation failed',
        errors,
      });
    }

    req.body = value;
    next();
  };
};

ਗਲਤੀ ਹੈਂਡਲਿੰਗ ਮਿਡਲਵੇਅਰ

ਕੇਂਦਰੀਕ੍ਰਿਤ ਗਲਤੀ ਹੈਂਡਲਿੰਗ ਲਗਾਤਾਰ ਗਲਤੀ ਜਵਾਬਾਂ ਨੂੰ ਯਕੀਨੀ ਬਣਾਉਂਦੀ ਹੈ ਅਤੇ ਸੰਵੇਦਨਸ਼ੀਲ ਜਾਣਕਾਰੀ ਨੂੰ ਗਾਹਕਾਂ ਨੂੰ ਲੀਕ ਹੋਣ ਤੋਂ ਰੋਕਦੀ ਹੈ।

// src/utils/ApiError.js
class ApiError extends Error {
  constructor(statusCode, message, errors = []) {
    super(message);
    this.statusCode = statusCode;
    this.errors = errors;
    this.isOperational = true;
    Error.captureStackTrace(this, this.constructor);
  }
}

module.exports = ApiError;

// src/utils/asyncHandler.js
exports.asyncHandler = (fn) => (req, res, next) => {
  Promise.resolve(fn(req, res, next)).catch(next);
};

// src/middleware/errorHandler.js
const logger = require('../config/logger');

exports.errorHandler = (err, req, res, next) => {
  let statusCode = err.statusCode || 500;
  let message = err.message || 'Internal Server Error';

  // Sequelize validation errors
  if (err.name === 'SequelizeValidationError') {
    statusCode = 400;
    message = 'Validation error';
  }

  // Sequelize unique constraint
  if (err.name === 'SequelizeUniqueConstraintError') {
    statusCode = 409;
    message = 'Resource already exists';
  }

  // Log server errors
  if (statusCode >= 500) {
    logger.error({
      message: err.message,
      stack: err.stack,
      url: req.originalUrl,
      method: req.method,
      ip: req.ip,
    });
  }

  res.status(statusCode).json({
    success: false,
    message,
    ...(process.env.NODE_ENV === 'development' && { stack: err.stack }),
    ...(err.errors?.length && { errors: err.errors }),
  });
};

ਪੁੱਛਗਿੱਛ ਅਨੁਕੂਲਨ ਅਤੇ ਇੰਡੈਕਸਿੰਗ

ਕੁਸ਼ਲ ਡਾਟਾਬੇਸ ਪੁੱਛਗਿੱਛ ਬੈਕਐਂਡ ਪ੍ਰਦਰਸ਼ਨ ਲਈ ਮਹੱਤਵਪੂਰਨ ਹਨ। ਆਪਣੇ MySQL ਸਵਾਲਾਂ ਨੂੰ ਤੇਜ਼ ਰੱਖਣ ਲਈ ਇਹਨਾਂ ਰਣਨੀਤੀਆਂ ਦਾ ਪਾਲਣ ਕਰੋ।

  • ਅਕਸਰ ਪੁੱਛੇ ਜਾਣ ਵਾਲੇ ਕਾਲਮਾਂ 'ਤੇ ਸੂਚਕਾਂਕ ਦੀ ਵਰਤੋਂ ਕਰੋ- ਜਿੱਥੇ ਧਾਰਾਵਾਂ, ਜੁਆਇਨ ਸ਼ਰਤਾਂ, ਅਤੇ ਕਥਨਾਂ ਦੁਆਰਾ ਆਦੇਸ਼ ਵਿੱਚ ਵਰਤੇ ਗਏ ਕਾਲਮਾਂ 'ਤੇ ਸੂਚਕਾਂਕ ਸ਼ਾਮਲ ਕਰੋ। ਸੰਯੁਕਤ ਸੂਚਕਾਂਕ ਨੂੰ ਖੱਬੇ ਪਾਸੇ ਦੇ ਅਗੇਤਰ ਨਿਯਮ ਦੀ ਪਾਲਣਾ ਕਰਨੀ ਚਾਹੀਦੀ ਹੈ।
  • ਚੋਣ ਤੋਂ ਪਰਹੇਜ਼ ਕਰੋ *- ਹਮੇਸ਼ਾ ਲੋੜੀਂਦੇ ਕਾਲਮਾਂ ਨੂੰ ਨਿਸ਼ਚਿਤ ਕਰੋ। ਇਹ ਡੇਟਾ ਟ੍ਰਾਂਸਫਰ ਨੂੰ ਘਟਾਉਂਦਾ ਹੈ ਅਤੇ MySQL ਨੂੰ ਕਵਰਿੰਗ ਇੰਡੈਕਸ ਦੀ ਵਰਤੋਂ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿੰਦਾ ਹੈ।
  • ਪੁੱਛਗਿੱਛਾਂ ਦਾ ਵਿਸ਼ਲੇਸ਼ਣ ਕਰਨ ਲਈ EXPLAIN ਦੀ ਵਰਤੋਂ ਕਰੋ- ਐਗਜ਼ੀਕਿਊਸ਼ਨ ਯੋਜਨਾ ਨੂੰ ਸਮਝਣ ਲਈ ਆਪਣੀਆਂ ਪੁੱਛਗਿੱਛਾਂ ਤੋਂ ਪਹਿਲਾਂEXPLAINਚਲਾਓ। ਪੂਰੇ ਟੇਬਲ ਸਕੈਨ, ਫਾਈਲਸੌਰਟ ਓਪਰੇਸ਼ਨ, ਅਤੇ ਅਸਥਾਈ ਟੇਬਲਾਂ ਦੀ ਭਾਲ ਕਰੋ।
  • ਪੰਨਾਬੰਦੀ ਨੂੰ ਅਨੁਕੂਲਿਤ ਕਰੋ- ਵੱਡੇ ਡੇਟਾਸੇਟਾਂ ਲਈ, OFFSET ਦੀ ਬਜਾਏ ਕਰਸਰ-ਅਧਾਰਿਤ ਪੰਨਾ ਕ੍ਰਮ (ਕੀਸੈੱਟ ਪੰਨਾਬੰਦੀ) ਦੀ ਵਰਤੋਂ ਕਰੋ, ਜੋ ਉੱਚ ਪੰਨਾ ਨੰਬਰਾਂ 'ਤੇ ਹੌਲੀ ਹੋ ਜਾਂਦੀ ਹੈ।
// Inefficient OFFSET pagination
const [rows] = await pool.execute(
  'SELECT * FROM products ORDER BY created_at DESC LIMIT ? OFFSET ?',
  [limit, (page - 1) * limit]
);

// Efficient cursor-based pagination
const [rows] = await pool.execute(
  `SELECT id, name, price, created_at FROM products
   WHERE created_at < ?
   ORDER BY created_at DESC
   LIMIT ?`,
  [cursor, limit]
);

ਡਾਟਾਬੇਸ ਮਾਈਗ੍ਰੇਸ਼ਨ

ਕਦੇ ਵੀ ਉਤਪਾਦਨ ਡੇਟਾਬੇਸ ਨੂੰ ਹੱਥੀਂ ਨਾ ਸੋਧੋ। ਸੰਸਕਰਣ-ਨਿਯੰਤਰਿਤ ਸਕੀਮਾ ਤਬਦੀਲੀਆਂ ਲਈ ਸੀਕਵਲਾਈਜ਼ ਮਾਈਗ੍ਰੇਸ਼ਨ ਦੀ ਵਰਤੋਂ ਕਰੋ।

// migrations/20250101000000-create-products-table.js
module.exports = {
  up: async (queryInterface, Sequelize) => {
    await queryInterface.createTable('products', {
      id: {
        type: Sequelize.UUID,
        defaultValue: Sequelize.UUIDV4,
        primaryKey: true,
      },
      name: {
        type: Sequelize.STRING(255),
        allowNull: false,
      },
      price: {
        type: Sequelize.DECIMAL(10, 2),
        allowNull: false,
      },
      sku: {
        type: Sequelize.STRING(100),
        unique: true,
        allowNull: false,
      },
      category_id: {
        type: Sequelize.UUID,
        references: {
          model: 'categories',
          key: 'id',
        },
        onUpdate: 'CASCADE',
        onDelete: 'SET NULL',
      },
      created_at: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
      },
      updated_at: {
        type: Sequelize.DATE,
        defaultValue: Sequelize.literal('CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP'),
      },
    });

    await queryInterface.addIndex('products', ['sku']);
    await queryInterface.addIndex('products', ['category_id']);
    await queryInterface.addIndex('products', ['created_at']);
  },

  down: async (queryInterface) => {
    await queryInterface.dropTable('products');
  },
};

ਦਰ ਸੀਮਾ

ਦਰ ਸੀਮਾ ਦੇ ਨਾਲ ਆਪਣੇ API ਨੂੰ ਦੁਰਵਿਵਹਾਰ ਤੋਂ ਬਚਾਓ। ਵੰਡੀਆਂ ਤੈਨਾਤੀਆਂ ਲਈ Redis ਸਟੋਰ ਦੇ ਨਾਲexpress-rate-limitਦੀ ਵਰਤੋਂ ਕਰੋ।

// src/middleware/rateLimiter.js
const rateLimit = require('express-rate-limit');
const RedisStore = require('rate-limit-redis');
const redis = require('../config/redis');

exports.apiLimiter = rateLimit({
  store: new RedisStore({ sendCommand: (...args) => redis.call(...args) }),
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100,
  message: {
    success: false,
    message: 'Too many requests, please try again later',
  },
  standardHeaders: true,
  legacyHeaders: false,
});

exports.authLimiter = rateLimit({
  store: new RedisStore({ sendCommand: (...args) => redis.call(...args) }),
  windowMs: 15 * 60 * 1000,
  max: 5,
  message: {
    success: false,
    message: 'Too many login attempts, please try again later',
  },
  skipSuccessfulRequests: true,
});

ਵਿੰਸਟਨ ਨਾਲ ਲੌਗਿੰਗ

ਪ੍ਰੋਡਕਸ਼ਨ ਐਪਲੀਕੇਸ਼ਨਾਂ ਨੂੰ ਮਲਟੀਪਲ ਟ੍ਰਾਂਸਪੋਰਟਾਂ ਅਤੇ ਲੌਗ ਪੱਧਰਾਂ ਦੇ ਨਾਲ ਢਾਂਚਾਗਤ ਲੌਗਿੰਗ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ।

// src/config/logger.js
const winston = require('winston');

const logger = winston.createLogger({
  level: process.env.LOG_LEVEL || 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.errors({ stack: true }),
    winston.format.json()
  ),
  defaultMeta: { service: 'api-server' },
  transports: [
    new winston.transports.File({
      filename: 'logs/error.log',
      level: 'error',
      maxsize: 5242880, // 5MB
      maxFiles: 5,
    }),
    new winston.transports.File({
      filename: 'logs/combined.log',
      maxsize: 5242880,
      maxFiles: 10,
    }),
  ],
});

if (process.env.NODE_ENV !== 'production') {
  logger.add(new winston.transports.Console({
    format: winston.format.combine(
      winston.format.colorize(),
      winston.format.simple()
    ),
  }));
}

module.exports = logger;

Docker ਤੈਨਾਤੀ

ਵਾਤਾਵਰਣ ਵਿੱਚ ਇਕਸਾਰ ਤੈਨਾਤੀਆਂ ਲਈ ਆਪਣੀ ਐਪਲੀਕੇਸ਼ਨ ਨੂੰ ਕੰਟੇਨਰਾਈਜ਼ ਕਰੋ।

# Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:20-alpine
WORKDIR /app
RUN addgroup -g 1001 -S appgroup && \
    adduser -S appuser -u 1001 -G appgroup
COPY --from=builder /app/node_modules ./node_modules
COPY src/ ./src/
COPY migrations/ ./migrations/
COPY package.json ./
USER appuser
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
CMD ["node", "src/server.js"]
# docker-compose.yml
version: '3.8'
services:
  api:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DB_HOST=mysql
      - DB_USER=app_user
      - DB_PASSWORD_FILE=/run/secrets/db_password
      - DB_NAME=myapp
    depends_on:
      mysql:
        condition: service_healthy
    restart: unless-stopped

  mysql:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password
      MYSQL_DATABASE: myapp
      MYSQL_USER: app_user
      MYSQL_PASSWORD_FILE: /run/secrets/db_password
    volumes:
      - mysql_data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  mysql_data:

ਸਿੱਟਾ

ਇੱਕ ਮਜ਼ਬੂਤ ​​Node.js ਅਤੇ MySQL ਬੈਕਐਂਡ ਬਣਾਉਣ ਲਈ ਆਰਕੀਟੈਕਚਰ, ਸੁਰੱਖਿਆ, ਪ੍ਰਦਰਸ਼ਨ, ਅਤੇ ਸੰਚਾਲਨ ਸੰਬੰਧੀ ਚਿੰਤਾਵਾਂ ਵੱਲ ਧਿਆਨ ਦੇਣ ਦੀ ਲੋੜ ਹੈ। ਇੱਕ ਸਾਫ਼ ਪ੍ਰੋਜੈਕਟ ਢਾਂਚਾ ਸਥਾਪਤ ਕਰਕੇ, ਸਹੀ ਪ੍ਰਮਾਣਿਕਤਾ ਅਤੇ ਪ੍ਰਮਾਣਿਕਤਾ ਨੂੰ ਲਾਗੂ ਕਰਕੇ, ਡੇਟਾਬੇਸ ਪੁੱਛਗਿੱਛਾਂ ਨੂੰ ਅਨੁਕੂਲਿਤ ਕਰਕੇ, ਅਤੇ ਤੁਹਾਡੀ ਤੈਨਾਤੀ ਨੂੰ ਕੰਟੇਨਰਾਈਜ਼ ਕਰਕੇ, ਤੁਸੀਂ ਇੱਕ ਬੈਕਐਂਡ ਬਣਾਉਂਦੇ ਹੋ ਜੋ ਸੁਰੱਖਿਅਤ, ਪ੍ਰਦਰਸ਼ਨਸ਼ੀਲ ਅਤੇ ਸਾਂਭਣਯੋਗ ਹੈ। ਇਸ ਗਾਈਡ ਵਿੱਚ ਦੱਸੇ ਗਏ ਬੁਨਿਆਦੀ ਤੱਤਾਂ ਨਾਲ ਸ਼ੁਰੂ ਕਰੋ, ਯਥਾਰਥਵਾਦੀ ਲੋਡ ਦੇ ਅਧੀਨ ਆਪਣੀ ਐਪਲੀਕੇਸ਼ਨ ਦੀ ਕਾਰਗੁਜ਼ਾਰੀ ਨੂੰ ਮਾਪੋ, ਅਤੇ ਤੁਹਾਡੇ ਦੁਆਰਾ ਖੋਜੀਆਂ ਗਈਆਂ ਰੁਕਾਵਟਾਂ ਨੂੰ ਦੁਹਰਾਓ। ਇੱਥੇ ਪੇਸ਼ ਕੀਤੇ ਗਏ ਪੈਟਰਨ ਹਜ਼ਾਰਾਂ ਉਤਪਾਦਨ ਐਪਲੀਕੇਸ਼ਨਾਂ ਵਿੱਚ ਸਾਬਤ ਹੋਏ ਹਨ ਅਤੇ ਤੁਹਾਡੇ ਬੈਕਐਂਡ ਸਿਸਟਮਾਂ ਲਈ ਇੱਕ ਠੋਸ ਬੁਨਿਆਦ ਵਜੋਂ ਕੰਮ ਕਰਨਗੇ।