Node.js Real-World Examples

நடைமுறை Node.js பயன்பாடுகள் மற்றும் உதாரணங்களை கற்றுக்கொள்ளுங்கள்

Express உடன் RESTful API

மிகவும் பொதுவான Node.js பயன்பாடுகளில் ஒன்று RESTful APIகளை உருவாக்குவதாகும். Express உடன் ஒரு எளிய ஆனால் நடைமுறை Todo API இன் உதாரணம் இங்கே:

const express = require('express');
const app = express();

// In-memory data store (in a real app, you would use a database)
let todos = [
  { id: 1, title: 'Learn Node.js', completed: false },
  { id: 2, title: 'Build a REST API', completed: false }
];

// Middleware
app.use(express.json());

// Log all requests
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

// GET all todos
app.get('/todos', (req, res) => {
  res.json(todos);
});

// GET a single todo
app.get('/todos/:id', (req, res) => {
  const todo = todos.find(t => t.id === parseInt(req.params.id));
  if (!todo) return res.status(404).json({ error: 'Todo not found' });
  res.json(todo);
});

// POST a new todo
app.post('/todos', (req, res) => {
  if (!req.body.title) {
    return res.status(400).json({ error: 'Title is required' });
  }
  
  const newTodo = {
    id: todos.length > 0 ? Math.max(...todos.map(t => t.id)) + 1 : 1,
    title: req.body.title,
    completed: req.body.completed || false
  };
  
  todos.push(newTodo);
  res.status(201).json(newTodo);
});

// PUT (update) a todo
app.put('/todos/:id', (req, res) => {
  const todo = todos.find(t => t.id === parseInt(req.params.id));
  if (!todo) return res.status(404).json({ error: 'Todo not found' });
  
  if (req.body.title) todo.title = req.body.title;
  if (req.body.completed !== undefined) todo.completed = req.body.completed;
  
  res.json(todo);
});

// DELETE a todo
app.delete('/todos/:id', (req, res) => {
  const index = todos.findIndex(t => t.id === parseInt(req.params.id));
  if (index === -1) return res.status(404).json({ error: 'Todo not found' });
  
  const deletedTodo = todos[index];
  todos.splice(index, 1);
  
  res.json(deletedTodo);
});

// Error handling middleware
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Something went wrong!' });
});

// Start the server
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

இந்த உதாரணம் சரியான பிழை கையாளுதல் மற்றும் நிலை குறியீடுகளுடன் ஒரு முழுமையான CRUD (Create, Read, Update, Delete) API ஐ நிரூபிக்கிறது.

அங்கீகார அமைப்பு

பெரும்பாலான பயன்பாடுகளுக்கு அங்கீகாரம் தேவைப்படுகிறது. Node.js இல் JWT-அடிப்படையிலான அங்கீகாரத்தின் உதாரணம் இங்கே:

const express = require('express');
const jwt = require('jsonwebtoken');
const bcrypt = require('bcrypt');

const app = express();
app.use(express.json());

// In a real app, use a database
const users = [];

// Secret key for JWT
const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';

// Register a new user
app.post('/register', async (req, res) => {
  try {
    const { username, password } = req.body;
    
    // Check if user already exists
    if (users.find(u => u.username === username)) {
      return res.status(400).json({ error: 'Username already exists' });
    }
    
    // Hash the password
    const hashedPassword = await bcrypt.hash(password, 10);
    
    // Create new user
    const user = {
      id: users.length + 1,
      username,
      password: hashedPassword
    };
    
    users.push(user);
    
    res.status(201).json({ message: 'User registered successfully' });
  } catch (error) {
    res.status(500).json({ error: 'Registration failed' });
  }
});

// Login
app.post('/login', async (req, res) => {
  try {
    const { username, password } = req.body;
    
    // Find user
    const user = users.find(u => u.username === username);
    if (!user) {
      return res.status(401).json({ error: 'Invalid credentials' });
    }
    
    // Check password
    const passwordMatch = await bcrypt.compare(password, user.password);
    if (!passwordMatch) {
      return res.status(401).json({ error: 'Invalid credentials' });
    }
    
    // Generate JWT token
    const token = jwt.sign(
      { userId: user.id, username: user.username },
      JWT_SECRET,
      { expiresIn: '1h' }
    );
    
    res.json({ token });
  } catch (error) {
    res.status(500).json({ error: 'Authentication failed' });
  }
});

// Middleware to verify JWT token
function authenticateToken(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
  
  if (!token) return res.status(401).json({ error: 'Authentication required' });
  
  jwt.verify(token, JWT_SECRET, (err, user) => {
    if (err) return res.status(403).json({ error: 'Invalid or expired token' });
    req.user = user;
    next();
  });
}

// Protected route example
app.get('/profile', authenticateToken, (req, res) => {
  res.json({ user: req.user });
});

app.listen(8080, () => {
  console.log('Authentication server running on port 8080');
});

கோப்பு பதிவேற்ற சேவை

Node.js கோப்பு பதிவேற்றங்களை கையாளுவதை எளிதாக்குகிறது, இது பல வலை பயன்பாடுகளில் பொதுவானது:

const express = require('express');
const multer = require('multer');
const path = require('path');
const fs = require('fs');

const app = express();
app.use(express.json());
app.use(express.static('public'));

// Configure multer storage
const storage = multer.diskStorage({
  destination: (req, file, cb) => {
    const uploadDir = './uploads';
    
    // Create directory if it doesn't exist
    if (!fs.existsSync(uploadDir)) {
      fs.mkdirSync(uploadDir);
    }
    
    cb(null, uploadDir);
  },
  filename: (req, file, cb) => {
    // Generate unique filename with original extension
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    const ext = path.extname(file.originalname);
    cb(null, file.fieldname + '-' + uniqueSuffix + ext);
  }
});

// File filter function
const fileFilter = (req, file, cb) => {
  // Accept images and PDFs only
  if (file.mimetype.startsWith('image/') || file.mimetype === 'application/pdf') {
    cb(null, true);
  } else {
    cb(new Error('Unsupported file type'), false);
  }
};

const upload = multer({
  storage: storage,
  fileFilter: fileFilter,
  limits: { fileSize: 5 * 1024 * 1024 } // 5MB limit
});

// Serve upload form
app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, 'public', 'index.html'));
});

// Single file upload endpoint
app.post('/upload/single', upload.single('file'), (req, res) => {
  if (!req.file) {
    return res.status(400).json({ error: 'No file uploaded' });
  }
  
  res.json({
    message: 'File uploaded successfully',
    file: {
      filename: req.file.filename,
      originalname: req.file.originalname,
      mimetype: req.file.mimetype,
      size: req.file.size
    }
  });
});

// Multiple file upload endpoint (max 5)
app.post('/upload/multiple', upload.array('files', 5), (req, res) => {
  if (!req.files || req.files.length === 0) {
    return res.status(400).json({ error: 'No files uploaded' });
  }
  
  res.json({
    message: `${req.files.length} files uploaded successfully`,
    files: req.files.map(file => ({
      filename: file.filename,
      originalname: file.originalname,
      mimetype: file.mimetype,
      size: file.size
    }))
  });
});

// Error handling middleware
app.use((err, req, res, next) => {
  if (err instanceof multer.MulterError) {
    // Multer-specific errors
    return res.status(400).json({ error: err.message });
  } else if (err) {
    // Other errors
    return res.status(500).json({ error: err.message });
  }
  next();
});

app.listen(8080, () => {
  console.log('File upload server running on port 8080');
});

மைக்ரோசர்விஸ் கட்டமைப்பு

Node.js மைக்ரோசர்விஸ்களை உருவாக்க சிறந்தது. சுகாதார சோதனைகள் மற்றும் சரியான கவனிப்பு பிரிப்புடன் ஒரு மைக்ரோசர்விஸின் எளிய உதாரணம் இங்கே:

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

const app = express();

// Middleware
app.use(express.json());
app.use(logger);

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

// Routes
app.use('/api/products', routes.productRoutes);

// Error handling
app.use(errorHandler);

// Start server
app.listen(config.PORT, () => {
  console.log(`Product catalog service running on port ${config.PORT}`);
});

// Handle graceful shutdown
process.on('SIGTERM', () => {
  console.log('SIGTERM received, shutting down gracefully');
  // Close database connections, etc.
  process.exit(0);
});
// src/routes/productRoutes.js
const express = require('express');
const productController = require('../controllers/productController');

const router = express.Router();

router.get('/', productController.getAllProducts);
router.get('/:id', productController.getProductById);
router.post('/', productController.createProduct);
router.put('/:id', productController.updateProduct);
router.delete('/:id', productController.deleteProduct);

module.exports = router;

🏗️ சிறந்த நடைமுறை:

ஒரு உண்மையான மைக்ரோசர்விஸ் கட்டமைப்பில், ஒவ்வொரு சேவைக்கும் அதன் சொந்த களஞ்சியம், விநியோக குழாய் மற்றும் தரவுத்தளம் இருக்கும்.

பணி திட்டமிடல்

Node.js திட்டமிடப்பட்ட பணிகள் மற்றும் பின்னணி வேலைகளை திறம்பட கையாள முடியும்:

const cron = require('node-cron');
const nodemailer = require('nodemailer');
const express = require('express');

const app = express();

// Configure mail transporter (this is just an example)
const transporter = nodemailer.createTransport({
  host: 'smtp.example.com',
  port: 587,
  secure: false,
  auth: {
    user: 'user@example.com',
    pass: 'password'
  }
});

// Schedule a task to run every day at 9:00 AM
cron.schedule('0 9 * * *', async () => {
  console.log('Running daily report task');
  
  try {
    // Generate report data (in a real app, fetch from database)
    const reportData = {
      date: new Date().toISOString().split('T')[0],
      metrics: {
        users: 1250,
        orders: 350,
        revenue: 12500
      }
    };
    
    // Send email with report
    await transporter.sendMail({
      from: 'system@example.com',
      to: 'admin@example.com',
      subject: `Daily Report - ${reportData.date}`,
      html: `
        

Daily Report

Date: ${reportData.date}

Key Metrics

  • Users: ${reportData.metrics.users}
  • Orders: ${reportData.metrics.orders}
  • Revenue: $${reportData.metrics.revenue}
` }); console.log('Daily report email sent successfully'); } catch (error) { console.error('Error sending daily report:', error); } }); // Schedule database backup every Sunday at midnight cron.schedule('0 0 * * 0', () => { console.log('Running weekly database backup'); // In a real app, you would run a database backup command here }); // Clean up temporary files every hour cron.schedule('0 * * * *', () => { console.log('Cleaning up temporary files'); // In a real app, you would delete old temporary files here }); // API to add a one-time job const scheduledJobs = new Map(); app.use(express.json()); app.post('/schedule-job', (req, res) => { const { id, scheduledTime, task } = req.body; if (!id || !scheduledTime || !task) { return res.status(400).json({ error: 'Missing required parameters' }); } const jobTime = new Date(scheduledTime).getTime(); const currentTime = Date.now(); if (jobTime <= currentTime) { return res.status(400).json({ error: 'Scheduled time must be in the future' }); } // Schedule the job const timeout = setTimeout(() => { console.log(`Executing job: ${id}`); // In a real app, use a job queue like Bull to handle the tasks console.log(`Task: ${task}`); scheduledJobs.delete(id); }, jobTime - currentTime); scheduledJobs.set(id, { timeout, scheduledTime, task }); res.status(201).json({ message: 'Job scheduled successfully', job: { id, scheduledTime, task } }); }); // Start server app.listen(8080, () => { console.log('Task scheduler running on port 8080'); });

நிகழ்நேர பகுப்பாய்வு டாஷ்போர்டு

WebSockets மற்றும் Chart.js உடன் பயன்பாட்டு அளவீடுகளை நிகழ்நேரத்தில் கண்காணித்து காட்சிப்படுத்தவும்:

const express = require('express');
const http = require('http');
const socketIo = require('socket.io');
const { v4: uuidv4 } = require('uuid');

const app = express();
const server = http.createServer(app);
const io = socketIo(server, {
  cors: {
    origin: '*', // In production, replace with your frontend domain
    methods: ['GET', 'POST']
  }
});

// In-memory store for analytics data (use a database in production)
const analyticsData = {
  pageViews: {},
  activeUsers: new Set(),
  events: []
};

// Track page views
app.use((req, res, next) => {
  const page = req.path;
  analyticsData.pageViews[page] = (analyticsData.pageViews[page] || 0) + 1;
  
  // Emit update to all connected clients
  io.emit('analytics:update', {
    type: 'pageView',
    data: { page, count: analyticsData.pageViews[page] }
  });
  
  next();
});

// Track custom events
app.post('/track', express.json(), (req, res) => {
  const { event, data } = req.body;
  const eventId = uuidv4();
  const timestamp = new Date().toISOString();
  
  const eventData = { id: eventId, event, data, timestamp };
  analyticsData.events.push(eventData);
  
  // Keep only the last 1000 events
  if (analyticsData.events.length > 1000) {
    analyticsData.events.shift();
  }
  
  // Emit event to all connected clients
  io.emit('analytics:event', eventData);
  
  res.status(201).json({ success: true, eventId });
});

// WebSocket connection handling
io.on('connection', (socket) => {
  const userId = socket.handshake.query.userId || 'anonymous';
  analyticsData.activeUsers.add(userId);
  
  // Send initial data to the newly connected client
  socket.emit('analytics:init', {
    pageViews: analyticsData.pageViews,
    activeUsers: analyticsData.activeUsers.size,
    recentEvents: analyticsData.events.slice(-50)
  });
  
  // Update all clients about the new active user count
  io.emit('analytics:update', {
    type: 'activeUsers',
    data: analyticsData.activeUsers.size
  });
  
  // Handle disconnection
  socket.on('disconnect', () => {
    analyticsData.activeUsers.delete(userId);
    io.emit('analytics:update', {
      type: 'activeUsers',
      data: analyticsData.activeUsers.size
    });
  });
  
  // Handle custom events from the client
  socket.on('analytics:event', (data) => {
    const eventId = uuidv4();
    const timestamp = new Date().toISOString();
    const eventData = { id: eventId, ...data, timestamp, userId };
    
    analyticsData.events.push(eventData);
    if (analyticsData.events.length > 1000) {
      analyticsData.events.shift();
    }
    
    io.emit('analytics:event', eventData);
  });
});

// API to get analytics data
app.get('/api/analytics', (req, res) => {
  res.json({
    pageViews: analyticsData.pageViews,
    activeUsers: analyticsData.activeUsers.size,
    totalEvents: analyticsData.events.length,
    recentEvents: analyticsData.events.slice(-50)
  });
});

// Serve the dashboard
app.use(express.static('public'));

const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`Analytics server running on port ${PORT}`);
  console.log(`Dashboard available at http://localhost:${PORT}/dashboard.html`);
});

⚠️ உற்பத்தி பயன்பாட்டிற்கான குறிப்பு:

பகுப்பாய்வு தரவை தரவுத்தளத்தில் நிலைநிறுத்துவதையும் சரியான அங்கீகாரத்தை செயல்படுத்துவதையும் கருத்தில் கொள்ளுங்கள்.

நடைமுறை Node.js பயன்பாடுகளுக்கான சிறந்த நடைமுறைகள்

உற்பத்தி Node.js பயன்பாடுகளை உருவாக்கும் போது, இந்த சிறந்த நடைமுறைகளைப் பின்பற்றவும்:

பயன்பாட்டு கட்டமைப்பு

தெளிவான திட்ட கட்டமைப்பைப் பயன்படுத்தவும் (MVC அல்லது ஒத்த)
வழிகளிலிருந்து வணிக தர்க்கத்தைப் பிரிக்கவும்
சூழல் மாறிகளில் உள்ளமைப்பை வைத்திருங்கள்
தேவையான இடங்களில் சார்பு உட்செலுத்தலைப் பயன்படுத்தவும்

பிழை கையாளுதல்

உலகளாவிய பிழை கையாளுதல் மிடில்வேரை செயல்படுத்தவும்
சரியான சூழலுடன் பிழைகளை பதிவு செய்யவும்
பொருத்தமான HTTP நிலை குறியீடுகளை வழங்கவும்
கைப்பற்றப்படாத விதிவிலக்குகள் மற்றும் கையாளப்படாத வாக்குறுதிகளை கையாளவும்

பாதுகாப்பு

எப்போதும் பயனர் உள்ளீட்டை சரிபார்க்கவும் மற்றும் சுத்திகரிக்கவும்
HTTPS மற்றும் பாதுகாப்பான குக்கீகளைப் பயன்படுத்தவும்
APIகளுக்கு விகித வரம்பை செயல்படுத்தவும்
சார்புகளை புதுப்பித்து வைக்கவும்
பாதுகாப்பு தலைப்புகளைப் பயன்படுத்தவும் (Helmet.js)

செயல்திறன் & அளவிடுதிறன்

HTTP பதில்களுக்கு சுருக்கத்தைப் பயன்படுத்தவும்
சரியான தற்காலிக சேமிப்பு உத்திகளை செயல்படுத்தவும்
பல-கோர் பயன்பாட்டிற்கு கிளஸ்டர் அல்லது PM2 ஐப் பயன்படுத்தவும்
நினைவக பயன்பாட்டை கண்காணிக்கவும் மற்றும் குப்பை சேகரிப்பை செயல்படுத்தவும்
சிறந்த வாசிப்புத்திறனுக்கு async/await ஐப் பயன்படுத்தவும்

💡 தொழில்முறை உதவிக்குறிப்பு:

உற்பத்தி பயன்பாடுகளுக்கு, சிக்கல்களை விரைவாக அடையாளம் கண்டு தீர்க்க விரிவான கண்காணிப்பு, பதிவு மற்றும் எச்சரிக்கையை எப்போதும் சேர்க்கவும்.

பயிற்சி

Node.js பயன்பாடுகளில் அங்கீகாரத்திற்காக, தரப்புகளுக்கு இடையே கோரிக்கைகளை பாதுகாப்பாக பரிமாற பொதுவாகப் பயன்படுத்தப்படும் தொழில்நுட்பத்தைத் தேர்வு செய்யவும்.

Cookies
✗ தவறு! குக்கீக்கள் அங்கீகாரத்திற்கு பயன்படுத்தப்படலாம், ஆனால் தரப்புகளுக்கு இடையே கோரிக்கைகளை பாதுகாப்பாக பரிமாறுவதற்கு JWTகள் பொதுவாகப் பயன்படுத்தப்படுகின்றன
Sessions
✗ தவறு! அமர்வுகள் அங்கீகாரத்திற்கு பயன்படுத்தப்படலாம், ஆனால் தரப்புகளுக்கு இடையே கோரிக்கைகளை பாதுகாப்பாக பரிமாறுவதற்கு JWTகள் பொதுவாகப் பயன்படுத்தப்படுகின்றன
JWT
✓ சரி! JWTகள் (JSON Web Tokens) தரப்புகளுக்கு இடையே கோரிக்கைகளை பாதுகாப்பாக பரிமாற பொதுவாகப் பயன்படுத்தப்படும் ஒரு திறந்த தரநிலையாகும்
OAuth
✗ தவறு! OAuth ஒரு அங்கீகார நெறிமுறையாகும், ஆனால் தரப்புகளுக்கு இடையே கோரிக்கைகளை பரிமாறுவதற்கு JWTகள் பொதுவாகப் பயன்படுத்தப்படும் டோக்கன்களாகும்