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 PromoterWSL VaultJobshoutSysOps 24/7
بلاگ
ہم سے رابطہ کریںLogin
Workstation

جدید کاروبار کے لیے AI ورک اسٹیشنز، AI ملٹی ایجنٹک سافٹ ویئر، GPU انفراسٹرکچر اور ذہین ایجنٹ حل۔

ہم سے رابطہ کریں

AI حل

AI ورک سٹیشنزAI SME Packagesپرائیویٹ AIGPU کلسٹرزایج AIانٹرپرائز AI لیبصنعت کے مطابق AI

مصنوعات

تمام مصنوعاتWSL CRM اور ERPمارکیٹنگOpenAI ایجنٹسWSL ProxyRing PromoterWSL VaultJobshoutSysOps 24/7

کمپنی

ہمارے بارے میںWorkstation کیوںشراکت دارگاہکوں کی کہانیاںقیمتیںرابطہ

وسائل

مضامیندستاویزاتبلاگتلاشسائٹ میپ
برطانیہ آفس
77-79 Marlowes, Hemel Hempstead HP1 1LFراستہ - M25 آؤٹر لندن سے جنکشن 20 لیںکمپنی نمبر: 11641870پیر - جمعہ: صبح 9:00 - شام 6:00 GMT
+44 7515 356 146
بیلجیم آفس
Workstation SRL, Rue Vanderkindere 34, 1180 Uccle, BrusselsBE 0751.518.683پیر - جمعہ: صبح 9:00 - شام 6:00 CET
+32 492 45 67 46
بھارت آفس
#159 Sector 9, Pocket 1, DDA Flats, 110077 Dwarka, New Delhi
+91 98881 98841

© 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 + ایکسپریس بیک اینڈ آرکیٹیکچر

Middleware

20

Auth (JWT)توثیقشرح کی حدCORSHelmet کلائنٹ براؤزر / ایپAPIگیٹ وے/api/v1ایکسپریسراستے XTAG5PUTX/GTAG5PETX XTAG5PETXکنٹرولرزہینڈلنگ کی درخواستسروسزبزنس لاجکMySQLرشتہ دار DB متعلقہ DB HTTPروٹکالکالاستفسارکا جواب میٹ کامیابی کے لیے: درست،ڈیٹا: [...]،صفحہ بندی: {...}}پائپ لائن کو ہینڈل کرنے میں خرابییا 108XX108XasyncHandlerایرر ہینڈلرسنٹرلائزڈ، مستقل خرابی کے جوابات
کی ساخت کو اچھی طرح سے برقرار رکھنے کے قابل ہے۔ خدشات کو واضح طور پر الگ کریں اور جلد کنونشن قائم کریں۔

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 ڈیزائن

اپنے API اختتامی پوائنٹس کو REST کنونشن کے بعد ڈیزائن کریں۔ وسائل کے لیے اسم استعمال کریں، اعمال کے لیے 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 — ایکٹوکنکشن 2 — ایکٹوکنکشن 3 — ایکٹوکنکشن 4 — IdleXTAG19195X XTAG19 کنکشنکنکشن کی حد: 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]
);

Sequelize ORM

پیچیدہ ڈیٹا ریلیشنس والی ایپلی کیشنز کے لیے، Sequelize ایک مکمل خصوصیات فراہم کرتا ہے، جیسا کہ ORM کی تعریف کے ساتھ ماڈل اور Migration کی تعریف عمارت 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 ایک طاقتور اسکیما پر مبنی توثیق لائبریری فراہم کرتا ہے۔

// 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 سوالات کو تیز رکھنے کے لیے ان حکمت عملیوں پر عمل کریں۔

  • اکثر پوچھے گئے کالموں پر اشاریہ جات کا استعمال کریں- WHERE شقوں، JOIN حالات، اور ORDER BY بیانات میں استعمال ہونے والے کالموں پر اشاریہ جات شامل کریں۔ جامع اشاریہ جات کو سب سے بائیں سابقہ ​​اصول پر عمل کرنا چاہیے۔
  • منتخب کرنے سے گریز کریں *- ہمیشہ اپنے مطلوبہ کالموں کی وضاحت کریں۔ یہ ڈیٹا کی منتقلی کو کم کرتا ہے اور 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 پس منظر کی تعمیر کے لیے فن تعمیر، سلامتی، کارکردگی، اور آپریشنل خدشات پر توجہ دینے کی ضرورت ہے۔ پراجیکٹ کا صاف ستھرا ڈھانچہ قائم کرکے، درست تصدیق اور توثیق کو نافذ کرکے، ڈیٹا بیس کے سوالات کو بہتر بنا کر، اور اپنی تعیناتی کو کنٹینرائز کرکے، آپ ایک ایسا بیک اینڈ بناتے ہیں جو محفوظ، پرفارمنس اور برقرار رکھنے کے قابل ہو۔ اس گائیڈ میں بیان کردہ بنیادی اصولوں کے ساتھ شروع کریں، حقیقت پسندانہ بوجھ کے تحت اپنی ایپلیکیشن کی کارکردگی کی پیمائش کریں، اور آپ کو جو رکاوٹیں دریافت ہوئی ہیں ان پر اعادہ کریں۔ یہاں پیش کیے گئے پیٹرن ہزاروں پروڈکشن ایپلی کیشنز میں ثابت ہو چکے ہیں اور آپ کے بیک اینڈ سسٹمز کے لیے ایک مضبوط بنیاد کے طور پر کام کریں گے۔