Izpētiet progresīvus starpprogrammatūras modeļus Express.js, lai veidotu robustas, mērogojamas un uzturamas tīmekļa lietotnes globālai auditorijai. Uzziniet par kļūdu apstrādi, autentifikāciju, ātruma ierobežošanu un daudz ko citu.
Express.js starpprogrammatūra: progresīvu modeļu apgūšana mērogojamām lietotnēm
Express.js, ātrs, neuzspiedošs un minimālistisks tīmekļa ietvars Node.js, ir stūrakmens tīmekļa lietotņu un API veidošanā. Tā pamatā ir jaudīgais starpprogrammatūras (middleware) koncepts. Šis bloga ieraksts iedziļinās progresīvos starpprogrammatūras modeļos, sniedzot jums zināšanas un praktiskus piemērus, lai radītu robustas, mērogojamas un uzturamas lietotnes, kas piemērotas globālai auditorijai. Mēs izpētīsim paņēmienus kļūdu apstrādei, autentifikācijai, autorizācijai, ātruma ierobežošanai un citiem svarīgiem mūsdienu tīmekļa lietotņu veidošanas aspektiem.
Izpratne par starpprogrammatūru: pamats
Express.js starpprogrammatūras funkcijas ir funkcijas, kurām ir piekļuve pieprasījuma objektam (req
), atbildes objektam (res
) un nākamajai starpprogrammatūras funkcijai lietotnes pieprasījuma-atbildes ciklā. Starpprogrammatūras funkcijas var veikt dažādus uzdevumus, tostarp:
- Jebkāda koda izpilde.
- Izmaiņu veikšana pieprasījuma un atbildes objektos.
- Pieprasījuma-atbildes cikla pārtraukšana.
- Nākamās starpprogrammatūras funkcijas izsaukšana stekā.
Starpprogrammatūra būtībā ir konveijers (pipeline). Katra starpprogrammatūras daļa veic savu specifisko funkciju un pēc tam, pēc izvēles, nodod vadību nākamajai starpprogrammatūrai ķēdē. Šī modulārā pieeja veicina koda atkārtotu izmantošanu, atbildības jomu sadalīšanu un tīrāku lietotnes arhitektūru.
Starpprogrammatūras anatomija
Tipiska starpprogrammatūras funkcija atbilst šai struktūrai:
function myMiddleware(req, res, next) {
// Veic darbības
// Piemērs: reģistrēt pieprasījuma informāciju
console.log(`Request: ${req.method} ${req.url}`);
// Izsauc nākamo starpprogrammatūru stekā
next();
}
Funkcija next()
ir ļoti svarīga. Tā signalizē Express.js, ka pašreizējā starpprogrammatūra ir pabeigusi savu darbu un vadība jānodod nākamajai starpprogrammatūras funkcijai. Ja next()
netiek izsaukta, pieprasījums tiks apturēts, un atbilde nekad netiks nosūtīta.
Starpprogrammatūras veidi
Express.js nodrošina vairākus starpprogrammatūras veidus, katrs no kuriem kalpo noteiktam mērķim:
- Lietotnes līmeņa starpprogrammatūra: Piemērota visiem maršrutiem vai konkrētiem maršrutiem.
- Maršrutētāja līmeņa starpprogrammatūra: Piemērota maršrutiem, kas definēti maršrutētāja instancē.
- Kļūdu apstrādes starpprogrammatūra: Īpaši izstrādāta kļūdu apstrādei. Tiek novietota *pēc* maršrutu definīcijām starpprogrammatūras stekā.
- Iebūvētā starpprogrammatūra: Iekļauta Express.js (piemēram,
express.static
statisku failu pasniegšanai). - Trešo pušu starpprogrammatūra: Instalēta no npm paketēm (piemēram, body-parser, cookie-parser).
Progresīvi starpprogrammatūras modeļi
Apskatīsim dažus progresīvus modeļus, kas var būtiski uzlabot jūsu Express.js lietotnes funkcionalitāti, drošību un uzturēšanu.
1. Kļūdu apstrādes starpprogrammatūra
Efektīva kļūdu apstrāde ir vissvarīgākā, veidojot uzticamas lietotnes. Express.js nodrošina īpašu kļūdu apstrādes starpprogrammatūras funkciju, kas tiek novietota *pēdējā* starpprogrammatūras stekā. Šī funkcija pieņem četrus argumentus: (err, req, res, next)
.
Šeit ir piemērs:
// Kļūdu apstrādes starpprogrammatūra
app.use((err, req, res, next) => {
console.error(err.stack); // Reģistrēt kļūdu atkļūdošanai
res.status(500).send('Something broke!'); // Atbildēt ar atbilstošu statusa kodu
});
Galvenie apsvērumi kļūdu apstrādē:
- Kļūdu reģistrēšana: Izmantojiet reģistrēšanas bibliotēku (piemēram, Winston, Bunyan), lai reģistrētu kļūdas atkļūdošanai un uzraudzībai. Apsveriet iespēju reģistrēt dažādus svarīguma līmeņus (piemēram,
error
,warn
,info
,debug
). - Statusa kodi: Atgrieziet atbilstošus HTTP statusa kodus (piemēram, 400 - Slikts pieprasījums, 401 - Neautorizēts, 500 - Iekšēja servera kļūda), lai paziņotu klientam par kļūdas raksturu.
- Kļūdu ziņojumi: Sniedziet klientam informatīvus, bet drošus kļūdu ziņojumus. Izvairieties no sensitīvas informācijas atklāšanas atbildē. Apsveriet iespēju izmantot unikālu kļūdas kodu, lai izsekotu problēmas iekšēji, vienlaikus atgriežot lietotājam vispārīgu ziņojumu.
- Centralizēta kļūdu apstrāde: Grupējiet kļūdu apstrādi īpašā starpprogrammatūras funkcijā, lai nodrošinātu labāku organizāciju un uzturēšanu. Izveidojiet pielāgotas kļūdu klases dažādiem kļūdu scenārijiem.
2. Autentifikācijas un autorizācijas starpprogrammatūra
Jūsu API drošība un sensitīvu datu aizsardzība ir ļoti svarīga. Autentifikācija pārbauda lietotāja identitāti, savukārt autorizācija nosaka, ko lietotājs drīkst darīt.
Autentifikācijas stratēģijas:
- JSON Web Tokens (JWT): Populāra bezvalstiska (stateless) autentifikācijas metode, kas piemērota API. Pēc veiksmīgas pieteikšanās serveris izsniedz klientam JWT. Klients pēc tam iekļauj šo marķieri turpmākajos pieprasījumos. Bieži tiek izmantotas bibliotēkas kā
jsonwebtoken
. - Sesijas: Uzturēt lietotāju sesijas, izmantojot sīkfailus (cookies). Tas ir piemērots tīmekļa lietotnēm, bet var būt mazāk mērogojams nekā JWT. Bibliotēkas kā
express-session
atvieglo sesiju pārvaldību. - OAuth 2.0: Plaši izplatīts standarts deleģētai autorizācijai, kas ļauj lietotājiem piešķirt piekļuvi saviem resursiem, tieši neizpaužot savus akreditācijas datus (piemēram, piesakoties ar Google, Facebook u.c.). Realizējiet OAuth plūsmu, izmantojot bibliotēkas kā
passport.js
ar specifiskām OAuth stratēģijām.
Autorizācijas stratēģijas:
- Lomu balstīta piekļuves kontrole (RBAC): Piešķiriet lietotājiem lomas (piem., administrators, redaktors, lietotājs) un piešķiriet atļaujas, pamatojoties uz šīm lomām.
- Atribūtu balstīta piekļuves kontrole (ABAC): Elastīgāka pieeja, kas izmanto lietotāja, resursa un vides atribūtus, lai noteiktu piekļuvi.
Piemērs (JWT autentifikācija):
const jwt = require('jsonwebtoken');
const secretKey = 'JŪSU_SLEPENA_ATSLEGA'; // Aizvietojiet ar spēcīgu, vides mainīgajā balstītu atslēgu
// Starpprogrammatūra JWT marķieru pārbaudei
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (token == null) return res.sendStatus(401); // Neautorizēts
jwt.verify(token, secretKey, (err, user) => {
if (err) return res.sendStatus(403); // Aizliegts
req.user = user; // Pievienot lietotāja datus pieprasījumam
next();
});
}
// Piemēra maršruts, ko aizsargā autentifikācija
app.get('/profile', authenticateToken, (req, res) => {
res.json({ message: `Sveicināti, ${req.user.username}` });
});
Svarīgi drošības apsvērumi:
- Droša akreditācijas datu glabāšana: Nekad neglabājiet paroles vienkārša teksta veidā. Izmantojiet spēcīgus paroļu jaucējfunkciju algoritmus, piemēram, bcrypt vai Argon2.
- HTTPS: Vienmēr izmantojiet HTTPS, lai šifrētu saziņu starp klientu un serveri.
- Ievades validācija: Validējiet visu lietotāja ievadi, lai novērstu drošības ievainojamības, piemēram, SQL injekciju un starpvietņu skriptošanu (XSS).
- Regulāri drošības auditi: Veiciet regulārus drošības auditus, lai identificētu un novērstu potenciālās ievainojamības.
- Vides mainīgie: Glabājiet sensitīvu informāciju (API atslēgas, datu bāzes akreditācijas datus, slepenās atslēgas) kā vides mainīgos, nevis iekodējot tos savā kodā. Tas atvieglo konfigurācijas pārvaldību un veicina labākās prakses drošību.
3. Ātruma ierobežošanas starpprogrammatūra
Ātruma ierobežošana aizsargā jūsu API no ļaunprātīgas izmantošanas, piemēram, pakalpojuma atteikuma (DoS) uzbrukumiem un pārmērīga resursu patēriņa. Tā ierobežo pieprasījumu skaitu, ko klients var veikt noteiktā laika periodā.
Ātruma ierobežošanai parasti izmanto tādas bibliotēkas kā express-rate-limit
. Apsveriet arī pakotni helmet
, kas ietver pamata ātruma ierobežošanas funkcionalitāti papildus virknei citu drošības uzlabojumu.
Piemērs (izmantojot express-rate-limit):
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minūtes
max: 100, // Ierobežot katru IP līdz 100 pieprasījumiem uz windowMs
message: 'Pārāk daudz pieprasījumu no šī IP, lūdzu, mēģiniet vēlreiz pēc 15 minūtēm',
});
// Piemērot ātruma ierobežotāju konkrētiem maršrutiem
app.use('/api/', limiter);
// Alternatīvi, piemērot visiem maršrutiem (parasti mazāk vēlams, ja vien visa datplūsma nav jāapstrādā vienādi)
// app.use(limiter);
Pielāgošanas iespējas ātruma ierobežošanai ietver:
- IP adreses balstīta ātruma ierobežošana: Visizplatītākā pieeja.
- Lietotāja balstīta ātruma ierobežošana: Nepieciešama lietotāja autentifikācija.
- Pieprasījuma metodes balstīta ātruma ierobežošana: Ierobežot konkrētas HTTP metodes (piem., POST pieprasījumus).
- Pielāgota glabātuve: Glabājiet ātruma ierobežošanas informāciju datu bāzē (piemēram, Redis, MongoDB), lai nodrošinātu labāku mērogojamību vairākās servera instancēs.
4. Pieprasījuma ķermeņa parsēšanas starpprogrammatūra
Express.js pēc noklusējuma nepārveido pieprasījuma ķermeni (request body). Jums būs jāizmanto starpprogrammatūra, lai apstrādātu dažādus ķermeņa formātus, piemēram, JSON un URL kodētus datus. Lai gan vecākās implementācijās varētu būt izmantotas pakotnes kā `body-parser`, pašreizējā labākā prakse ir izmantot Express iebūvēto starpprogrammatūru, kas pieejama kopš Express v4.16.
Piemērs (izmantojot iebūvēto starpprogrammatūru):
app.use(express.json()); // Pārveido JSON kodētus pieprasījuma ķermeņus
app.use(express.urlencoded({ extended: true })); // Pārveido URL kodētus pieprasījuma ķermeņus
Starpprogrammatūra `express.json()` pārveido ienākošos pieprasījumus ar JSON kravām un padara pārveidotos datus pieejamus `req.body`. Starpprogrammatūra `express.urlencoded()` pārveido ienākošos pieprasījumus ar URL kodētām kravām. Opcija `{ extended: true }` ļauj pārveidot bagātīgus objektus un masīvus.
5. Reģistrēšanas starpprogrammatūra
Efektīva reģistrēšana (logging) ir būtiska jūsu lietotnes atkļūdošanai, uzraudzībai un auditēšanai. Starpprogrammatūra var pārtvert pieprasījumus un atbildes, lai reģistrētu attiecīgo informāciju.
Piemērs (Vienkārša reģistrēšanas starpprogrammatūra):
const morgan = require('morgan'); // Populārs HTTP pieprasījumu reģistrētājs
app.use(morgan('dev')); // Reģistrēt pieprasījumus 'dev' formātā
// Cits piemērs, pielāgota formatēšana
app.use((req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
next();
});
Ražošanas vidēm apsveriet iespēju izmantot robustāku reģistrēšanas bibliotēku (piem., Winston, Bunyan) ar sekojošām iespējām:
- Reģistrēšanas līmeņi: Izmantojiet dažādus reģistrēšanas līmeņus (piem.,
debug
,info
,warn
,error
), lai kategorizētu žurnāla ziņojumus pēc to svarīguma. - Žurnālu rotācija: Ieviesiet žurnālu rotāciju, lai pārvaldītu žurnāla failu lielumu un novērstu problēmas ar diska vietu.
- Centralizēta reģistrēšana: Sūtiet žurnālus uz centralizētu reģistrēšanas pakalpojumu (piem., ELK steks (Elasticsearch, Logstash, Kibana), Splunk), lai atvieglotu uzraudzību un analīzi.
6. Pieprasījuma validācijas starpprogrammatūra
Validējiet ienākošos pieprasījumus, lai nodrošinātu datu integritāti un novērstu neparedzētu uzvedību. Tas var ietvert pieprasījuma galveņu, vaicājuma parametru un pieprasījuma ķermeņa datu validāciju.
Bibliotēkas pieprasījumu validācijai:
- Joi: Jaudīga un elastīga validācijas bibliotēka shēmu definēšanai un datu validācijai.
- Ajv: Ātrs JSON shēmas validators.
- Express-validator: Express starpprogrammatūras komplekts, kas ietin validator.js vieglai lietošanai ar Express.
Piemērs (izmantojot Joi):
const Joi = require('joi');
const userSchema = Joi.object({
username: Joi.string().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().min(6).required(),
});
function validateUser(req, res, next) {
const { error } = userSchema.validate(req.body, { abortEarly: false }); // Iestatiet abortEarly uz false, lai iegūtu visas kļūdas
if (error) {
return res.status(400).json({ errors: error.details.map(err => err.message) }); // Atgriezt detalizētus kļūdu ziņojumus
}
next();
}
app.post('/users', validateUser, (req, res) => {
// Lietotāja dati ir derīgi, turpināt ar lietotāja izveidi
res.status(201).json({ message: 'Lietotājs veiksmīgi izveidots' });
});
Labākās prakses pieprasījumu validācijai:
- Shēmas balstīta validācija: Definējiet shēmas, lai norādītu gaidāmo datu struktūru un datu tipus.
- Kļūdu apstrāde: Atgrieziet klientam informatīvus kļūdu ziņojumus, ja validācija neizdodas.
- Ievades sanitizācija: Sanitizējiet lietotāja ievadi, lai novērstu ievainojamības, piemēram, starpvietņu skriptošanu (XSS). Kamēr ievades validācija koncentrējas uz to, *kas* ir pieņemams, sanitizācija koncentrējas uz to, *kā* ievade tiek attēlota, lai noņemtu kaitīgos elementus.
- Centralizēta validācija: Izveidojiet atkārtoti lietojamas validācijas starpprogrammatūras funkcijas, lai izvairītos no koda dublēšanās.
7. Atbildes saspiešanas starpprogrammatūra
Uzlabojiet savas lietotnes veiktspēju, saspiežot atbildes pirms to nosūtīšanas klientam. Tas samazina pārsūtīto datu apjomu, nodrošinot ātrāku ielādes laiku.
Piemērs (izmantojot saspiešanas starpprogrammatūru):
const compression = require('compression');
app.use(compression()); // Iespējot atbildes saspiešanu (piem., gzip)
compression
starpprogrammatūra automātiski saspiež atbildes, izmantojot gzip vai deflate, pamatojoties uz klienta Accept-Encoding
galveni. Tas ir īpaši noderīgi, pasniedzot statiskus resursus un lielas JSON atbildes.
8. CORS (Cross-Origin Resource Sharing) starpprogrammatūra
Ja jūsu API vai tīmekļa lietotnei ir jāpieņem pieprasījumi no dažādiem domēniem (izcelsmēm), jums būs jākonfigurē CORS. Tas ietver atbilstošu HTTP galveņu iestatīšanu, lai atļautu starpizcelsmju pieprasījumus.
Piemērs (izmantojot CORS starpprogrammatūru):
const cors = require('cors');
const corsOptions = {
origin: 'https://jusu-atlautais-domens.com',
methods: 'GET,POST,PUT,DELETE',
allowedHeaders: 'Content-Type,Authorization'
};
app.use(cors(corsOptions));
// VAI lai atļautu visas izcelsmes (izstrādei vai iekšējām API -- lietot ar piesardzību!)
// app.use(cors());
Svarīgi apsvērumi par CORS:
- Izcelsme (Origin): Norādiet atļautās izcelsmes (domēnus), lai novērstu neautorizētu piekļuvi. Parasti ir drošāk iekļaut konkrētas izcelsmes baltajā sarakstā, nevis atļaut visas izcelsmes (
*
). - Metodes: Definējiet atļautās HTTP metodes (piem., GET, POST, PUT, DELETE).
- Galvenes: Norādiet atļautās pieprasījuma galvenes.
- Sagatavošanās pieprasījumi (Preflight Requests): Sarežģītiem pieprasījumiem (piem., ar pielāgotām galvenēm vai metodēm, kas nav GET, POST, HEAD), pārlūkprogramma nosūtīs sagatavošanās pieprasījumu (OPTIONS), lai pārbaudītu, vai faktiskais pieprasījums ir atļauts. Serverim ir jāatbild ar atbilstošām CORS galvenēm, lai sagatavošanās pieprasījums būtu veiksmīgs.
9. Statisko failu pasniegšana
Express.js nodrošina iebūvētu starpprogrammatūru statisko failu (piem., HTML, CSS, JavaScript, attēlu) pasniegšanai. To parasti izmanto jūsu lietotnes priekšgala (front-end) pasniegšanai.
Piemērs (izmantojot express.static):
app.use(express.static('public')); // Pasniegt failus no 'public' direktorijas
Novietojiet savus statiskos resursus public
direktorijā (vai jebkurā citā jūsu norādītā direktorijā). Express.js pēc tam automātiski pasniegs šos failus, pamatojoties uz to failu ceļiem.
10. Pielāgota starpprogrammatūra specifiskiem uzdevumiem
Papildus apspriestajiem modeļiem, jūs varat izveidot pielāgotu starpprogrammatūru, kas pielāgota jūsu lietotnes specifiskajām vajadzībām. Tas ļauj jums iekapsulēt sarežģītu loģiku un veicināt koda atkārtotu izmantošanu.
Piemērs (Pielāgota starpprogrammatūra funkcionalitātes karogiem (Feature Flags)):
// Pielāgota starpprogrammatūra, lai iespējotu/atspējotu funkcijas, pamatojoties uz konfigurācijas failu
const featureFlags = require('./config/feature-flags.json');
function featureFlagMiddleware(featureName) {
return (req, res, next) => {
if (featureFlags[featureName] === true) {
next(); // Funkcija ir iespējota, turpināt
} else {
res.status(404).send('Funkcija nav pieejama'); // Funkcija ir atspējota
}
};
}
// Lietošanas piemērs
app.get('/new-feature', featureFlagMiddleware('newFeatureEnabled'), (req, res) => {
res.send('Šī ir jaunā funkcija!');
});
Šis piemērs demonstrē, kā izmantot pielāgotu starpprogrammatūru, lai kontrolētu piekļuvi konkrētiem maršrutiem, pamatojoties uz funkcionalitātes karogiem. Tas ļauj izstrādātājiem kontrolēt funkcionalitātes izlaišanu, nepārvietojot vai nemainot kodu, kas nav pilnībā pārbaudīts, kas ir izplatīta prakse programmatūras izstrādē.
Labākās prakses un apsvērumi globālām lietotnēm
- Veiktspēja: Optimizējiet savu starpprogrammatūru veiktspējai, īpaši lietotnēs ar lielu datplūsmu. Minimizējiet CPU ietilpīgu operāciju izmantošanu. Apsveriet kešatmiņas stratēģiju izmantošanu.
- Mērogojamība: Izstrādājiet savu starpprogrammatūru tā, lai tā būtu horizontāli mērogojama. Izvairieties no sesijas datu glabāšanas atmiņā; izmantojiet izkliedētu kešatmiņu, piemēram, Redis vai Memcached.
- Drošība: Ieviesiet drošības labākās prakses, tostarp ievades validāciju, autentifikāciju, autorizāciju un aizsardzību pret izplatītām tīmekļa ievainojamībām. Tas ir kritiski svarīgi, īpaši ņemot vērā jūsu auditorijas starptautisko raksturu.
- Uzturamība: Rakstiet tīru, labi dokumentētu un modulāru kodu. Izmantojiet skaidras nosaukumu konvencijas un ievērojiet konsekventu kodēšanas stilu. Modularizējiet savu starpprogrammatūru, lai atvieglotu uzturēšanu un atjauninājumus.
- Testējamība: Rakstiet vienības testus un integrācijas testus savai starpprogrammatūrai, lai nodrošinātu tās pareizu darbību un savlaicīgi atklātu potenciālās kļūdas. Pārbaudiet savu starpprogrammatūru dažādās vidēs.
- Internacionalizācija (i18n) un Lokalizācija (l10n): Apsveriet internacionalizāciju un lokalizāciju, ja jūsu lietotne atbalsta vairākas valodas vai reģionus. Nodrošiniet lokalizētus kļūdu ziņojumus, saturu un formatējumu, lai uzlabotu lietotāja pieredzi. Ietvari, piemēram, i18next, var atvieglot i18n centienus.
- Laika joslas un datuma/laika apstrāde: Esiet uzmanīgi ar laika joslām un rūpīgi apstrādājiet datuma/laika datus, īpaši strādājot ar globālu auditoriju. Izmantojiet bibliotēkas, piemēram, Moment.js vai Luxon, datuma/laika manipulācijām vai, vēlams, jaunāko Javascript iebūvēto Date objekta apstrādi ar laika joslu atpazīšanu. Glabājiet datumus/laikus UTC formātā savā datu bāzē un konvertējiet tos uz lietotāja vietējo laika joslu, tos attēlojot.
- Valūtas apstrāde: Ja jūsu lietotne nodarbojas ar finanšu darījumiem, pareizi apstrādājiet valūtas. Izmantojiet atbilstošu valūtas formatējumu un apsveriet iespēju atbalstīt vairākas valūtas. Nodrošiniet, ka jūsu dati tiek konsekventi un precīzi uzturēti.
- Juridiskā un normatīvā atbilstība: Esiet informēti par juridiskajām un normatīvajām prasībām dažādās valstīs vai reģionos (piem., GDPR, CCPA). Ieviesiet nepieciešamos pasākumus, lai nodrošinātu atbilstību šiem noteikumiem.
- Pieejamība: Nodrošiniet, ka jūsu lietotne ir pieejama lietotājiem ar invaliditāti. Ievērojiet pieejamības vadlīnijas, piemēram, WCAG (Web Content Accessibility Guidelines).
- Uzraudzība un brīdināšana: Ieviesiet visaptverošu uzraudzību un brīdināšanu, lai ātri atklātu problēmas un reaģētu uz tām. Uzraugiet servera veiktspēju, lietotnes kļūdas un drošības draudus.
Noslēgums
Progresīvu starpprogrammatūras modeļu apgūšana ir ļoti svarīga, lai veidotu robustas, drošas un mērogojamas Express.js lietotnes. Efektīvi izmantojot šos modeļus, jūs varat izveidot lietotnes, kas ir ne tikai funkcionālas, bet arī uzturamas un labi piemērotas globālai auditorijai. Atcerieties visā izstrādes procesā par prioritāti izvirzīt drošību, veiktspēju un uzturamību. Ar rūpīgu plānošanu un īstenošanu jūs varat izmantot Express.js starpprogrammatūras jaudu, lai veidotu veiksmīgas tīmekļa lietotnes, kas atbilst lietotāju vajadzībām visā pasaulē.
Papildu lasāmviela: