Замонавий веб-иловалар деярли ҳар доим икки қисмдан иборат: фойдаланувчи кўрадиган frontend ва маълумотларни бошқарадиган backend. Ушбу икки қисмни бир-бирига боғловчи кўприк айнан REST API ҳисобланади. Node.js ва унинг устида қурилган Express framework'и бугунги кунда backend дастурлаш учун энг оммабоп танловлардан бирига айланган, чунки улар соддалиги, тезлиги ва улкан экотизими билан ажралиб туради. Ушбу мақолада биз нолдан бошлаб тўлиқ ишлайдиган REST API қуришни, route ва middleware тушунчаларини, CRUD амалларини, хатоларни бошқариш, валидация ва аутентификацияни амалий код мисоллари билан ўрганиб чиқамиз.
Express нима ва нега у керак
Express — бу Node.js учун минимал ва мослашувчан web framework бўлиб, у HTTP сўровларини қабул қилиш ва жавоб қайтариш жараёнини анча соддалаштиради. Node.js нинг ўзида ҳам веб-сервер яратиш мумкин, бироқ бунда ҳар бир сўровни қўлда таҳлил қилиш, URL'ларни солиштириш ва жавоб сарлавҳаларини созлаш каби мураккаб ишларни ўзингиз бажаришингизга тўғри келади. Express эса бу мураккабликни яшириб, сизга route'лар, middleware ва қулай ёрдамчи методлар орқали ишлаш имконини беради. Айнан шу сабабли минглаб компаниялар ва стартаплар ўз API'ларини Express асосида қурадилар, чунки у кам код ёзиб кўп натижага эришиш имконини беради.
Лойиҳани созлаш ва биринчи сервер
Ишни бошлаш учун аввало компьютерингизда Node.js ўрнатилган бўлиши керак. Кейин янги лойиҳа папкасини яратиб, ундаги пакетларни бошқариш учун npm ёрдамида лойиҳани ишга туширамиз ва Express кутубхонасини ўрнатамиз. Қуйидаги буйруқлар лойиҳанинг асосий тузилмасини тайёрлайди ва биринчи ишга тушириладиган серверни ёзишга замин яратади.
mkdir my-api && cd my-api
npm init -y
npm install express
Энди лойиҳа илдизида index.js файлини яратамиз ва энг оддий серверни ёзамиз. Бу сервер фақат битта манзилга сўров келганда жавоб қайтаради, бироқ у бизнинг бутун API'мизнинг пойдевори бўлиб хизмат қилади. Диққат қилинг, сервер маълум бир портни тинглайди ва у ишга тушганда консолга хабар чиқаради.
const express = require('express');
const app = express();
app.use(express.json());
app.get('/', (req, res) => {
res.json({ message: 'API ishlayapti' });
});
const PORT = 3000;
app.listen(PORT, () => {
console.log(`Server ${PORT}-portda ishga tushdi`);
});
Route'лар ва CRUD эндпоинтлари
REST API нинг асосий ғояси ресурслар билан ишлашдир, масалан фойдаланувчилар ёки мақолалар. Ҳар бир ресурс устида тўртта асосий амал бажарилади: яратиш, ўқиш, янгилаш ва ўчириш, яъни CRUD. Бу амаллар мос равишда POST, GET, PUT ва DELETE HTTP методлари орқали ифодаланади. Қуйидаги мисолда биз оддий массив кўринишидаги вақтинчалик маълумотлар омбори билан ишловчи тўлиқ CRUD эндпоинтларини кўриб чиқамиз.
let users = [{ id: 1, name: 'Ali' }];
app.get('/users', (req, res) => {
res.json(users);
});
app.get('/users/:id', (req, res) => {
const user = users.find(u => u.id === Number(req.params.id));
if (!user) return res.status(404).json({ error: 'Topilmadi' });
res.json(user);
});
app.post('/users', (req, res) => {
const user = { id: Date.now(), name: req.body.name };
users.push(user);
res.status(201).json(user);
});
app.delete('/users/:id', (req, res) => {
users = users.filter(u => u.id !== Number(req.params.id));
res.status(204).end();
});
Ушбу кодда req.params орқали URL'даги динамик қисмларни, req.body орқали эса сўров танасидаги JSON маълумотларни ўқиймиз. Жавоб қайтаришда HTTP ҳолат кодларини тўғри танлаш жуда муҳим: янги ресурс яратилганда 201, муваффақиятли ўчиришда 204, топилмаганда эса 404 коди қайтарилади. Бу кодлар API мижозларига нима содир бўлганини аниқ тушунтиради.
Middleware тушунчаси
Middleware — бу сўров серверга келиб, жавоб қайтгунча бўлган оралиқда ишлайдиган функциялардир. Улар орқали сиз сўровларни журналга ёзиш, аутентификацияни текшириш, маълумотларни қайта ишлаш ёки хатоларни ушлаб қолиш каби ишларни марказлаштирилган тарзда бажаришингиз мумкин. Юқорида ишлатган express.json() ҳам аслида middleware бўлиб, у келаётган JSON танасини автоматик равишда объектга айлантиради. Ўз middleware'ингизни ёзиш ҳам жуда осон.
function logger(req, res, next) {
console.log(`${req.method} ${req.url}`);
next();
}
app.use(logger);
Эътибор беринг, ҳар бир middleware охирида next() функциясини чақириш керак, акс ҳолда сўров кейинги босқичга ўтмай осилиб қолади. Бу механизм Express'ни жуда кучли қилади, чунки сиз мураккаб мантиқни кичик ва қайта ишлатиладиган бўлакларга ажратишингиз мумкин.
Хатоларни бошқариш ва валидация
Ишончли API яратишда энг кўп эътибордан четда қоладиган, бироқ энг муҳим жиҳатлардан бири бу хатоларни тўғри бошқаришдир. Фойдаланувчи нотўғри маълумот юбориши, мавжуд бўлмаган ресурсни сўраши ёки серверда кутилмаган муаммо юзага келиши мумкин. Бундай ҳолатларда API тушунарли хато хабари ва тўғри ҳолат кодини қайтариши шарт. Express'да махсус хато бошқарувчи middleware тўртта аргумент қабул қилади ва у барча route'лардан кейин жойлаштирилади.
app.post('/users', (req, res, next) => {
if (!req.body.name) {
return res.status(400).json({ error: 'Ism majburiy' });
}
next();
});
app.use((err, req, res, next) => {
console.error(err);
res.status(500).json({ error: 'Server xatosi' });
});
Валидация, яъни кирувчи маълумотларни текшириш, хавфсизлик нуқтаи назаридан ҳам ниҳоятда зарур. Амалиётда кўпчилик дастурчилар бу вазифани қўлда ёзиш ўрнига махсус кутубхоналардан, масалан Joi ёки express-validator'дан фойдаланадилар, бу эса кодни тоза ва ишончли сақлашга ёрдам беради.
Маълумотлар базаси ва аутентификация
Ҳақиқий лойиҳаларда маълумотлар массивда эмас, балки маълумотлар базасида сақланади. Node.js MongoDB билан Mongoose орқали ёки PostgreSQL билан Prisma каби воситалар орқали осон боғланади. Боғланиш одатда илова ишга тушиши билан бир марта ўрнатилади ва кейин route'лар ичида шу боғланиш орқали сўровлар бажарилади. Аутентификация эса кўпинча JWT, яъни JSON Web Token технологияси орқали амалга оширилади: фойдаланувчи тизимга кирганда унга махсус токен берилади ва кейинги сўровларда шу токен орқали унинг кимлиги тасдиқланади.
const jwt = require('jsonwebtoken');
function auth(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Token yoq' });
try {
req.user = jwt.verify(token, process.env.SECRET);
next();
} catch {
res.status(403).json({ error: 'Token notogri' });
}
}
Энг яхши амалиётлар
Профессионал даражадаги API яратиш учун бир нечта муҳим қоидаларга амал қилиш керак. Биринчидан, кодингизни мантиқий қатламларга ажратинг: route'лар, бизнес мантиғи ва маълумотлар билан ишлаш алоҳида файлларда туриши лойиҳани ўсиб боргани сайин бошқаришни осонлаштиради. Иккинчидан, махфий маълумотларни, масалан маълумотлар базаси паролларини ва токен калитларини ҳеч қачон кодга тўғридан-тўғри ёзманг, балки муҳит ўзгарувчиларида сақланг. Учинчидан, API версиялашни жорий этинг ва доимий равишда сўровлар тезлигини чеклаш каби хавфсизлик чораларини қўлланг. Ушбу амалиётларга риоя қилсангиз, сизнинг API'ингиз нафақат ишлайдиган, балки ҳақиқий юкламага дош берадиган ишончли тизимга айланади.