JavaScript na serveri rýchlo a jednoducho so slovenským Total.js frameworkom
Nebudem písať dlhé omáčky, ale prejdem rovno k veci. Pokiaľ patríte k lenivým programátorom ako som ja, tak určite oceníte náš domáci Total.js framework, ktorý Vám ponúka množstvo zaujímavých funkcií na tvorbu webových stránok, webových služieb, webových a intranetových appiek.
Začíname
Garantujem Vám, že Vašu prvú webovú aplikáciu v Node.js a Total.js budete mať napísanú do 5 minút. Programujem už veľmi veľa rokov a s určitosťou môžem povedať, že inštalácia celého tohto prostredia je najjednoduchšia a najrýchlejšia zo všetkého čo poznám.
- stiahnite a nainštalujte si Node.js platformu https://nodejs.org/en/download/prebuilt-installer
- vytvorte si niekde u seba adresár na Node.js appky napr.
/totalapps/
- potom si vytvorte ďalší pod-adresár
/totalapps/node_modules/
(sem sa nainštaluje Total.js framework) - potom si vytvorte ďalší pod-adresár
/totalapps/hello-world/
a do neho vytvorte nižšie uvedené súbory:
package.json
:
index.js
:
Keď to máte, tak si vytvorte adresár /hello-world/controllers/
a do neho vytvorte súbor api.js
:
A keď už toto máte, tak si otvorte terminál/príkazový riadok v adresáry /hello-world/
a napíšte:
Ak všetko zbehlo, tak si otvorte webový prehliadač a zadajte URL adresu: http://127.0.0.1:8000
. Na tejto adrese by sa Vám mal zobraziť výstup z Total.js aplikácie.
Total.js má v sebe veľmi veľkú funkčnosť a dokonca aj automaticky reaguje na zmeny v zdrojom kóde. Pokiaľ urobíte zmenu v controllers
, tak sa framework automaticky reštartne. Takže kľudne si môžete otvoriť projekt a priamo vykonávať zmeny bez dodatočných príkazov v terminály alebo v príkazovom riadku.
Dôležité: Total.js má v sebe zabudovaný webový server, takže v prípade, že chcete prevádzkovať viacej Total.js aplikácií súbežne, tak každá aplikácia musí bežať na inom porte. Toto sa na serveri rieši tzv. reverznou proxy (o tom inokedy).
Pokročilejšie funkcie
Ak ste sa dočítali až sem, tak sa ešte trochu pohráme so základnou funkčnosťou frameworku.
Rozšírime súbor /controllers/api.js
o novú funkčnosť, takže nižšie uvedené časti zdrojového kódu skopírujte do spomínaného súboru.
Dynamické parametre a SPA routing:
// Parametrická routa 1
ROUTE('GET /products/{category}/', function($) {
$.text('Category: ' + $.params.category);
});
// Parametrická routa 2
ROUTE('GET /products/{category}/{id}/', function($) {
$.text('Category: {0}, id: {1}'.format($.params.category, $.params.id));
});
// Wildcard (SPA) routing
// Táto akcia spracuje všetky requesty od endpointu /admin/
ROUTE('GET /admin/*', function($) {
$.text($.url);
});
In-memory proxy na iný server:
ROUTE('GET /rss/', function($) {
$.proxy('https://blog.totaljs.com/rss/');
});
Po uložení navštívte stránku http://127.0.0.1:8000/rss/
a mali by ste vidieť obsah RSS feedu z Total.js blogu.
Spracovanie dát:
// Total.js spracuje JSON alebo urlencoded payload automaticky
// Maximálny limit (by default) je 5 kB na celý payload
ROUTE('POST /form/', function($) {
// Payload je uložený v:
// $.body {Object}
// Klientovi vrátime v JSONe to, čo nám poslal
$.json($.body);
});
// Ako viem rozšíriť maximálny limit napríklad na 1 MB?
// ROUTE('POST /form/ <1MB ', function($) { ... });
Parsovanie HTML obsahu cez Total.js HTML parser (SHMU.sk):
// Vyparsujeme aktuálne počasie zo SHMU stránky
ROUTE('GET /pocasie/', async function($) {
let html = await RESTBuilder.GET('https://www.shmu.sk').raw().promise($);
let htmlparser = html.parseHTML();
// Vyhľadáme všetky elementy s classou ".map-point"
let points = htmlparser.find('.map-point');
let response = [];
// V nájdených bodoch vyhľadáme špecifické hodnoty
for (let point of points) {
let city = {};
city.name = point.find('.map-city')[0].text();
city.temperature = point.find('.map-temp-w')[0].text();
response.push(city);
}
$.json(response);
});
Spracovanie používateľských súborov (file upload):
ROUTE('POST /upload/ @upload <5MB', function($) {
for (let file of $.files)
console.log(file);
$.success();
});
Pozdržanie odpovede na 2 sekundy:
// Pozor: Total.js má v sebe mechanizmus na auto-odpoveď v prípade, že akcia neodpovie klientovi (by default: 5 sekúnd)
ROUTE('GET /delay/', function($) {
setTimeout(() => $.success(), 2000);
});
// Predvolený timeout sa dá rozšíriť napr. na 20 sekúnd nižšie uvedeným zápisom
// ROUTE('GET /delay/ <20s', function($) { ... });
Spustenie ďalšej treťostranovej applikácie a vrátenie odpovede na request:
// v MacOS musíte mať spustenú appku pod "sudo"
ROUTE('GET /ping/', async function($) {
try {
let response = await SHELL('ping -c 3 www.totaljs.com');
$.text(response);
} catch (e) {
$.invalid(e);
}
});
Načítanie a upravenie odpovede z externej služby:
ROUTE('GET /json/', async function($) {
// Načítanie externého JSONu
let response = await RESTBuilder.GET('https://www.totaljs.com/dashboard.json').promise($);
// Upravíme odpoveď:
response.extended = true;
// Vrátime klientovi
$.json(response);
});
Real-time streamovanie CSV/XML dát:
ROUTE('GET /csv/ <20s', function($) {
// Urobíme request na CSV súbor, ktorý budeme streamovať po častiach.
// Nižšie uvedený kód bude fungovať aj s gigovými datami.
RESTBuilder.GET('https://raw.githubusercontent.com/datasets/world-cities/refs/heads/main/data/world-cities.csv').stream(function(err, response) {
// Error handling v prípade, že služba z nejakého dôvodu padne.
if (err) {
$.invalid(err);
// $.invalid('Služba je dočasne nedostupná');
return;
}
let countries = {};
// Pomocou metódy Utils.streamer() sa dá efektívne streamovať CSV, XML alebo podobné typy obsahu.
// Streamer potrebuje vedieť, čo je oddeľovač dát (funkcia hľadá v bufferi (bytes) oddeľovač).
response.stream.on('data', Utils.streamer('\n', function(line, index) {
// Vyparsujeme CSV riadok
var csv = line.parseCSV()[0];
if (countries[csv.b])
countries[csv.b]++;
else
countries[csv.b] = 1;
}, 1)); // 1 znamená, že preskoč "1" riadok
// Keď sa skončí stream, vrátime odpoveď
response.stream.on('end', () => $.json(countries));
});
// Ako by sa parsovalo XML?
// response.stream.on('data', Utils.streamer('<CD>', '</CD>', function(line, index) { ... }));
});
Spracúvame statické súbory
// Táto routa spracuje všetky .jpg obrázky na ceste /photos/*.jpg.
// Na každý jeden obrázok odpovie rovnakým obrázkom zo servera pixabay.com.
ROUTE('FILE /photos/*.jpg', function($) {
// http://127.0.0.1:8000/photos/peter.jpg
// filename = peter.jpg
let filename = $.split[1];
RESTBuilder.GET('https://cdn.pixabay.com/photo/2024/09/27/22/44/owl-9079962_640.jpg').stream(function(err, response) {
if (err) {
$.invalid(err);
} else {
// Prestreamujeme data z ďalšieho servera
$.stream(response.headers['content-type'], response.stream);
}
});
});
Záver
Týmto blogom som chcel iba ukázať základnú funkčnosť Total.js frameworku. V ďalších blogoch sa posunieme ďalej a ukážem Vám ďalšie zaujímavé funkcie v Total.js Platforme.
- Webová stránka: https://www.totaljs.com
- Open-source (hotové) Total.js aplikácie: https://www.totaljs.com/apps/
- Dokumentácia: https://docs.totaljs.com
- Ďalšie blogy o Total.js Platforme (EN): https://blog.totaljs.com