Haqiqiy loyihalar misollari
Express bilan RESTful API
Eng keng tarqalgan Node.js ilovalaridan biri bu RESTful API yaratishdir. Express bilan oddiy, ammo amaliy Todo API misoli:
Misol: Express bilan 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}`);
});
Ushbu misol xatolarni to‘g‘ri qayta ishlash va status kodlariga ega to‘liq CRUD (Create, Read, Update, Delete) API’ni namoyish etadi.
Autentifikatsiya tizimi
Aksariyat ilovalar autentifikatsiyani talab qiladi. Node.js da JWT asosidagi autentifikatsiyaga misol:
Misol: Express yordamida JWT autentifikatsiyasi
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');
});
Fayl yuklash xizmati
Node.js ko‘plab veb-ilovalarda keng tarqalgan fayllarni yuklashni osonlashtiradi:
Misol: Express va Multer bilan fayl yuklash
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');
});
Mikroservis arxitekturasi
Node.js mikroservislarni yaratish uchun ideal. Salomatlik tekshiruvlari va tashvishlarni to‘g‘ri ajratish bilan mikroservisning oddiy misoli:
Misol: Mikroservis mahsulot katalogi
// 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;
Eng yaxshi amaliyot: Haqiqiy mikroservis arxitekturasida har bir xizmat o‘z ombori, tarqatish pipeline va ma’lumotlar bazasiga ega bo‘ladi.
Vazifalarni rejalashtiruvchi
Node.js rejalashtirilgan vazifalar va fon ishlarini samarali bajarishi mumkin:
Misol: Cronga o‘xshash vazifalarni rejalashtiruvchi
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: `
<h1>Daily Report</h1>
<p><strong>Date:</strong> ${reportData.date}</p>
<h2>Key Metrics</h2>
<ul>
<li>Users: ${reportData.metrics.users}</li>
<li>Orders: ${reportData.metrics.orders}</li>
<li>Revenue: $${reportData.metrics.revenue}</li>
</ul>
`
});
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');
});
Haqiqiy vaqtda Analytics boshqaruv paneli
WebSockets va Chart.js yordamida real vaqtda ilova ko‘rsatkichlarini kuzatib boring va vizualizatsiya qiling:
Misol: Real-time Analytics Server
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`);
});
Eslatma: Ishlab chiqarishda foydalanish uchun ma’lumotlar bazasida doimiy tahlil ma’lumotlarini saqlash va tegishli autentifikatsiyani amalga oshirishni ko‘rib chiqing.
Haqiqiy dunyo Node.js ilovalari uchun eng yaxshi amaliyotlar
Node.js ishlab chiqarish ilovalarini yaratishda quyidagi eng yaxshi amaliyotlarga amal qiling:
Ilova tuzilishi
- Aniq loyiha tuzilmasidan foydalaning (MVC yoki shunga o‘xshash)
- Biznes mantiqini marshrutlardan ajrating
- Konfiguratsiyani muhit o‘zgaruvchilarida saqlang
- Kerakli hollarda qaramlik in’ektsiyasidan foydalaning
Xato bilan ishlash
- Xatolarni qayta ishlash uchun global dasturni joriy qiling
- Xatolarni tegishli kontekst bilan qayd qiling
- Tegishli HTTP holat kodlarini qaytaring
- Tugallanmagan istisnolar va bajarilmagan Promiselarni bajaring
Xavfsizlik
- Har doim foydalanuvchi ma’lumotlarini tekshiring va tozalang
- HTTPS va xavfsiz cookie-fayllardan foydalaning
- API uchun tezlikni cheklashni amalga oshiring
- Bog‘liqlarni yangilab turing
- Xavfsizlik sarlavhalaridan foydalaning (Helmet.js)
Ishlash va masshtablilik
- HTTP javoblari uchun siqishni foydalaning
- To‘g‘ri keshlash strategiyalarini amalga oshiring
- Ko‘p yadroli foydalanish uchun klaster yoki PM2 dan foydalanishni o‘ylab ko‘ring
- Xotiradan foydalanishni kuzatib boring va axlat yig‘ishni amalga oshiring
- Yaxshiroq o‘qilishi uchun async/wait dan foydalaning
Professional Maslahat: Ishlab chiqarish ilovalari uchun har doim muammolarni tezda aniqlash va hal qilish uchun keng qamrovli monitoring, jurnallar va ogohlantirishlarni o‘z ichiga oladi.
W3Schools Pathfinder
Yutuqlaringizni kuzating – bu bepul!
