nav_dugme codeBlog codeBlog
  • početna Početna stranica
  • Sačuvani članci Sačuvani članci
  • Članci
     (spisak)
  • Kontakt
Povratak na vrh stranice

Info & povezani članci Info o članku - dugme

Info

trejler_sat Datum objave: 20.06.2021.

trejler_dokument Jezici: JavaScript

trejler_teg_narandzasti Težina: 7/10

HTML
JavaScript
nodejs
es6
MySql
web dizajn
http
http statusni kodovi
internet
web server
arrow funkcije
lambda funkcije
teorija

Tema: JavaScript

Uvod u JavaScript i DOM (Document Object Model)Operacije sa nizovima u programskom jeziku JavaScriptJavaScript ES6 sintaksaAsinhrono programiranje u JavaScriptu

Povezani članci

Callback funkcije i lambda izraziŠablonske niske u programskim jezicimaUvod u PHP i back-end programiranjeUvod u PythonUvod u AJAX (Asynchronous JavaScript And XML)Uvod u Fetch APIHTTP statusni kodoviJSON - tekstualni format za razmenu podatakaIzbor prvog programskog jezikaGNU/Linux - 1. deo - Uvod
Svi članci
First, solve the problem. Then, write the code.
John Johnson

Uvod u Node.js

Facebook LinkedIn Twitter Viber WhatsApp E-mail
zoom_plus zoom_minus bookmark
početna > Članci > Teorija

Uvod

Da bismo mogli čitaocima predočiti pravi smisao radnog okruženja kao što je Node.Js, bilo bi potrebno da se u mislima vratimo petnaestak godina unazad, u vreme kada je JavaScript još uvek bio samo front-end jezik a Node.js nije ni postojao.

Ako bismo pod navedenim uslovima proveli neko vreme pišući JS skripte, primetili bismo da je JavaScript prilično elegantan i funkcionalan jezik (pod uslovom da smo u stanju da pravilno odmerimo kako sa njim treba postupati i da se zadržimo u okvirima pravila dobrog programiranja), i spontano bi nam palo na pamet kako bi bilo zanimljivo kada bi 'lepa i pregledna' JS sintaksa mogla da se koristi za pisanje desktop programa i/ili kao jezik za razvoj mrežnih servera.

Mnogi programeri razmišljali su na navedeni način, a neki su radili i na iznalaženju rešenja ....

Pre nešto više od deset godina (2009), mladi američki programer Rajan Dal (Ryan Dahl), kreirao je Node.js - radno okruženje koje koristi program V8 (JavaScript interpretator otvorenog koda iz Google Chrome-a), i povezuje ga sa ulazno-izlaznim mogućnostima operativnog sistema na kome je instaliran, čime opisani sistem poprima odlike navedene u drugom pasusu, tj. (pomalo slikovito), postaje: sistem za pisanje desktop programa preko JavaScript sintakse i takođe (što je programerima posebno "golicalo maštu" dok takva mogućnost nije postojala), okruženje za kreiranje back-end komponenti web aplikacija - preko istog jezika koji se koristi za front-end.

U godinama koje su došle, početna ideja je 'zaživela' i radno okruženje Node.js je (zaista) postalo izuzetno popularno, najviše kao serverska tehnologija, ali takođe i kao osnova svojevrsnog "ekosistema" za kreiranje najraznovrsnijih web aplikacija, desktop programa, biblioteka, modula i drugih softverskih dodataka ....

Pre nego što počnemo (za prave)

Kao što smo već pisali, postoje tehnike koje je praktično neophodno poznavati, pre nego što se neko upusti u upoznavanje sa okruženjem Node.js.

Pored samih osnova JavaScript-a i funkcija za obavljanje operacija sa nizovima, potrebno je pre svega biti upoznat sa šablonskim niskama, sa funkcijama povratnog poziva i lambda notacijom, kao i sa ostalim tehnikama o kojima smo već pisali u članku o ES6 sintaksi (koji je linkovan na početku odeljka).

Striktno govoreći, poznavanje PHP-a nije neophodan preduslov za upoznavanje sa Node.js-om, ali, smatraćemo (u nastavku) da ste bar okvirno upoznati i sa PHP-om (pri čemu je više nego poželjno da ste sa PHP-om upoznati i 'više nego okvirno' :)), i takođe ćemo smatrati da ste upoznati sa osnovnom internet terminologijom i HTTP statusima.

Ukoliko su uslovi koje smo prethodno naveli ispunjeni (bar dobrim delom :)), nastavljamo dalje ....

Što se tiče samog Node.js-a, članak pred vama, kao i drugi članci koje spremamo (koji će za temu imati Node.js i srodne tehnologije), odnosiće se prevashodno (ali ne isključivo) na primenu Node.js-a kao back-end tehnologije, i stoga je, u navedenim okolnostima, sasvim primereno (i uobičajeno) napraviti na početku osvrt na razlike između Node.Js-a i PHP-a (u ovom trenutku, dve najpopularnije tehnologije za razvoj web aplikacija manjeg i srednjeg obima).

Napomenimo i to da ćemo se u članku takođe osvrnuti na pristup MySql bazama preko Node.js-a, bez obzira na to što u glavnom primeru (pokretanje web servera), ovoga puta nećemo koristiti baze podataka (međutim, povezivaćemo se sa bazama podataka u budućim člancima koji su vezani za Node.js, i (naravno), čitaocima može značiti da sami uskoro isprobaju povezivanje u sopstvenim primerima i projektima).

Razlike između Node.js-a i PHP-a

Šta je to što Node.js čini veoma zanimljivim radnim okruženjem koje je u pojedinim situacijama bolji izbor od PHP-a i zašto je Node stekao veliku popularnost?

Za razliku od PHP-a, u kome se naredbe izvršavaju sinhrono (što praktično znači da je pokretanje sledeće naredbe "blokirano" sve dok se prethodna naredba u potpunosti ne izvrši), u Node.js-u se naredbe izvršavaju asinhrono, što znači da određene naredbe mogu biti pokrenute pre završetka izvršavanja prethodne naredbe.

U praksi, sve što smo naveli ne znači da se preko Node.js-a 'tek tako' mogu pisati aplikacije u kojima je više procesa pokrenuto istovremeno (Node.js nije 'multi-threaded' okruženje), i ne znači da je "Node.js brži od PHP-a" (pogotovo ne "obavezno i uvek"), ali, pod određenim okolnostima - može biti brži.

Da pojasnimo, preko poznatog primera: u Node.js-u, pozivi funkcija za pristup bazama podataka tipično * ne blokiraju dolazeće naredbe (budući da se obrada podataka u bazama obavlja na udaljenom računaru), ali - pokretanje bilo kakve procesorski zahtevne procedure (recimo, while petlje koja računa decimale broja PI preko iterativne formule i sl) - i te kako može "ukočiti" aplikaciju.

Jednostavno rečeno, u situacijama kada je potrebno brzo obraditi veliki broj zahteva koji nisu previše zahtevni (po pitanju vremena koje je potrebno za pojedinačnu obradu), Node.js može biti vrlo zanimljivo rešenje (koje najčešće pokazuje bolje performanse od PHP-a).

Vrlo često (kao u prethodno pomenutim okolnostima), ali, svakako ne i uvek (pri čemu se u obzir moraju uzeti i druge pojedinosti), i stoga ćemo daljoj diskusiji na temu razlika između back-end tehnologija uskoro posvetiti zaseban članak (da ne bismo nepotrebno širili diskusiju na samom početku).

Takođe, ukoliko vas zanima tematika asinhronog izvršavanja koda u JavaScript-u, u članku koji smo posvetili navedenoj temi, možete pronaći više informacija.

* Hoćemo reći - postoje i "sinhrone" verzije funkcija (koje blokiraju izvršavanje koda), ali, tipično se koriste asinhrone verzije funkcija.

Pored prethodno navedenih objektivnih okolnosti, prilično smo sigurni da mnogi web developeri poslednjih godina daju prednost Node.js-u isključivo iz subjektivnih i/ili estetskih razloga, jer, za većinu programera, JS je jednostavno "lepši" i prijemčiviji od PHP-a (to već ostavljamo svakome da samostalno proceni i izabere :)), a u obzir treba uzeti i praktičnu stranu pristupa u kome se jedan jezik koristi: i za frontend, i za backend (u slučaju Node.js-a).

Instalacija okruženja i pokretanje Node aplikacija

U uvodnom članku, želimo pre svega da pokažemo kako se može pokrenuti jednostavan web server preko Node.js-a (pretpostavljamo da je to tematika koja je čitaocima najzanimljivija :)), ali, prvo ćemo se ipak upoznati sa osnovnim operacijama sa direktorijumima i datotekama, a takođe ćemo se upoznati i sa opcijama za pristup bazama podataka, međutim - pre svega navedenog - potrebno je (naravno) da se upoznamo sa još osnovnijim tehnikalijama ....

Instalacija radnog okruženja

Sa adrese nodejs.org možete preuzeti instalacionu verziju okruženja Node.js koje odgovara operativnom sistemu koji koristite (i potom možete instalirati okruženje Node.js, to jest, Node.js aplikaciju, na vaš računar).

Instalacioni program je mali, * instalacija se obavlja brzo i lako, a nakon instalacije, putanja do izvršne datoteke Node aplikacije biće prijavljena operativnom sistemu.

* Nije samo instalacioni program mali: Node zauzima svega nekoliko desetina Megabajta i nakon instalacije.

Međutim, iako sama instalacija okruženja Node.js zauzima relativno malo memorijskog prostora, dodatne aplikacije i biblioteke koje možete preuzimati sa interneta, često umeju da budu "poveće" (i kada se ovakvi sadržaji posle nekog vremena "nakupe", memorijsko zauzeće je često 'podosta' veće od nekoliko desetina Megabajta - o čemu takođe treba voditi računa).

Još jedna napomena: u slučaju da koristite starije verzije operativnog sistema Windows, nećete moći da koristite najnoviju verziju Node.js-a (v14 u trenutku pisanja ovog članka), što na sajtu nije naglašeno.

Kao i u članku koji smo posvetili Python-u, i ovoga puta će komande za pokretanje skripti odgovarati Windows okruženju (u slučaju Linux-a i MacOS-a, putanje prema direktorijumima i samoj izvršnoj datoteci Node.js aplikacije se razlikuju, ali, ostale komande su gotovo istovetne).

Pokretanje korisničkih aplikacija

Pre nego što počnemo da pokrećemo Node aplikacije (koje ćemo samostalno kreirati), potrebno je da prvo utvrdimo 'osnovnu tehničku ispravnost' instaliranog okruženja. :)

Otvorićemo sistemsku konzolu, * i potom ćemo uneti sledeću naredbu (ista naredba važi i za Linux i MacOS okruženja):

		
node -v
		
	
Slika 1. - Provera verzije radnog okruženja Node.js.

* Na Windows računarima, najlakše ćete pronaći konzolu preko startnog menija, ** u koji treba uneti naredbu cmd,

** Prečica: CTRL+ESC (ili, jednostavno - Win taster).

Ako je sve u redu, biće prikazan odgovor nalik sledećem (s tim da će verzija u vašem slučaju gotovo sigurno biti drugačija, to jest, novija):

		
v13.14.0
		
	
Slika 2. - Primer konzolnog ispisa koji se dobija pri pokretanju naredbe sa slike #1.

Uspešnim izvršavanjem komande node -v ustanovili smo dve stvari:

  • pre svega to da je okruženje Node.js uredno instalirano i da je putanja do izvršne datoteke Node.js aplikacije uredno prijavljena operativnom sistemu (što znači da se komanda node može pokretati iz bilo kog direktorijuma)
  • konkretnu verziju paketa Node.js

Sada možemo pokretati i naše sopstvene skripte.

Kao prvo, prostim unošenjem komande node (bez dodatnih argumenata), dobija se direktan pristup JS interpretatoru ....

		
D:\node_apps> node
Welcome to Node.js v13.14.0.
Type ".help" for more information.
>
		
	
Slika 3. - Primer pokretanja Node.js interpretatora bez navođenja naziva JS datoteke (što praktično znači da se u nastavku JS komande mogu predavati direktno).

.... kome se mogu direktno predavati instrukcije.

Ako interpretatoru predamo sledeće komande (jednu za drugom) ....

		
// 1.
console.log(a)

// 2.
let a = 12
console.log(a)

// 3.
console.log(`а + 10 = ${a + 10}`)
		
	
Slika 4. - Primer komandi koje ćemo redom predati Node.js interpretatoru (za probu).

.... dobićemo sledeće povratne poruke:

		
// 1.
undefined

// 2.
12

// 3.
a + 10 = 22
		
	
Slika 5. - Poruke koje se ispisuju u konzoli, po pokretanju naredbi sa prethodne slike.

Međutim ("generalno"), programeri se vrlo retko obraćaju interpretatoru neposredno (naravno, niko vam ne brani da takav interaktivni pristup (ako vam se baš sviđa), isprobavate do mile volje 🙂).

Umesto pokretanja metodom ručnog zadavanja pojedinačnih komandi, Node aplikacije se gotovo uvek pokreću iz datoteka (s tim da ozbiljnije projekte obavezno treba smeštati i u zasebne direktorijume, i pisati za njih konfiguracione JSON datoteke).

Baš kao što smo i do sada radili, kada smo pisali programe i sajtove u drugim jezicima, i ovoga puta kreirajte zaseban direktorijum (tj. 'folder') za vaše Node.js projekte (osnovna adresa koju ćemo mi koristiti u članku je "D:\node_apps"), i potom sačuvajte, na lokaciji koju ste predvideli za Node aplikacije, datoteku sa nazivom proba.js (poznata ekstenzija na koju ste već navikli) - i unesite u datoteku sledeći sadržaj:

		
console.log("Dobar dan! :)");
		
	
Slika 6. - Nezaobilazni program "zdravo svete" (Node.js varijanta), sa kojim uvek počinjemo upoznavanje sa novim jezicima i tehnologijama.

Još jednom, napomena: i ostale skripte koje ćemo (tek) pisati, smestite u zasebne datoteke (a kasnije, kada na red dođu veći projekti sa više datoteka, kreirajte i zasebne foldere za svaki projekat).

Otvorite konzolu (ako ste je zatvarali) i unesite sledeće komande:

		
D:
cd \node_apps
		
	
Slika 7. - Konzolne naredbe za prebacivanje u direktorijum sa Node.js skriptama (koje ćemo kreirati).

Ako koristite drugačiju putanju ili neki drugi OS, postarajte se da dođete do direktorijuma sa skriptama.

Na kraju, pokrenite "hello world" aplikaciju;

		
node proba.js
		
	
Slika 8. - Pokretanje prve Node skripte.

U konzoli će biti ispisan sledeći tekst:

		
D:
cd \node_apps
D:\node_apps> node proba.js
Dobar dan! :)
		
	
Slika 9. - Konzolni ispis koji se dobija pokretanjem skripte sa slike #6.

Sve je (bar naizgled), vrlo slično kao da je pokrenut program koji je pisan u C-u (i skoro isto kao kada smo pokretali Python skripte).

Usput: nije "strašno" ni ako se ne prebacimo u direktorijum u kome se nalazi skripta koju želimo da pokrenemo, ali - u tom slučaju se mora navesti cela putanja do datoteke (npr: D:\> node d:\node_apps\proba.js i sl).

Node Package Manager - npm

Na ovom mestu upoznaćemo se ukratko i sa programom Node Package Manager (u daljem tekstu - npm), koji olakšava posao instaliranja Node.js modula, biblioteka, ili celokupnih aplikacija.

Neki od modula koje ćemo koristiti, kao što je recimo fs (File System), deo su osnovne instalacije paketa Node.js (fs je jedan od tzv. 'core modula'), međutim, drugi moduli se moraju dodatno instalirati, i - u takvim situacijama - "na scenu stupa" npm.

Sa pojmom modula u JavaScript-u upoznali smo se u članku o ES6 sintaksi.

Modul mysql, koji (očekivano) služi za povezivanje Node aplikacija sa MySql bazama podataka, jedan je od modula koji se moraju dodatno instalirati (i trebaće nam kasnije u članku).

Da bismo instalirali navedeni paket, u konzolu je potrebno uneti sledeću naredbu (podrazumevamo da se još uvek nalazimo u folderu sa Node.js projektima):

		
npm install mysql
		
	
Slika 10. - Komanda za instaliranje modula mysql, preko menadžera paketa npm (Node Package Manager).

Po uspešno završenoj instalaciji, u prilici smo da koristimo modul mysql (sa svim pripadajućim funkcijama), ali, bitno je da postupamo svesno i odgovorno po pitanju strukture direktorijuma (tj. po pitanju strukture Node.js projekata).

U prethodnom slučaju, modul mysql je postao dostupan aplikaciji koju pišemo, kao i ostalim (manjim) aplikacijama koje možete pokretati iz probnog foldera, * međutim, aplikacije koje su smeštene u druge foldere - ne mogu koristiti modul mysql.

Jednostavno, korisnicima je dat izbor da module instaliraju: 'u lokalu' (kao u gornjem primeru), * ili tako da budu dostupni svim Node aplikacijama na računaru, što se postiže preko argumenta -g ('global'):

		
npm install mysql -g
		
	
Slika 11. - Instaliranje modula mysql preko npm-a (uz korišćenje argumenta -g).

* U smislu urednosti, instaliranje dodatnih modula u zajednički folder, nikako ne predstavlja "idealno rešenje" (ni izdaleka - i želimo da budemo sasvim jasni po tom pitanju :)), ali, budući da ćemo iz zajedničkog direktorijuma pokrenuti samo nekoliko manjih, probnih Node aplikacija, situacija je .... relativno prihvatljiva. :)

Dakle: na samom početku nismo hteli da "komplikujemo", međutim, kada su u pitanju iole ozbiljniji projekti kojima ćete se baviti ubuduće, izaberite - kao što smo prethodno nagovestili - jednu od sledeće dve opcije: za svaki projekat, koji se nalazi u zasebnom folderu, instalirajte neophodne module 'u lokalu', ili - instalirajte module tako da budu dostupni globalno.

Menadžer paketa npm može se koristiti i za inicijalizaciju projekata, ali, u tom slučaju je potrebno da svaki projekat bude smešten u zaseban direktorijum (tj. 'folder').

Pokretanjem sledeće komande (na primer, unutar foldera D:\node_proba\projekat_01) ....

		
npm init -y
		
	
Slika 12. - Inicijalizacija projekta (u zasebnom direktorijumu), preko programa npm.

.... kreira se "prazna" * konfiguraciona JSON datoteka:

		
{
	"name": "projekat_01",
	"version": "1.0.0",
	"description": "",
	"main": "index.js",
	"directories": {
		"doc": "docs"
	},
	"scripts": {
		"test": "echo \"Error: no test specified\" && exit 1"
	},
	"keywords": [],
	"author": "",
	"license": "ISC"
}
		
	
Slika 13. - Primer konfiguracione JSON datoteke (koja nastaje pokretanjem komande 'npm init -y').

Navedeni pristup (inicijalizacija projekta preko programa npm), svakako pomaže u organizaciji većih i ozbiljnijih projekata, ali, to je tema koju ćemo obraditi u sledećem članku, u kome ćemo detaljno opisati postupak kreiranja web servera uz pomoć paketa Express.js (verovatno najpopularnije biblioteke za Node.js).

* JSON datoteka naravno/očigledno nije doslovno prazna, već je prazna 'figurativno', tj. popunjena je generičkim vrednostima, koje se lako mogu izmeniti u bilo kom editoru.

Ukoliko komandu init pozovemo bez argumenta -y, bićemo u prilici da preko konzole unesemo različite vrednosti kao što su: naziv projekta, verzija, opis i sl, ali, prethodno smo prikazali pristup koji je uobičajeniji, i podrazumeva "brzinsko" kreiranje datoteke, uz naknadno unošenje odgovarajućih vrednosti (kao što smo nagovestili, konkretne vrednosti je jednostavnije uneti ili izmeniti preko editora nego preko konzole).

Kada je u pitanju osnovna funkcionalnost Node aplikacija (i budući da smo se već bavili osnovnim komandama JavaScript-a kao i drugim temama vezanim za ovaj jezik), nećemo "ponavljati priču" o dobro poznatim C-olikim konstrukcijama JS-a (kao što su grananja, petlje, način definisanja i pozivanja funkcija i sl), ali, iznećemo usput nekoliko primedbi opšteg tipa, koje se tiču razlika između izvršavanja skripti u browser-u i pokretanja Node.js aplikacija.

Razlike između Node.js-a i izvršavanju JS-a u browseru

Sa jedne strane, Node.js jeste "JavaScript koji se izvršava u konzoli" (što ćemo jasno videti već na primerima u narednim odeljcima), ali, sa druge strane - u odnosu na pokretanje JavaScript-a u browseru - postoje određene razlike koje su očigledne i neke razlike koje su 'nešto manje očigledne':

  • Node.js ima pristup file sistemu, ali, nema pristup DOM strukturi, browser-u i pripadajućoj funkcionalnosti (tj. objektima window i document, kukijima i objektu localStorage)
  • 'JavaScript u browser-u' nema pristup file sistemu, ali (naravno/očekivano/dobro poznato), ima pristup DOM strukturi i ostalim navedenim opcijama u browserima

U svemu postoji još jedan važan detalj (koji, reklo bi se, ponekad "žulja" programere koji su navikli na 'JavaScript u browseru') - ne postoji globalni opseg promenljivih, odnosno: promenljiva koja je deklarisana izvan funkcija, nije automatski dostupna svim modulima (tj. datotekama) unutar projekta, već samo onom modulu u kome je deklarisana (međutim, kao što smo pokazali u linkovanom članku, postoji način da se podaci i funkcije učine dostupnim i drugim modulima).

Navedene razlike će (takođe) biti predmet detaljnije diskusije u narednom članku o Node.js-u (koji ćemo posvetiti kreiranju servera preko biblioteke Express.js).

Primer jednostavne Node.js aplikacije

Na početku smo pomenuli da je Node.js u ovom trenutku jedna od najpopularnijih serverskih tehnologija, a kao što takođe znamo, priprema HTML sadržaja je jedan od osnovnih zadataka u back-end programiranju.

Shodno navedenom, za sam početak pozabavićemo se (upravo) kreiranjem vrlo jednostavne Node.js aplikacije, koja (po pokretanju), čuva HTML dokument na lokaciji po izboru.

Budući da smo se već upoznali i sa šablonskim niskama, formatiranje ćemo obaviti upravo preko šablonskih niski.

Imaćemo priliku da koristimo i povratne pozive (sa čime ste (nadamo se :)), takođe već upoznati), a upoznaćemo se i sa funkcijom writeFile, iz modula fs (koji smo ranije pominjali).

Prvo ćemo definisati funkciju koja vraća sadržaj HTML dokumenta (po sličnom obrascu kao u članku o šablonskim niskama):

		
function formatiranjeHTMLDokumenta(title, naslov_h1, prvi_pasus) {
	let htmlDoc = `
<!DOCTYPE html>
<html>
	<head>
		<title>${title}</title>
	</head>
	<body>
		<h1>${naslov_h1}</h1>
		<p>
			${prvi_pasus}
		</p>
	</body>
</html>
`;

	return htmlDoc;
}
		
	
Slika 14. - Funkcija koja vraća formatirani HTML ispis.

Napomena (još jednom): kreirajte zasebne datoteku za svaku Node aplikaciju (dok ne pređemo na nešto ozbiljnije projekte, koji će zahtevati i zasebne direktorijume).

U primeru u kome kreiramo HTML dokument, upis HTML dokumenta u datoteku obavićemo preko (već najavljene) funkcije writeFile, iz modula fs. *

		
const fs              = require('fs');
const nazivDatoteke   = 'index.html';
const sadrzajDatoteke = formatiranjeHTMLDokumenta("Node aplikacija #1", "Glavni naslov");

function proveraUpisa(err) {
	if (err) {
		console.error(err)
		return;
	}

	console.log(`Datoteka ${nazivDatoteke } je kreirana.`);
	console.log("Sadržaj je upisan.");
}

fs.writeFile(nazivDatoteke, sadrzajDatoteke, 'utf8', proveraUpisa);
		
	
Slika 15. - Skripta za formatiranje HTML datoteke, koja koristi funkciju sa prethodne slike (po pozivu metode writeFile, datoteka će biti sačuvana na lokaciju koju smo naveli).

* Skraćeno od "File System" (fs je jedan od 'core' modula i sadrži funkcije za čitanje i upis u datoteke, i druge funkcije vezane za operativni sistem).

Opšta šema poziva funkcije writeFile podrazumeva četiri argumenta:

  • naziv datoteke (koju je potrebno kreirati i/ili popuniti tekstualnim sadržajem)
  • tekstualni sadržaj koji se upisuje u datoteku
  • metodu enkodiranja (UTF-8)
  • funkciju povratnog poziva, koja će se izvršavati posle (pokušaja) upisa
		
fs.writeFile(nazivDatoteke, sadrzajDatoteke, 'utf8', callback);
		
	
Slika 16. - Opšta šema poziva metode writeFile iz modula fs.

Četvrti argument je definisan kao funkcija povratnog poziva, koja prima jedan argument (poruku o grešci), a ovoga puta callback funkciju nismo implementirali preko arrow notacije (već kao standardnu imenovanu funkciju), budući da nije u pitanju "funkcija manjeg obima koja se efikasno može zapisati u jednom ili dva reda".

Prethodno navedeno rešenje, u ovom slučaju smatramo elegantnijim i praktičnijim, međutim, budući da takođe nije u pitanju ni funkcija prevelikog obima, može se koristiti i lambda notacija:

		
fs.writeFile(nazivDatoteke, sadrzajDatoteke, 'utf8', (err) => {
	if (err) {
		console.error(err)
		return;
	}

	console.log(`Datoteka ${nazivDatoteke } je kreirana.`);
	console.log("Sadržaj je upisan.");
});
		
	
Slika 17. - Primer sa prethodne slike, prepravljen tako da koristi funkciju povratnog poziva koja je implementirana preko lambda notacije.

Ali - u gornjem primeru - i dalje bismo (uvek) radije birali varijantu #1 (callback funkcija implementirana preko imenovane funkcije).

Iako smo već najavili da nećemo u uvodnom članku koristiti baze podataka pri pokretanju servera (što će biti tema poslednjeg poglavlja), ipak smatramo da je već na početku potrebno upoznati se sa osnovnim funkcijama za pristup bazama podataka preko Node.js-a.

Povezivanje sa MySql bazom i preuzimanje podataka

Da bismo mogli da radimo 'išta' sa MySql bazama (baš kao i u primerima u kojima smo za povezivanje sa bazama koristili PHP), potrebno je prvo obezbediti najosnovniju funkcionalnost, to jest - potrebno je povezati Node projekat sa bazom podataka.

Kreirajte novu datoteku sa prigodnim nazivom i unesite u datoteku sledeći sadržaj:

		
const mysql = require('mysql');

const veza  = mysql.createConnection({
	host:     "localhost",
	user:     "root",
	password: "",
	database: "korisnici"
});

veza.connect(err => {
	
	if (err) {
		 console.log("Greška u povezivanju sa MySql serverom!");
		 throw err;
	}
	
	console.log("Uspešno ste se povezali sa MySql serverom.");

});
		
	
Slika 18. - Praktičan primer Node.js skripte za povezivanje sa bazom podataka.

Primećujemo da je (jedini) argument funkcije connect, callback funkcija (koja se aktivira posle povezivanja sa bazom).

Ovoga puta smo smatrali da je lambda notacija dobar izbor za implementaciju osnovnog povratnog poziva, međutim, konkretnu funkciju preko koje ćemo zapravo čitati sadržaj tabele (iz baze podataka), mnogo radije ćemo implementirati kao standardnu imenovanu funkciju (koju treba 'spremiti unapred'):

		
/* -------------------------------------------- */
// Definicija funkcije za čitanje podataka
// (u pitanju je imenovana funkcija koja će
// (kasnije) biti korišćena u okviru callback
// funkcije koja se poziva nakon što se
// uspostavi veza sa bazom ....
/* -------------------------------------------- */
function CitanjeTabele(veza, tabela, ime, prezime) {
	let upit = `SELECT * FROM ${tabela} WHERE ime="${ime}" AND prezime="${prezime}" ORDER BY id ASC`;
	
	veza.query(upit, (err, rezultat, polja) => {
		if (err) {
			console.log("Greška pri prosleđivanju upita!");
			throw(err);
		}

		console.log(rezultat);
		console.log(rezultat[0].ime);
		console.log(rezultat[0].prezime);
		console.log(rezultat[0].email);
	});
}
/* -------------------------------------------- */
const mysql = require('mysql');

const veza  = mysql.createConnection({
	host:     "localhost",
	user:     "root",
	password: "",
	database: "korisnici"
});
/* -------------------------------------------- */
// Poziv funkcije za čitanje podataka
// (koju smo ranije pripremili), obavlja se
// u okviru u okviru callback funkcije koja se
// pokreće nakon uspostavljanja veze ....
/* -------------------------------------------- */
veza.connect(err => {
	if (err) {
		 console.log("Greška u povezivanju sa MySql serverom!");
		 throw err;
	}
	console.log("Uspešno ste se povezali sa MySql serverom.");
	CitanjeTabele(veza, "korisnici", "Petar", "Petrović");
});
/* -------------------------------------------- */
console.log("Proba async ....");
/* -------------------------------------------- */

	
Slika 19. - Primer Node.js skripte koja pristupa bazi 'korisnici' i čita podatke iz tabele.

Funkcija CitanjeTabele koristi metodu query, koja pripada objektu veza i preko koje se bazi podataka (sa kojom se povezujemo) prosleđuje upit.

Na ovako jednostavnom primeru, ugnežđavanje funkcija i dalje deluje pregledno (bar donekle :)), međutim, ukoliko bi nastala situacija u kojoj "povratni pozivi koriste (dodatne) povratne pozive" .... "povratni pozivi povratnih poziva (takođe) koriste povratne pozive" .... (u mislima dodajte još koji 'nivo rekurzije') .... programski kod više ne bi bio pregledan (ni izdaleka)!

Ugnežđavanje povratnih poziva, i (što je mnogo bitnije) - sintaksne konstrukcije koje omogućavaju da se (višestruko) ugnežđeni pozivi izbegnu - biće tema članka o asinhronom programiranju u Javascriptu (članak je već u pripremi i biće objavljen uskoro).

Što se tiče podataka koji su preuzeti iz MySql baze, može se primetiti da je način pristupa podacima idejno sličan načinu pristupa u PHP-u, ali, postoje i razlike:

  • umesto da se sadržaj čita red-po-red, preko funkcije (u PHP-u, u pitanju je funkcija mysqli_fetch_assoc), redovima se može pristupiti direktno, preko indeksa
  • za pristup pojedinačnim podacima, koriste se nazivi polja tabele (koji se pojavljuju kao polja objekta rezultat).

Za sam kraj uvodne priče o Node.js-u, sledi "ono što smo čekali" - pokrenućemo lokalni web server.

Pokretanje jednostavnog web servera

Kada smo koristili PHP za pokretanje web sajtova, nismo 'previše brinuli' o tome šta radi sam PHP interpretator (što je donekle očekivano, jer, kada se koristi paket kao što je Apache, PHP interpretator se pokreće automatski).

Takođe, na internet serverima za koje se plaća hosting, tipično ne postoji mogućnost samostalnog pokretanja PHP interpretatora.

Sa Node aplikacijama, situacija je sa jedne strane malo drugačija, i moraćemo sami da pokrenemo server (koji je pre toga potrebno konfigurisati), ali, sa druge strane, procedura nije (iole značajno) komplikovanija u odnosu na proceduru u PHP-u (na koju smo navikli).

U osnovnom smislu, web server je program koji obraća pažnju na mrežni saobraćaj koji je usmeren prema računaru na kome je program pokrenut:

  • kada se na odgovarajućem mrežnom portu pojavi zahtev za određenim vidom obrade podataka, server proverava zahtev
  • ukoliko je zahtev uredno formatiran - obavlja se priprema sadržaja koji će biti vraćen korisniku (tj. klijentu) koji je zahtevao sadržaj

Još prostije: korisnik se obraća serveru preko URL-a (tj. preko "putanje"), server tumači zadatu putanju, i - ukoliko je korisnik naveo jednu od mogućih/dozvoljenih putanja - dobiće od servera odgovor u vidu sadržaja (odnosno, u browseru će se otvoriti naslovna stranica, blog, kontakt stranica i sl). *

* Uzeli smo za primer (fiktivni) server na kome postoje putanje: /, /blog i /kontakt (ostale putanje nisu dozvoljene).

Ukoliko zahtev nije uredno poslat, odgovor servera će biti neki od "nepovoljnih" HTTP statusa. *

U glavnom primeru kojim se bavimo, aplikaciju ćemo smestiti u datoteku "probni_server.js" (za sada nećemo ipak kreirati i zaseban podfolder), unećemo sledeći sadržaj ....

		
/* -------------------------------------------- */
// PROBNI NODE SERVER:
/* -------------------------------------------- */

// Uvoz neophodnih modula:
const http = require('http');
const fs   = require('fs');

// Parametri veze:
const hostname = '127.0.0.1';
const port     = process.env.port || 8080;

// Definisanje jednostavnog HTTP servera:
const server = http.createServer((req, res) => {
	res.statusCode = 200;
	res.setHeader('Content-Type', 'text/html');
	fs.createReadStream('index.html').pipe(res);
});

// Pozivanje funkcije za osluškivanje
// 'mrežnog saobraćaja':
server.listen(port, hostname, () => {
  console.log(`Server na adresi http://${hostname}:${port}/ je pokrenut ....`);
});
		
	
Slika 20. - Primer Node.js skripte preko koje se definiše jednostavan HTTP server.

.... i potom ćemo pokrenuti server (kao što bismo pokrenuli bilo koju drugu Node aplikaciju):

		
node probni_server
		
	
Slika 21. - Naredba za pokretanje probnog web servera u terminalu.

Što se tiče parametara koji su korišćeni za kreiranje servera, prepoznajemo:

  • IP adresu (127.0.0.1 - što je praktično localhost)
  • port (process.env.port || 8080)
  • statusni kod (200)

* Usput: kao što smo pomenuli u linkovanom članku, HTTP statusi se šalju uvek, ali, u najpraktičnijem smislu, HTTP statusi se direktno prikazuju samo u slučaju pojave grešaka.

(Ukoliko učitavanje protekne 'bez ispada', u browseru se tipično prikazuje sadržaj stranice.)

Što se tiče tehnikalija koje (možda) "ne prepoznajemo" na samom početku, osvrnimo se za sada na objekte req i res.

U pitanju su objekti koji sadrže:

  • parametre zahteva koji je korisnik uputio (za šta je zadužen objekat req (skraćeno od "request"))
  • detaljan odgovor servera (za šta je zadužen objekat res (skraćeno od "response"))

Metoda pipe, preko koje se direktno predaje odgovor klijentu (praktično - objekat res), posebno je zanimljiva, jer upravo se preko navedene metode sadržaj HTML datoteke index.html preusmerava u objekat res (koji "nosi" sadržaj stranice koja će biti prikazana). *

Videli smo da se ne mora koristiti ekstenzija .js pri pozivu skripte preko konzolnog Node interpretatora (nismo morali ni do sada, ali, hteli smo da budemo precizni na samom početku :)), a ako posmatramo terminal, može se steći utisak da program .... "stoji i ne radi ništa"?!

Međutim, kreirali smo Node aplikaciju koja (osim poruke koja se ispisuje na početku), ne komunicira sa krajnjim korisnicima preko konzole, već - preko internet browsera.

Ako otvorimo browser i unesemo adresu localhost:8080, biće prikazana stranica koju smo kreirali preko funkcije formatiranjeHTMLDokumenta (iz prvog primera).

* Koncept "protočne obrade" (eng. pipeline/piping), podrazumeva prosleđivanje rezultata obrade jednog programa (ili, u našem slučaju, funkcije), drugom, odnosno - "sledećem" programu.

Navedeni pristup posebno je zastupljen na UNIX-u i operativnim sistemima koji su nastali iz UNIX-a (Linux, BSD), što možemo videti na primeru sledećih naredbi:

ls -l | grep "oktobar" > pretraga_oktobar.txt

Komanda ls pronalazi (i priprema za prikaz) tekstualne podatke o sadržaju direktorijuma - što bi 'inače' značilo da će u konzoli biti prikazani podaci o svim datotekama i svim poddirektorijumima, ali - budući da se rezultat ne šalje na standardni izlaz (tj. konzolu), već se šalje komandi grep (koja služi za pretragu tj. 'filtraciju' unetih podataka) - biće odbačeni svi rezultati koji ne sadrže u imenu nisku "oktobar" i, na kraju - umesto da rezultat (izvršavanja komande grep) bude prikazan u konzoli - biće preusmeren (preko operatora >) - u datoteku "oktobar.txt"

U slučaju Node servera koji smo kreirali, pojam "pajpovanja" podrazumeva da će rezultat čitanja datoteke index.html biti prosleđen u objekat res.

Šta je REPL?

Pošto smo ustanovili da server 'funkcioniše' (u osnovnom smislu), osvrnućemo se još jednom na tok komunikacije između klijenta i servera:

  • program "osluškuje" mrežni saobraćaj preko porta 8080
  • periodično se proverava da li postoje zahtevi koji su upućeni serveru
  • čim se pojavi zahtev, proverava se URL i zatim (ukoliko je klijent uredno uneo adresu), * server isporučuje odgovarajući sadržaj (u konkretnom primeru koji smo prikazali, sadržaj je statička HTML stranica)

Nakon što se (određeni) zahtev korisnika obradi, aplikacija se vraća na "osluškivanje" (tj. praktično: "očekivanje budućih zahteva").

Skraćenica REPL iz gornjeg naslova (Read-Evaluate-Print-Loop), odnosi se na prethodno opisani postupak:

  • Read ("osluškivanje" konekcije)
  • Evaluate (provera i obrada zahteva)
  • Print (prikaz stranice - u slučaju da postoji pravilno primljen i obrađen zahtev)
  • Loop (povratak na osluškivanje konekcije)

* Ovoga puta, ne postoji "prava" provera, ali, u tehničkom smislu, "provera" se svodi na to da server dozvoljava da se korisnici obrate samo korenoj "ruti" servera: / (definisanjem dodatnih putanja bavićemo se u sledećem članku o okruženju Node.js).

Sledeći koraci ....

Uvodni članak o okruženju Node.js zamislili smo samo kao kratak uvod u osnovne tehnikalije i ovoga puta nećemo 'širiti diskusiju', međutim, budući da smo "načeli" priču o "Node serverima", svakako ćemo se u doglednoj budućnosti pozabaviti upravo temom pokretanja (ozbiljnijeg) servera.

Koristićemo okruženje Express.js, koje predstavlja jednostavnu i funkcionalnu nadogradnju osnovnog okruženja (popularno: "micro framework"), definisaćemo rute i odgovore, predvidećemo mehanizme za obradu korisničkih grešaka, koristićemo šablone za kreiranje HTML-a, i naravno - povezaćemo web aplikaciju sa bazom podataka (a bavićemo se i brojnim drugim tehnikalijama).

Pored "Express servera", teme kojima ćemo ubuduće takođe posvetiti pažnju, biće: razlike između PHP-a, Node.js-a i drugih back-end tehnologija (pri čemu ćemo se detaljno pozabaviti i PHP interpretatorom), asinhrono programiranje u JS-u, AJAX, Fetch API (a "negde usput" napravićemo i kratak osvrt na back-end tehnologije koje su zasnovane na Python-u).

Tema ima "podosta", ali, tim bolje :) ....

Autor članka Nikola Vukićević Za web portal codeblog.rs
Napomena: Tekstovi, slike, web aplikacije i svi ostali sadržaji na sajtu codeblog.rs (osim u slučajevima gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog pismenog odobrenja autora.
© 2020-2026. Sva prava zadržana.
Facebook LinkedIn Twitter Viber WhatsApp E-mail
početna > Članci > Uvod u Node.js
codeBlog codeBlog
Sajt posvećen popularizaciji kulture i veštine programiranja.
Napomena: Tekstovi i slike na sajtu codeblog.rs (osim u slučajevima, gde je drugačije navedeno) predstavljaju intelektualnu svojinu autora sajta codeblog.rs i zabranjeno je njihovo korišćenje na drugim sajtovima i štampanim medijima, kao i bilo kakvo drugo korišćenje u komercijalne svrhe, bez eksplicitnog odobrenja autora.
© 2020-2026. Sva prava zadržana.
Facebook - logo
Instagram - logo
LinkedIn - logo
Twitter - logo
E-mail
Naslovna
   •
Uslovi korišćenja
   •
Obaveštenja
   •
FAQ
   •
Kontakt