PUNIM DIPLOMEsmu.umib.net/DiplomaPublikimiPublic/DownloadDok?dok... · Arkitektura e sistemit ......
Transcript of PUNIM DIPLOMEsmu.umib.net/DiplomaPublikimiPublic/DownloadDok?dok... · Arkitektura e sistemit ......
-
UNIVERSITETI I MITROVICËS “ISA BOLETINI”
FAKULTETI I INXHINIERISË MEKANIKE DHE KOMPJUTERIKE
DEPARTAMENTI: INFORMATIKË INXHINIERIKE
PUNIM DIPLOME
Mentori: Kandidati:
MSc. Besmir Sejdiu, PhD Cand. Jeton Haxha
Mitrovicë, Maj 2020
-
UNIVERSITETI I MITROVICËS “ISA BOLETINI”
FAKULTETI I INXHINIERISË MEKANIKE DHE KOMPJUTERIKE
DEPARTAMENTI: INFORMATIKË INXHINIERIKE
PUNIM DIPLOME
LËNDA: KOMPJUTERIKA II
ZHVILLIMI I SISTEMIT PËR REZERVIME ONLINE NË
RESTORANT
Mentori: Kandidati:
MSc. Besmir Sejdiu, PhD Cand. Jeton Haxha
Mitrovicë, Maj 2020
-
1
PËRMBAJTJA
1. Hyrja dhe motivimi ......................................................................................................... 3
2. Teknologjitë e shfrytëzuara për zhvillimin e sistemit ............................................... 4
2.1. Gjuhët programuese ................................................................................................ 4
2.2. Dallimi në mes të termit Front End dhe Back End ............................................ 5
2.3. Gjuha programuese Javascript.............................................................................. 6
2.3.1. Sintaksa e gjuhës programuese Javascript ................................................ 7
2.4. ReactJS dhe ReduxJS .............................................................................................. 9
2.5. MongoDB dhe MongooseJS.................................................................................. 12
2.7. NodeJS dhe ExpressJS .......................................................................................... 15
3. Definimi i kërkesave funksionale dhe jo-funksionale .............................................. 17
4. Krijimi i bazës së të dhënave për rezervime online në restorant .......................... 19
5. Arkitektura e sistemit ................................................................................................... 23
6. Zhvillimi i sistemit të propozuar për rezervime online në restorant .................... 26
6.1. Krijimi i Back End-it ............................................................................................. 28
6.2. Krijimi i Front End-it dhe lidhja me Back End ................................................ 31
7. PËRFUNDIMI ............................................................................................................... 42
8. LITERATURA .............................................................................................................. 44
-
2
DEDIKIM
Këtë punim diplome u’a dedikoj familjes sime, shoqërisë sime dhe të gjithë
mësimdhënësve të mi që më shoqëruan dhe mundësuan arritjen e këtij rrugëtimi shumë
të rëndësishëm profesional.
-
3
KAPITULLI I
1. Hyrja dhe motivimi
Duke parë zhvillimin aktual të teknologjisë dhe rritjen e ndikimit të tij në secilin sektor
të ekonomisë, edhe sektori i gastronomisë është ndikur shumë në këtë aspekt. Pasiqë në
ditët e sotme jeta është shumë më dinamike se që ka qenë në të kaluarën, koha është një
faktor shumë i rëndësishëm në jetën e secilit. Duke parë këtë, mendova që të zhvilloj një
sistem për rezervime, porosi online në një restorant duke shfrytëzuar tëknologjinë. Ky
sistem ka për qëllim çasjen dhe arritjen e qëllimit të caktuar në kohë sa më të shpejtë dhe
kosto sa më të vogël. Aplikacioni do të zhvillohët në ueb duke shfrytëzuar gjuhën
programuese Javascript, e cila cilësohet një gjuhë shumë e fuqishme dhe me të ardhme të
ndritur si dhe sistemi integrues i zhvillimit do të jetë Visual Studio Code. Pjesa e parë e
këtij punimi diplome është njohja me gjuhën programuese Javascript dhe sintaksën e saj,
dallimi në mes të Front End dhe Back End dhe ndarja e gjuhëve në bazë të kategorive.
Pjesa e dytë fokusohet në llojet e kërkesave, qëllimin e tyre si dhe definimin e kërkesave
për aplikacionin tonë. Pjesa e tretë ka të bëj me llojet e bazave të të dhenave, MongoDB
si sistem për menaxhimin e të dhënave si dhe krijimin e bazës së të dhënave për
aplikacionit tonë. Pjesa e katërtë ka të bëj me arkitekturën e sistemit tonë. Si dhe pjesa e
pestë zhvillimi i aplikacionit për rezervime, porosi online në restorant.
-
4
KAPITULLI II
2. Teknologjitë e shfrytëzuara per zhvillimin e sistemit
2.1. Gjuhët programuese
Gjuha ka qenë mjeti ynë kryesor i komunikimit dhe interaksionit njerëzor për mijëra vjet.
Për një komunitet, gjuha përmban fjalë që njerëzve u nevojitën të komunikojnë. Fjalët në
veti janë abstrakte por ato tregojnë kuptimin ose veprimin. Kur shikojmë komunikimin e
kompjuterve, e shohim që nuk ka shumë ndryshim. Kompjuteri ka shumë pjesë
hardverike dhe softuerike që duhet të komunikojnë me njëra tjetrën, dhe kjo mundësohet
përmes gjuhëve kompjuterike programuese. Gjuhët kompjuterike programuese na
mundësojne të japim instruksione një kompjuteri në një gjuhë që kompjuteri e njeh.
Pasiqë e dijmë që kompjuteri kupton vetëm në formë të njëshave dhe zerove, gjuhët
programuese duhet të kompajllohën në mënyrë që kompjuteri ta kuptoj. Sic ekzistojnë
gjuhë të ndryshme në botë, ekzistojnë edhe shumë gjuhë programuese.
Zyrtarisht, gjuha e parë programuese ishte Plankalkül, e zhvilluar nga Konrad Zuse për
Z3 diku në mes të viteve 1943 dhe 1945. Sidoqoftë, ajo nuk u implementua deri në vitin
1998.
Short Code, e propozuar nga John Mauchly në vitin 1949, konsiderohet të jetë gjuha e
parë programuese e nivelit të lartë. Ajo ishtë e dizajnuar për të paraqitur shprehje
matematikore në mënyrë të lexueshme nga njerëzit. Sidoqoftë, ajo duhej të përkthehej në
gjuhën e makinës para se të ekzekutohej, ajo kishte relativisht shpejtësi të vogël
procesuese.
Disa gjuhë tjera programuese u zhvilluan në vitet e 50-ta dhe 60-ta, duke përfshirë
Autocode, COBOL, FLOW-MATIC dhe LISP. Prej këtyre gjuhëve, vetëm COBOL dhe
LISP përdoren në ditët e sotme.
Gjuhët programuese ndahën në bazë të dy kategorive: niveli i ultë (ang. Low level) dhe
niveli i lartë (ang. High level). ‚Niveli‘ i referohët se sa ngat kodit binar është një gjuhë
programuese.
Gjuha që llogaritët më së afërmi kodit binar është Asembly ose C.
Gjuhët që konsiderohën të nivelit të lartë janë: JAVASCRIPT, C#, JAVA, PYTHON etj.
-
5
Poashtu gjuhët programuese ndahen në bazë të mënyrës së funksionimit, psh. funksionale,
kompajlluese, procedurale, skriptuese, markuese etj. Më poshtë në tabelën 1, gjeni listën
për secilën nga kategoritë me gjuhët programuese përkatëse.
FUNKSIONALE KOMPAJLLUESE PROCEDURALE SKRIPTUESE MARKUESE
F#, Erlang,
Haskell, Joy,
OPAL, ML
C, C++, C#, D,
COBOL, Fortran,
Java, Objective-C,
Visual Basic,
Small
Pascal, Oberon,
MatLab, Occam,
PL/C, HyperTalk,
Javascript,
VBScript,
PHP, Perl,
Python, Ruby
HTML,
XML,
DHTML,
DML,
XHTML
Tabela 1. Gjuhët programuese në bazë të kategorive [5]
2.2. Dallimi në mes të termit Front End dhe Back End
Në fushën e programimit shpesh hasim dy terme: Front End dhe Back End, të cilat së
bashku përbëjnë programimin në tëresi.
Front End është gjithëçka që përfshihet me atë që përdoruesi sheh, duke përfshirë
dizajnin, fotografitë, përmbajtjen, strukturën. Kjo mundësohet përmes gjuhëve HTML,
CSS dhe Javascript.
Back End është gjithëcka që mundëson funksionimin e elementëve, logjikën dhe të
dhënat. Gjuhët që përdoren për Back End janë të shumëllojshme, si psh. JavaScript, PHP,
Python, JAVA, RUBY, C#, SQL, MongoDB etj.
Një tjetër tërm mjaft i njohur, i cili krijohet pas bashkimit të Front End dhe Back End
është Full Stack. Nuk ka ndonjë dallim strikt në mes të dy termeve të lartcekura, disa
programerë shpeshherë dijnë të programojnë në Front End por jo në Back End, dhe
anasjelltas. Më poshtë në figurën 1, gjeni një skemë të Front End dhe Back End, si dhe
disa gjuhë që përdorën në secilin term.
Figura 1. Skemë e Front End dhe Back End [6]
-
6
Sistemi ynë do të zhvillohet kryesisht nga Javascript dhe kornizat/libraritë e tij.
Front End:
HTML, JSX– gjuhë markuese
CSS, Bootstrap (librari e CSS) – gjuhë stiluese
ReactJS (kornizë e Javascript)
Back End:
MongoDB – sistem për menaxhimin e databazës
MongooseJS (kornizë e MongoDB)
ExpressJS (kornizë e Javascript)
NodeJS (kornizë e Javascript)
2.3. Gjuha programuese Javascript
Javascript është një gjuhë programuese kompjuterike dinamike. Është gjuhë e lehtë (nuk
shfrytëzon shumë memorie të kompjuterit), cross-platform (përdorët në shumë platforma)
dhe më së shumti përdoret si pjesë e ueb faqeve, implementimet e së cilës e lejojnë
skriptën e anës së klientit të ndërveproj me shfrytëzuesin dhe të bëjë faqet dinamike [15].
Poashtu është gjuhë programuese interpretuese me aftësi të orientuara nga objektet [2].
Javascript fillimisht njihej si LiveScript në vitin 1995, por në vitin 1996 Netscape e
ndërroi emrin në Javascript, ndoshta për shkak të famës që gjenerohej nga gjuha
programuese JAVA. Një vit më vonë, në vitin 1997 Javascript u pranua në një organizatë
të quajtur Ecma International në mënyrë që të krijojë një standard të ri. EcmaScript 1
(ES1) u bë verzioni i parë i gjuhës Javascript. Pra kur themi EcmaScript i referohemi
standardit ndërsa kur themi Javascript i referohemi gjuhës programuese. Pas një dekade
e më shumë, më saktësisht në vitin 2009 EcmaScript 5 (ES5) u lansua me shumë tipare
të reja, edhe pse ju deshën vite shfletuesve që ti implementojnë këto ndryshime të reja.
Në vitin 2015 u lansua EcmaScript 6 (ES6), që ishte ndryshimi më i madh i bërë në
gjuhën programuese Javascript, me shumë gjëra të reja dhe praktike për zhvilluesit.
Trendi vazhdon edhe në vitet në vazhdim, ES2016 ose ES7, ES2017 ose ES8, ES2018
ose ES9, ES2019 ose ES10.
ES5 mbetët verzioni që përkrahet nga të gjithë shfletuesit, ndërsa verzionet e lansuara më
vonë vazhdojnë të implementohen.
-
7
Javascript së bashku me HTML dhe CSS përbëjnë 3 bërthamat kryesore të uebit [4], siq
shihet në figurën 2.
HTML – paraqet strukturën dhe përmbajtjën
CSS – mundëson stilizimin
JS – mundëson funksionalitetin e faqes d.m.th ndërlidhjen e HTML dhe CSS
Figura 2. Tri bërthamat e uebit
2.3.1. Sintaksa e gjuhës programuese Javascript
Sintaksa e Javascript është një grup i rregullave që përcaktojnë një program të strukturuar
mirë. Më poshtë në tabelën 2, gjeni fjalët kyçe në Javascript.
Fjalët kyçe:
abstract arguments await boolen break byte
case catch char class const continue
debugger default deletë do double else
enum eval export extends for function
finally float false final goto if
implements import int interface in instanceof
let long native new null package
private protected public return short static
super switch synchronized this throw throws
transient true try typeof var void
volatile while with yielf
Tabela 2. Fjalët kyçe në Javascript [7]
Komentet në Javascript mund të përdoren për të shpjeguar kodin, dhe për ta bërë atë
më të lexueshëm. Ekzistojnë dy lloje të komenteve: një rresht ( // ) dhe më shumë rreshta
( /* */ )
-
8
Deklarimi i variablave bëhet përmes fjalëve kyçe: let, var dhe const. Ekzistojnë dy lloje
të variablave: lokale dhe globale. Rregullat që duhet marrë parasysh gjatë krijimit të
variablave (identifikuesve) janë [8]:
a) Emri duhet të filloj me a-z ose A-Z, me nënvize ( _ ) ose shenjën e dollarit ( $ ).
b) Pas shkronjës së parë mund të përdoren numrat 0 – 9, psh vlera1
c) Variablat janë të ndjeshme d.m.th vlera1 nuk është e njejtë me Vlera1
Deklarimi i funksioneve bëhet përmes fjalës kyçe function, e përcjellur nga një emër dhe
pastaj kllapat e vogla ( ).
Emri i funksionit mund të përmbaj shkronja, numra, nënviza dhe shenjën e dollarit $.
Kllapat mund të përmbajne emra të parametrave të ndarë me presje: (parametri1,
parametri2, ...).
Kodi që do të ekzekutohet me rastin e thirrjës së funksionit, vendosët brenda kllapave
gjarpërore { }. Pas kodit që do të ekzekutohet vendoset fjala kyçe return, kur Javascript
arrin këtë, funksioni do të ndalë ekzekutimin.
Ekzistojnë disa lloje të funksioneve, mirëpo gjatë zhvillimit të sistemit tonë shumicën e
rastëve do ta përdorim Arrow Function.
Arrow Function:
const MbledhVlerat = (vlera1, vlera2, vlera3) => {
return vlera1 + vlera2 + vlera3;
}
MbledhVlerat(2,6,12); // rezultati 20
Function Declaration:
function MbledhVlerat (vlera1, vlera2, vlera3) {
return vlera1 + vlera2 + vlera3;–
}
MbledhVlerat(2,6,12); // rezultati 20
Function Expression:
const MbledhVlerat = function(vlera1, vlera2, vlera3) {
return vlera1 + vlera2 + vlera3;
}
MbledhVlerat(2,6,12); // rezultati 20
-
9
Vektorët (ang. Arrays) janë shumë të rëndësishme në programim e veqanarisht në
Javascript. Vektorët mundësojnë të ruajmë disa të dhëna brenda një variable të vetme.
Definimi i tyre bëhet në disa mënyra:
const vektori1 = [‚vlera1‘, ‚vlera2‘, ‚vlera3‘];
ose
const vektori1 = new Array(‘vlera1’, ‘vlera2’, ‘vlera3’);
Vektorët në Javascript si në shumicën e gjuhëve tjerë programuese është ‘0 based’ d.m.th
vlera e parë e ka indeksin 0.
Manipulimi me stringje është shumë i shpeshtë në programim. Ekzistojnë disa mënyra
për menaxhim më të lehtë psh.
let emri = “Jeton”;
let mbiemri = “Haxha”;
let studenti = “Une jam ” + emri + “ “ + mbiemri;
// rezultati: Une jam Jeton Haxha
ose
let studenti = `Une jam ${emri} ${mbiemri}`;
// rezultati: Une jam Jeton Haxha
2.4. ReactJS dhe ReduxJS
React JS është një librari open-source e Javascript-it e krijuar dhe mirëmbajtur nga
Facebook që nga viti 2013, që përdoret për të ndërtuar ndërfaqë të përdoruesit (user
interface), specifikisht për aplikacionet një faqëshe (single page applications). Shpesh
quhet edhe kornizë (framework) e Javascript për shkak të sjelljes së saj dhe aftësive
[15,16]. Përdoret për të menaxhuar shtresën e pamjes për aplikacionet në web dhe në
mobil. React-i na mundëson të krijojmë komponentë të ripërdorshme të pavarura. Poashtu
React-i u mundëson zhvilluesve të krijojnë ueb aplikacione të mëdha që mund të
ndryshojnë të dhënat, pa pasur nevojë ta rifreskosh faqën. Qëllimi kryesor i React-it është
të jetë i shpejtë, i strukturuar dhe i thjeshtë. Ai punon vetëm në nderfaqë të përdoruesit në
aplikacione [3].
Ekzistojnë dy lloje të komponenteve në React: komponentet me klasa (ang. Class
Components) dhe komponentet me funksione (ang. Function Components).
Gjatë këtij aplikacioni do të përdoren komponentët me funksione.
-
10
Atributet e ReactJS [15,16]:
JSX – React-i e përdor JSX për të bërë shabllone në vend të Javascript-it të
zakonshëm. Është më i shpejtë sepse e optimizon kodin përderisa e kompajllon
atë. Është i sigurtë për gabime, dhe shumicën e gabimeve i kap gjatë kompajllimit.
Mundëson shkrimin më të lehtë dhe më të shpejtë të shablloneve.
Virtual DOM – është një kopje e lehtë e DOM-it origjinal. I ka të gjitha atributët
e DOM-it real. Kur bëhet ndonjë përditësim, i gjithë DOM-i virtual përditësohet.
Është shumë më i shpejtë se DOM-i real sepse i përditëson vetëm ndryshimet e
bëra dhe jo të gjithë DOM-in real, duke bërë krahasimin në mes të DOM-it real
dhe Virtual DOM-it. Kjo është arsyeja që manipulimi me DOM-in e ReactJS është
shumë më i shpejtë se sa i kornizave tjera si psh. Angular ose Vue.
State – është vendi prej ku të dhënat vijnë në komponentë. Ka komponentë me
gjendje (ang. State) dhe pa gjendje (ang. Stateless).
Props – Dallimi kryesor në mes të State dhe Props është se Props janë të
pandryshueshme.
Hooks – janë funksione që të lejojnë të ’futësh’ në gjendjën e React-it dhe tipareve
të ciklit prej komponentëve me bazë funksionet. Hooks nuk punojnë brenda
klasave – pra ato të lejojnë të përdorësh React-in pa klasa. Disa nga hooks janë:
useEffect, useState, useContext, useReducer, useCallback etj.
Si cdo kornizë tjetër edhe React-i ka përparësitë dhe mangësitë e tij. Në figurën 3,
tregohen përparësitë dhe mangësitë e React-it.
Përparësitë Mangësitë
Përdor DOM-in virtual që e bënë
eksperiencën e përdoruesit më të mirë,
dhe më pak kompleks.
Nevojitet librari shtësë për ‘routing’,
menaxhim të gjendjes dhe interaksion me
API.
Përdor JSX që është shumë i thjeshtë dhe
i lehtë për tu mësuar.
Është librari me madhësi të madhe.
Nuk ka nevojë për ndarje të skedarëve
për logjiken dhe markimin.
Ritmi i zhvillimit është shumë i lartë.
Është librari open-source që mirëmbahet
nga Facebook.
Mbulon vetëm pjesën e UI d.m.th front
end-in.
Ofron zgjidhje edhe për zhvillimin ne
tëlefon, duke shfrytëzuar React Native.
Dokumentimi është i mangët në
mirëmbajtje
Është më e shpejtë në renderime se
kornizat tjera.
-
11
Shprehjet kushtëzuese janë shumë të
dobishme.
Është miqësore me SEO (search engine
optimization).
Ka vegla shumë të mira për zhvilluesit. Tabela 3. Përparësitë dhe mangësitë e ReactJS [16]
Dallimet në mes të ReactJS dhe AngularJS:
1. ReactJS është librari ndërsa AngularJS është kornizë
2. ReactJS u zhvillua nga Facebook ndërsa AngularJS nga Google
3. ReactJS përdor JSX ndërsa Typescript përdoret në AngularJS
4. Nuk ka koncept të DOM-it virtual në AngularJS
5. Në ReactJS përdoret ‘të dhëna vetëm në një kahje’, ndërsa në AngularJS dy-
kahëshe.
Redux
Redux është një mbajtës i gjendjës së parashikueshme për aplikacionet e shkruara në
Javascript. Ndërsa aplikacioni rritët, bëhet më e vështirë për ta mbajtur atë të organizuar
dhe për të ruajtur rrjedhën e të dhënave (data flow) [10]. Redux e zgjidhë këtë problem
duke menaxhuar gjendjën e aplikacionit me një objekt të vetëm global të quajtur Store.
Parimet themelore të Redux-it ndihmojnë në ruajtjen e qëndrueshmërisë në të gjithë
aplikacionin tonë, gjë që e bënë më të lehtë rregullimin dhe testimin e tij.
Parashikueshmëria e Redux-it përcaktohet nga këto tri parime, si vijon:
Një burim i vetëm i të dhënave
Gjendja e të gjithë aplikacionit ruhet në një objekt (object tree) brenda një vendi
të vetëm (single store). Meqë e gjithë gjendja e aplikacionit ruhet në një vend të
vetëm, kjo e bënë rregullimin më të lehtë dhe zhvillimin më të shpejtë.
Gjendja është vetëm e lexueshme (read-only)
E vetma mënyrë për ta ndryshuar gjendjën është thirrja e një funksioni të caktuar,
një objekt që shpjegon se cfarë ndodhi. Kjo d.m.th që askush nuk mund ta
ndryshoj direkt gjendjën e aplikacionit tonë.
Ndryshimet mund të bëhen me funksione të pastra
Për ta specifikuar se si procesi i gjendjes është transformuar nga aksionet
(actions), ne duhet të shkruajmë reduktues (reducers). Reduktuesi është një vend
-
12
qendror ku modifikimi i gjendjës ndodh. Reduktuesi është një funksion i cili merr
gjendje dhe aksion si argument, dhe kthen një gjendje të re të përditësuar.
Figura 3 në vijim, tregon procesin se si funksion Redux-i.
Figura 3. Skemë se si funksionon Redux-i [17]
2.5. MongoDB dhe MongooseJS
MongoDB është një databazë e orientuar në dokumentë, cross-platform që ofron
performancë të lartë, çasje të lartë dhe shfrytëzim në sisteme të ndryshme.
Ajo u zhvillua nga Eliot Horowitz dhe Dwight Merriman në vitin 2007, përderisa ata
hasën disa probleme me databazën relacionale. Emri rrjedh nga fjala ang. Humongous
(prezent në sasi të mëdha), që përkrahë idenë e procesimit të madh të të dhënave. Në vitin
2009, MongoDB u bë një projekt falas (open source) për çasje, përderisa kompania
ofronte edhe shërbime komerciale. Ndërsa në vitin 2013, kompania zyrtarisht u emërtua
MongoDB Inc.. MongoDB bënë pjesë në llojin e databazave NoSQL (ang. Not only
Structured Query Languages). MongoDB punon në koncept të koleksionit dhe
dokumentit [11].
Koleksioni është një grup i dokumenteve të MongoDB. Është ekuivalentë me tabelën tek
databazat relacionale. Një koleksion ekziston brenda një databaze të vetme. Koleksionet
nuk kërkojnë detyrimisht një skemë. Dokumentet brenda një koleksioni mund të kenë
fusha të ndryshme.
Dokumentet kanë skema dinamike. Skema dinamike d.m.th që dokumentët në
koleksionin e njejtë nuk kanë nevojë të kenë të njejtën strukturë ose grup të fushave, dhe
fushat e përbashkëta në dokumentet e koleksionit mund të mbajnë tipe të ndryshme të të
dhënave.
-
13
Avantazhet e MongoDB në krahasim me databazat relacionale:
Mund të mos ketë skemë, e lehtë për ndryshime
Struktura e një objekti të vetëm është i qartë.
Nuk ka ndërlidhje komplekse, aftësi për pyetës shumë kompleks
Përdorë memorien e brendshme për të ruajtur të dhënat punuese, çasje më të shpejtë
Në tabelat më poshtë tregohen dallimet në koncepte (tabela 4) dhe logjikë (tabela 5) në
mes të databazave SQL dhe NoSQL.
MongoDB Tabelat relacionale
Databazë Databazë
Koleksion Tabel
Dokument Rresht
Index Index
$lookup Join
Reference Foreign key Tabela 4. Konceptet në MongoDB dhe SQL [11]
NoSQL SQL
Databazë jo racionale Databazë racionale
E bazuar në dokumentë E bazuar në tabela
Skema dinamike Skema të pre-definuara
Përdorë gjuhë jo të strukturuar (UnQL) Përdorë gjuhë të strukturuar (SQL)
Preferohët për grupe të mëdha të të
dhënave
Nuk preferohët për grupe të mëdha të të
dhënave
Horizontalisht scalable (aftësia për të
ndryshuar në madhësi dhe sasi)
Vertikalisht scalable
Tabela 5. Dallimet në mes të NoSQL dhe SQL [11]
MongooseJS
Mongoose është një kornizë e Javascript që zakonisht përdoret në aplikacionet e NodeJS
me një databazë MongoDB. Është një mapues i një dokumenti (Object Document
Mapper), kjo d.m.th që Mongoose na lejon të krijojmë objekte me një skemë të fuqishme,
që kopjohet në një dokument të MongoDB.
-
14
Mongoose siguron një sasi të jashtëzakonshme të funksionalitëtit rreth krijimit dhe punës
me skema. Ajo aktualisht përmban tetë tipe të skemave që një vlerë mund të ruhet.
Ato janë: String, Number, Date, Buffer, Boolean, Mixed, ObjectId dhe Array [9].
Secili tip i të dhënave të lejon të specifikosh:
Një vlerë të paracaktuar
Një funksion të caktuar validues
Tregon që një vlerë është e kërkuar detyrimisht
Krijon indekset që na lejojnë të merrën më shpejtë të dhënat
Një funksion GET që na lejon të manipulojmë të dhënat para se të kthehët si një
objekt
Një funksion SET që na lejon të manipulojmë të dhënat para se të ruhen në
databazë
Poashtu disa tipe të të dhënave na lejojnë të i pershtatim se si të dhënat ruhen dhe
merren nga databaza. Për shembull:
Tipi i të dhënave String na lejon:
Të konvertojmë të dhënat në shkronja të vogla
Të konvertojmë të dhënat në shkronja të mëdha
Të i shkurtojmë të dhënat para se të ruhen
Të i limitojme të dhënat që ruhen gjatë procesit të validimit
Të caktojmë një enum që cakton listat e vlerave që lejohen
Tipi Number dhe Date na lejojnë të caktojmë vlerën minimale dhe maksimale.
Tipi Buffer na lejon të ruajmë të dhëna binare, psh ndonjë dokument të koduar.
Tipi Mixed na lejon të ndryshohet vlera në cfarëdo vlere tjetër.
Tipi ObjectId na lejon të ruajmë një vlerë unike për secilin dokument.
Tipi Array na lejon të ruajmë vektorë si në Javascript.
-
15
2.7. NodeJS dhe ExpressJS
Node JS është një platformë e shtresës së serverit, e krijuar në Motorin e Javascript të
Google Chrome-it, e cila u zhvillua nga Ryan Dahl në vitin 2009. Node JS është një
mjedis open-source (projekt falas) dhe cross-platform (shumë platformësh), për të
zhvilluar aplikacionet për server dhe rrjetë [14]. Aplikacionet janë të shkruara në
Javascript, dhe mund të ekzekutohën në OS X, Microsoft Windows dhe Linux. Node JS
poashtu ofron një librari të pasur me module të ndryshme, të cilat thjeshtësojnë zhvillimin
e web aplikacioneve duke shfrytëzuar NodeJS.
Disa nga atributet më të rëndësishme të NodeJS janë [13]:
Asinkron dhe i bazuar në ngjarje (event driven)
Të gjitha API e librarive të NodeJS janë asinkrone, që d.m.th veprojnë pavarur njëra
tjetrës. Në thelb d.m.th që një server i bazuar ne NodeJs kurrë nuk pret një API për të
kthyer të dhëna. Serveri zhvendoset te API i rradhës pasi e thërret atë dhe një
mekanizëm njoftimi i ngjarjeve (events) të NodeJS e ndihmon serverin të marrë një
përgjigjje nga thirrja e mëparëshme e API.
Shumë i shpejtë
Pasiqë është i ndërtuar në Motorrin e Javascript V8, libraria e NodeJS është shumë e
shpejtë në ekzekutimin e kodit.
Single Threaded por shumë e fuqishme
NodeJS përdorë nje model të vetëm me unazat e ngjarjeve. Mekanizmi i ngjarjës
ndihmon serverin të përgjigjet në mënyrë jo bllokuese dhe bënë serverin shumë të
fuqishëm, të kundërtën e serverave tradicional që krijonin thread-a të limituar për të
trajtuar kërkesat.
Licensa - NodeJS është e lansuar nën licensën e MIT.
Ku preferohet të perdoret NodeJS:
Tek aplikacionet e lidhura me hyrje/dalje
Tek aplikacionet me transmetim të të dhënave
Tek aplikacionet me të dhëna intenzive në kohë reale (DIRT)
Tek aplikacionet me API të bazuar në JSON
Tek aplikacionet një faqëshe (Single Page Applications)
Ndërsa nuk preferohet të përdoret kur kemi të bëjmë me shfrytëzim të madh të CPU-së.
-
16
ExpressJS
Express është një kornizë për ueb aplikacione që siguron një API të thjeshtë për të
ndërtuar uebfaqe, ueb aplikacione dhe back end. Është kornizë e lehtë e NodeJS, dhe është
shumë e domosdoshme për krijimin e aplikacioneve [12]. Me ExpressJS nuk kemi nevojë
të brengosemi për protokollet dhe proceset e afërta me procesorin.
Express siguron një ndërfaqe minimale për të ndërtuar aplikacionet tona, duke na ofruar
veglat që nevojitën për të ndërtuar aplikacionin tonë. Është fleksibil sepse ekzistojnë
shumë module të çasshme në npm (node package manager), e cila mund të vendoset
direkt në Express.
Express u zhvillua nga TJ Holowaychuk dhe mirëmbahet nga fondacioni NodeJS dhe
shumë kontribues anembanë botës.
Përkundër kundërshtarëve të Express, të cilët kanë një mënyrë për të ndërtuar
aplikacionet, Express-i nuk e ka ndonjë mënyrë të unifikuar për të ndërtuar dicka. Është
shumë fleksibil dhe i aplikueshëm.
Atributet e Express-it:
Mund të përdoret për të dizajnuar faqe të vetme, shumë faqëshe dhe ueb
aplikacione hibride.
Na lejon të konfigurojmë ndermjetësit për tu përgjigjur kërkesat HTTP
Cakton një tabelë të kursit e cila përdoret për të shfaqur aksione të ndryshme të
bazuar në metodë të HTTP dhe URL.
Lejon të shfaqë në mënyrë dinamike faqet e HTML të bazuar në argumentet e
japura në shabllone.
Përparësitë e Express-it:
Shumë i shpejtë
Asinkron dhe single-threaded
Strukturën e ngjajshme me MVC (Modal View Controller)
API-të e fuqishme
-
17
KAPITULLI III
3. Definimi i kërkesave funksionale dhe jo-funksionale
Kërkesat për një sistem janë përshkrimet e shërbimeve që një sistem duhet ti siguroj dhe
kufizimet në veprimet e tij. Këto kërkesa reflektojnë nevojat e klientëve për një sistem që
shërben për një qëllim të caktuar psh kontrollimin e një pajisje, bërjen e një porosie ose
me gjet informacione. Procesi i gjetjes, analizimit, dokumentimit dhe kontrollimit të
këtyre shërbimeve dhe kufizimeve quhen kërkesat inxhinierike [1].
Termi kërkesë nuk është përdorur rregullisht në industrinë e softuerëve. Në disa raste, një
kërkesë është thjeshtë një shprehje abstrakte e një shërbimi, që një sistem duhet të siguroj
ose të kufizoj në një sistem.
Shpesh kërkesat e sistemeve softuerike klasifikohen si funksionale ose jo-funksionale:
1. Kërkesat funksionale
Këto janë deklarimi i sherbimeve që sistemi duhet ti siguroj, si do të reagoj sistemi
në hyrje të caktuara dhe si do të veproj sistemi në situata të caktuara. Në disa raste,
kërkesat funksionale munden në mënyrë eksplicite të tregojnë se çfarë nuk duhet
të bëjë sistemi [1].
2. Kërkesat jo-funksionale
Këto janë kufizimet në shërbimet ose funksionet e ofruara nga sistemi. Këto
përfshijnë kufizime kohore, kufizime në procesin e zhvillimit, dhe kufizimet e
imponuara nga standarde të ndryshme. Kërkesat jo-funksionale shpeshë aplikohen
për sistemin në tërësi, sesa për disa veçori të caktuara të sistemit [1].
Definimi i kërkesat për aplikacionin tonë në bazë të llojit të përdoruesit. Aplikacioni ynë
ka tre lloje të përdoruesve: vizitor, klient dhe punëtor.
Vizitori
Kërkesat funksionale:
Vizitorit duhet t’i ofrohet mundësia e informimit përmes galerisë së restorantit, menysë
së restorantit, mundësia për regjistrim dhe kyçje në sistem, mundësia për çasje nga pajisjet
mobile.
-
18
Kërkesat jo-funksionale:
Vizitori nuk mund të bëjë porosi/rezervim nëse nuk është i kyçur në sistem, poashtu nuk
mund të bëjë rezervim më vonë se dy javë nga data aktuale.
Klienti
Kërkesat funksionale:
Përveç shërbimeve si vizitor, klientit duhet ti ofrohet mundësia: për të bërë porosi apo
rezervim, për të shtuar produkte në shportë, për ta shikuar dhe ndryshuar profilin personal,
ti shikoj porositë/rezervimet e bëra dhe statusin e porosisë/rezervimit
Kërkesat jo-funksionale:
Kohëzgjatja e gjendjës i kyçur në aplikacion nuk duhet të jetë më gjatë se 1 orë.
Klienti lirohet nga çmimi i shpërndarjes nëse nën totali është më i madh se 20€.
Punëtori
Ekzistojne tri lloje të punëtorëve në bazë të pozitës: menaxher, kuzhinier dhe shpërndarës.
Kërkesat funksionale:
Menaxherit duhet t’i ofrohet mundësia ti shikoj klientët ekzistues, t’i shikoj/ndryshoj
porositë dhe rezervimet, t’i shikoj/shtoj/ndryshoj/fshij punëtorët dhe produktet, ta
shikoj/ndryshoj profilin personal.
Kuzhinierit duhet t’i ofrohet mundësia për kycje në sistem, ta shikoj dhe ndryshoj
profilin personal, si dhe t’i shoh dhe ndryshoj vetëm porositë me status të caktuar.
Shpërndarësit duhet t’i ofrohet mundësia për kycje në sistem, ta shikoj dhe ndryshoj
profilin personal, si dhe t’i shoh dhe ndryshoj vetëm porositë me status të caktuar.
Kërkesat jo-funksionale:
Pas çdo veprimi të suksesshëm apo pasuksesshëm punëtorit duhet t’i paraqitet një njoftim.
Kuzhinieri dhe shpërndarësi nuk duhet ta kenë mundësinë t’i shikojnë apo ndryshojnë
produktet, rezervimet apo punëtorët tjerë.
-
19
KAPITULLI IV
4. Krijimi i bazës së të dhënave për rezervime online në
restorant
Për përdorim më të lehtë të MongoDB në NodeJS, do të përdorim MongooseJS. Cdo gjë
në Mongoose fillon me një skemë. Secila skemë kopjohet te një koleksion i MongoDB
dhe e cakton formën e dokumenteve brenda atij koleksioni. Për ta përdorë skemën, skema
duhet të konvertohet në një model.
Krijimin e skemave dhe modeleve do ta bëjmë brenda sistemit tonë të integruar zhvillues
Visual Code. Aplikacioni ynë do të përbëhet nga 6 modele (tabela në databazat
relacionale) si dhe emërtimi tash e tutje do të jetë në gjuhën angleze për shkak të
univerzalitetit.
Ato janë: Client (klienti), Employee (punëtori), Order (porosia), Reservation (rezervimi),
Product (produkti) dhe Cart (shporta e produkteve).
-Modeli Client do ti ketë këto atribute: emri, mbiemri, e-mail, fjalëkalimi, numri i
telefonit, adresa e banimit, data e regjistrimit si dhe statusi.
const mongoose = require('mongoose');
const ClientSchema = new mongoose.Schema({
name: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true},
telephone: { type: String},
street: { type: String },
houseNumber: { type: String },
city: { type: String },
country: { type: String },
dateRegistered: { type: Date, default: Date.now },
status: { type: Boolean, required: true }
});
module.exports = Client = mongoose.model('client', ClientSchema);
-
20
-Modeli Employee do ti ketë këto atribute: emri, mbiemri, e-mail, fjalëkalimi, numri i
telefonit, datëlindja, adresa e banimit, data e regjistrimit, pozita si dhe statusi.
const mongoose = require('mongoose');
const EmployeeSchema = new mongoose.Schema({
name: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true},
password: { type: String, required: true },
birthday: { type: Datë },
telephone: { type: String },
street: { type: String },
houseNumber: { type: String },
city: { type: String },
country: { type: String },
dateRegistered: { type: Date, default: Date.now },
position: { type: String, required: true },
status: { type: Boolean, required: true }
})
module.exports = Employee = mongoose.model('employee', EmployeeSchema);
-Modeli Order do ti ketë këto atribute: id e klientit, emri i klientit, numri i telefonit,
produktet ( id e produktit, emri, çmimi, sasia dhe përshkrimi), adresa e porosisë, data/koha
e porosisë, totali, mënyra e pagesës si dhe statusi.
const mongoose = require('mongoose');
const OrderSchema = new mongoose.Schema({
client: { type: mongoose.Schema.Types.ObjectId, ref: 'client' },
nameClient: { type: String },
telephoneNumber: { type: String },
products: [{
productID: { type: mongoose.Schema.Types.ObjectId, ref: 'product'},
productName: { type: String },
productPrice: { type: Number },
productQuantity: { type: Number },
-
21
productDescription: { type: String}}],
street: { type: String },
houseNumber: { type: String },
city: { type: String },
country: { type: String },
description: { type: String },
orderDate: { type: Date, default: Date.now },
total: { type: Number },
paymentMethod: { type: String },
status: { type: String}
})
module.exports = Order = mongoose.model('order', OrderSchema);
-Modeli Reservation do ti ketë këto atribute: id e klientit, emri i klientit, koha e fillimit,
koha e mbarimit, data për rezervim, numri i personave, përshkrimi, data e rezervimit si
dhe statusi.
const mongoose = require('mongoose');
const ReservationSchema = new mongoose.Schema({
client: { type: mongoose.Schema.Types.ObjectId, ref: 'client' },
name: { type: String },
startTime: { type: Date },
endTime: { type: Date },
date: { type: Date },
nrPerson: { type: String },
description: { type: String },
status: { type: String, required: true },
reservationDoneAt: { type: Datë, default: Date.now }
})
module.exports = Reservation = mongoose.model('reservation',
ReservationSchema);
-
22
- Modeli Product do ti ketë këto atribute: kategoria, emri i produktit, përshkrimi, çmimi,
fotografia e produktit, e ngarkuar nga punëtori i caktuar, data e shtimit si dhe statusi.
const mongoose = require('mongoose');
const ProductSchema = new mongoose.Schema({
category: { type: String, required: true },
name: { type: String },
description: { type: String },
price: { type: Number, required: true },
photo: { type: String },
uploadedBy: {
employee: { type: mongoose.Schema.Types.ObjectId, ref: 'employee'}
},
uploadedDate: { type: Date, default: Date.now },
status: { type: Boolean, required: true}
})
module.exports = Product = mongoose.model('product', ProductSchema);
-Modeli Cart do ti ketë këto atribute: id e klientit, produktet në shportë ( id e produktit,
emri, çmimi, sasia si dhe përshkrimi), nën totali, çmimi i transportit dhe totali.
const mongoose = require('mongoose');
const CartSchema = new mongoose.Schema({
client: { type: mongoose.Schema.Types.ObjectId, ref: 'client' },
cartProducts: [{
productID: { type: mongoose.Schema.Types.ObjectId },
productName: { type: String },
productPrice: { type: Number },
productQuantity: { type: Number },
productDescription: { type: String }
}],
subTotal: { type: Number },
deliveryFee: { type: Number },
total: { type: Number}
});
module.exports = Cart = mongoose.model('cart', CartSchema);
-
23
KAPITULLI V
5. Arkitektura e sistemit
Arkitektura e sistemit i përshkruan ndërveprimet në mes të aplikacioneve,
databazave, dhe ndërmjetësve (middlewares) në web. Siguron që shumë aplikacione të
punojnë njëkohësisht.
Le të sqarojmë me një shembull të thjeshtë duke hapur nje webfaqe (figura 4).
Fillimisht përdoruesi duhet të ketë lidhje në internet dhe një shfletues (Internet Explorer,
Google Chrome, Mozilla, Opera etj). Dhe pasi që të shtypet butoni Go pas shkruarjes së
URL-it në pjesën e adresës në shfletues, shfletuesi bënë kërkesë në atë adresë të caktuar.
Serveri i dërgon fajllat shfletuesit si përgjigjje të kërkesës së bërë. Dhe pastaj shfletuesi i
ekzekuton ata fjalla për të shfaqur faqen e kërkuar.
Figura 4. Skemë se si funksionon uebfaqja
Më poshtë në figurën 5, gjenden shtresat se si funksionon aplikacioni ynë.
Figura 5. Shtresat e sistemit tonë [18]
-
24
Tipet e arkitekturave të sistemeve
Ekzistojnë disa lloje të arkitekturave të sistemeve: SPA (Single Page Application),
Microservices, Serverless, MVC (Model View Controller) etj. Në sistemin tonë kemi
përdorur arkitekturen SPA.
SPA mundëson që në vend se të ngarkohet i gjithë aplikacioni nga serveri secilën herë që
përdoruesi bënë kërkesë për diçka të caktuar, ajo ofron që të ngarkohet vetëm kërkesa e
caktuar. AJAX, shkurtesë për Asynchronous Javascript and XML, është themeli që
mundëson komunikimin e faqeve në këtë mënyrë, dhe kështu i bënë SPA-të një realitet.
Për shkak që SPA-të i parandalojnë ndërprerjet në eksperiencën e përdoruesit, ato në një
mënyrë u ngjajnë aplikacioneve tradicionale të desktopit.
SPA-të janë të dizajnuara në një mënyrë që ato kërkojnë elementet dhe përmbajtjen më
të rëndësishme. Kjo çon në bërjen e aplikacioneve shumë interaktive.
Figura 6 tregon shtresat e pamjës së përdoruesit.
Figura 6. Shtresat e pamjes së përdoruesit [19]
UI components paraqet pamjen e aplikacionit tonë.
Façade paraqet një ndërfaqë të thjeshtësuar të komponenteve.
State management paraqet menaxhimin e gjendjës së komponenteve.
-
25
Store paraqet mbajtësin e gjendjes së aplikacionit.
Reducers paraqesin funksionet që caktojnë ndryshimin e gjendjës së aplikacionit.
Async services paraqesin shërbimet asinkrone ose të pavarura.
Gateways paraqesin kërkesat e përdoruesit, në rastin tonë HTTP kërkesat.
Commands paraqesin stilet e arkitekturave të softuerve si psh. RESTful, RPC etj.
Payloads paraqesin të dhënat që kërkohen nga përdoruesi përmes kërkesave, dhe në rastin
tonë paraqiten në formatin JSON.
-
26
KAPITULLI VI
6. Zhvillimi i sistemit të propozuar për rezervime online në
restorant
Aplikacioni i zhvilluar përmban komponentet si:
Shiriti i navigimit (navbar-i) për klientët dhe vizitorët, që shërben për çasje të
komponenteve si Gallery, Menu, Order, Reservation, Cart, Login, Register,
Profile dhe Logout
Faqja e parë ose landing page, që shërben me shumë si faqe informuese dhe
drejtuese.
Gallery, shërben për të njoftuar klientin me ambientin e restorantit dhe shfaq disa
fotografi të restorantit
Menu, shërben për të njoftuar klientin me listën e produkteve që gjenden në
menynë e restorantit
Order, shërben për të paraqitur listën e produkteve për porosi, secili produkt ka
foton, emrin, përshkrimin, çmimin dhe opsionin për shtim në shportë
Cart, apo shporta për mbajtjën e produkteve të zgjedhura, secili produkt në shportë
ka mundësinë e shtimit të përshkrimit (opsional), ndryshimin e sasise së dëshiruar
si dhe fshirjen e produktit nga shporta. Poashtu ekziston totali, nën totali, si dhe
çmimi i shpërndarjes ( nëse nën totali >= 20euro, shpërndarja është falas)
Checkout, është procesi i fundit para bërjes së porosisë. Duhet të ipet adresa e
porosisë, ndonjë përshkrim opsional, mënyra e pagesës si dhe paraqitët lista e
produkteve të zgjedhura për porosi
Reservation, shërben për të bërë rezervim. Data, koha dhe numri i personave janë
obligative, përshkrimi është opsional.
Login, shërben për kyçje në sistem. E-mail dhe fjalëkalimi janë obligativë.
Registër, shërben për regjistrim si klient në restorant. Fushat që duhet mbushur
me të dhëna janë: emri, mbiemri, e-mail, fjalëkalimi, adresa e banimit, si dhe
numri i telefonit.
Profile, shërben për të shfaqur profilin e përdoruesit të Kyçeur, mund të bëhet
ndryshimi i të dhënave.
-
27
My orders, shërben për të shfaqur listën e porosive të bëra. Secila porosi shfaq të
dhënat si: klienti, data e porosisë, numri i telefonit, adresa, produktet, përshkrimi
i porosise, totali, mënyra e pagesës, si dhe statusi i porosisë.
My reservations, shërben për të shfaqur listën e rezervimeve të bëra. Secili
rezervim shfaq të dhënat si: klienti, data, koha e fillimit dhe koha e mbarimit e
rezervimit, numri i personave, përshkrimi, si dhe statusi i rezervimit.
Logout, shërben për çkyçje nga sistemi
Shiriti i navigimit për punëtoret, ka çasje në profilin e punëtorit dhe funksionin
për çkyçje nga sistemi
Dashboard, shërben si meny navigimi për punëtorët, në listën e produkteve,
porosive, rezervimeve, punëtorëve dhe klientëve. Pamja e dashboard dallon
varësisht nga pozita e punëtorit, menaxheri ka çasje të plotë në të dhënat, ndërsa
kuzhinieri dhe shpërndaresi i porosive kanë kufizime.
Products, shërben për listim të të gjitha produkteve, ndryshim të produkteve, shtim
të produkteve dhe largim të produkteve përmes fushës Status ( aktiv ose jo-aktiv)
Orders, shërben për listim të porosive, si dhe ndryshim të statusit të porosisë së
caktuar
Reservations, shërben për listim të rezervimeve, si dhe ndryshim të statusit të
rezervimit të caktuar
Employees, shërben për listim të të gjithë punëtorëve, ndryshim të punëtorëve,
shtim të punëtorëve dhe largim të punëtorëve përmes fushës Status ( aktiv ose jo-
aktiv)
Clients, shërben për listim të të gjithë klientëve
Para se të fillojmë shkruarjen e kodit për të zhvilluar aplikacionin, duhet t’i instalojme
disa vegla që na nevojitën për zhvillim. Fillimisht na nevojitet një mjedis i integruar për
zhvillim. Ne do të përdorim Visual Code të kompanisë Microsoft.
Pasi kemi instaluar mjedisin për zhvillim, nevojiten këto vegla/shtojca:
Git – sistem për kontrollimin e verzioneve,
NodeJS,
Redux DevTools – pasiqë do të përdorim Redux për menaxhimin e gjendjës, zhvillimi pa
ketë vegël do të ishte shumë më kompleks dhe më i mundimshëm.
-
28
Për të shfrytëzuar databazën MongoDB, fillimisht duhet të regjistrohemi në webfaqën e
MongoDB www.MongoDB.com dhe të krijojmë një projekt. Pas krijimit të projektit
duhet të krijojmë një cluster, dhe pastaj të krijojme një user për çasje në atë clustër. Pas
krijimit të cluster-it, mund ta bëjmë lidhjen e MongoDB me aplikacionin tonë në Visual
Code, përmes Connection String-ut që na ofron MongoDB.
Për manipulim më të lehtë të të dhënave me MongoDB, ne do të perdorim MongooseJS,
që është një objekt modelimi për MongoDB.
6.1. Krijimi i Back End-it
Hapi i parë që duhet bërë në Visual Code është instalimi i fajllave startues, kjo bëhet
përmes komandës npm init në konzollën e Visual Code, japim të dhënat e aplikacionit
tonë dhe krijohet fajlli package.json. Pastaj i instalojmë disa vegla bazike që na nevojiten,
përmes komandës:
npm i express express-validator bcryptjs config jsonwebtoken mongoose.
Tani do i instalojmë disa nga veglat e zhvilluesit përmes komandës
npm i –D nodemon concurrently
Pas instalimit të këtyre veglave, fillojmë me krijimin e aplikacionit.
1. Krijojmë serverin, duke shfrytëzuar ExpressJS
const express = require(‘express’);
const path = require(‘path’);
const app = express();
const PORT = process.env.PORT || 8888;
app.listen(PORT, () => console.log(`Server started on port ${PORT}`));
2. Krijojmë skedarin API dhe shtigjet (routing)
a. Skedari API brenda skedarit routes
Routes \ api
auth.js, carts.js, clients.js, employees.js, orders.js, products.js, profile.js,
reservations.js
http://www.mongodb.com/
-
29
b. Caktimi i shtigjeve (routing)
// define routes
app.use(‘/api/clients’, require(‘./routes/api/clients’));
app.use(‘/api/products, require(‘./routes/api/products));
app.use(‘/api/employees, require(‘./routes/api/employees));
app.use(‘/api/profile, require(‘./routes/api/profile));
app.use(‘/api/auth, require(‘./routes/api/auth));
app.use(‘/api/reservations, require(‘./routes/api/reservations));
app.use(‘/api/orders, require(‘./routes/api/orders));
app.use(‘/api/carts, require(‘./routes/api/carts));
3. Ruajmë linkun e lidhjes me MongoDB në fajllin default.json brenda skedarit config
{
“mongoURI”: “mongodb+src://jeton123:@restappkipkt.
mongodb.net/test?retryWrites=true&w=majority”
}
4. Krijojmë funksionin për lidhje me databazë dhe e inicojmë funksionin në fajllin
server.js.
Funksioni për lidhje me databazë:
const mongoose = require('mongoose');
const config = require('config');
const db = config.get('mongoURI');
const connectDB = async () => {
try {
await mongoose.connect(db, {
useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true,
useFindAndModify: false});
console.log('MongoDB connected.');
}
catch (err) {
console.error(err.message);
process.exit(1);
}
}
module.exports = connectDB;
-
30
Inicimi i funksionit për lidhje me databazë, në fajllin server.js.
// connect database
connectDB();
5. Krijojmë modelin për secilin koleksion (e kemi bërë në kapitullin e katërtë).
6. Pas krijimit të modeleve, jemi të gatshëm të krijojmë API-në për sistemin tonë, që do
ti trajtoj HTTP kërkesat e përdoruesit (GET, POST, PUT, DELETE).
HTTP kërkesat për sistemin tonë:
auth: profile:
POST – Kyçe përdoruesin POST – Krijo profilin
GET – Kush eshtë i Kyçur GET – Gjej profilin tim
clients: reservations:
POST – Regjistro klientin POST – Shto rezervimin
GET – Gjej klientin nga ID e japur GET – Gjej rezervimet e mia
GET – Gjej të gjithë klientët ekzistues GET – Gjej të gjitha rezervimet ekzistuese
PUT – Modifiko rezervimin nga ID e japur
employees: products:
POST – Regjistro punëtorin POST – Shto produktin
GET – Gjej punëtorin nga ID e japur GET – Gjej të gjitha produktet ekzistuese
GET – Gjej të gjithë punëtorët ekzistues GET – Gjej produktin nga ID e japur
PUT – Modifiko punëtorin nga ID e japur PUT – Modifiko produktin nga ID e japur
orders: carts:
POST – Shto porosine GET – Merr shportën e përdoruesit
GET – Gjej porosine nga ID e japur POST – Modifiko produktet në shportë
GET – Gjej porositë e mia PUT – Modifiko shportën e përdoruesit
GET – Gjej të gjitha porositë ekzistuese DELETË – Fshij shportën pas porosisë
PUT – Modifiko porosinë nga ID e japur DELETË – Fshij produktet nga shporta
-
31
7. Pas krijimit të API, do të krijojmë ndërmjetësin (middleware) përmes JWT (JSON
Web Token). Ky ndërmjetës shërben që të ruajmë shtigjet nga përdoruesit e pa-
autorizuar.
Fillimisht ruajmë një fjalëkalim sekret për JWT-në tonë
{
“jwtSecret”: “mysecretwebtoken”
}
Pastaj krijojmë ndërmjetësin (middleware) auth.js.
const jwt = require('jsonwebtoken');
const config = require('config');
module.exports = function(req, res, next) {
// get token from header
const token = req.header('x-auth-token');
// check if not token
if(!token) {
return res.status(401).json({ msg: 'No token, authorization denied'});
}
// verify token
try {
const decoded = jwt.verify(token, config.get('jwtSecret'));
if(decoded.employee) { req.employee = decoded.employee; }
else { req.client = decoded.client; }
next();
}
catch(err) {
res.status(401).json({ msg: 'Token is not valid'});
}}
6.2. Krijimi i Front End-it dhe lidhja me Back End
1. Pas përfundimit të të gjitha HTTP kërkesave që nevojitën për aplikacionin tonë, tani
do të fillojmë me zhvillimin e pjesës së Front End, duke shfrytëzuar ReactJS dhe
Redux-in për menaxhimin e gjendjës së komponenteve. Së pari krijojmë aplikacionin
në React përmes komandës npx create-react-app client në konzollën e Visual Code.
-
32
Por në mënyrë që të punojnë në një takt pjesa e Front End dhe Back End, do të
shfrytëzojmë veglën concurrently, që tashmë e kemi instaluar në aplikacionin tonë.
Në fajllin package.json, tek objekti scripts shtojmë këto komanda në vijim dhe sistemi do
të sinkronizohet:
“server”: “nodemon server”,
“client”: “npm start –prefix client”,
“dev”: “concurrently \”npm run server\” \”npm run client\””
2. Tani do t’i instalojme disa vegla që na nevojitën gjatë punës me ReactJS, përmes
komandes:
npm i axios react-router-dom redux react-redux redux-thunk redux-devtools-
extension moment react-moment
3. Pastaj në skedarin client > package.json, shtojmë komandën
“proxy”: “http://localhost:8888”
Kjo komandë shërben që në vend se ta përdorim shprehjën http://localhost:8888 për
secilën HTTP kërkesë që bëjmë, do ta perdorim shkurtësën ‘/’ dhe është e njejta gjë.
4. Para se të fillojmë me shkrimin e kodit në pjesën e klientit, fillimisht do ta largojmë
pjesërisht kodin shabllon në projektin e krijuar nga React.
5. Tani do të fillojmë me krijimin e komponenteve të nevojshme për sistemin tonë.
Të gjitha komponentet do të vendosën në skedarin Components, brenda skedarit src. Por
komponentet do të ndahen në disa skedarë, në bazë të funksioneve:
ClientView
MyProfile > LeftPills, RightContentPills, ClientAccount, Profile, MyOrders,
MyReservations, OrderItem, ReservationItem
NewOrder > Order, Cart, CartProductItem, ProductItem, Checkout
NewReservation > Reservation
EmployeeView
Clients > Clients, ClientItëm, ClientView, ViewForm
Dashboard > Dashboard, DashboardPill, LeftPills
Employees >Employees, EmployeeItëm, EmployeeView,ViewAddForm
Orders > Orders, OrderItem, OrderView, ViewForm
Products > Products, ProductItem, ProductView, ViewAddForm
Profile > EProfile
Reservations > Reservations, ReservationItem
auth > Login, Register, NotAuthorized
-
33
layout > Alert, Gallery, Landing, Menu, Navbar, Spinner
routing > PrivateRouteClient, PrivatëRouteEmployee
6. Pasi të krijohen komponentet e nevojshme, duhet të caktohen shtigjet në React për
t’iu çasur atyne komponenteve. Caktimi i shtigjeve bëhet në fjallin App.js, dhe
sintaksa është si vijon.
Fillimisht importohet fajlli, dhe pastaj kthehët përmbajtja përmes metodës return.
Import from ‘’;
return (
Nëse shtegu është vetëm për klientët:
Nëse shtegu është vetëm për punëtorët:
7. Pas krijimit të komponenteve, aplikacioni është i gatshëm për përdorimin e ReduxJS.
Pasi që e dijmë se si funksionon Redux, fillimisht krijojmë store (mbajtësin e gjendjes)
së aplikacionit tonë.
import { createStore, applyMiddleware } from 'redux';
import { composeWithDevTools } from 'redux-devtools-extënsion';
import thunk from 'redux-thunk';
import rootReducer from './reducers';
const initialState = {};
const middleware = [thunk];
const store = createStore(
rootReducer, initialState,
composeWithDevTools(applyMiddleware(...middleware)));
export default store;
-
34
Në mënyrë që të mund t’a perdorim store-n e krijuar, në fajllin kryesor App.js importojmë
Provider dhe store e krijuar, dhe të gjitha shtigjet futën brenda këtij Provider, në mënyrë
që të kenë çasje në store.
import { Provider } from ‚react-redux‘;
import store from ‘./store’;
const App = () => (
)
Export default App;
8. Pastaj krijojmë skedarin reducers, dhe në të krijojme fajllin index.js. Fajlli index.js do
të shërbejë si bashkues i të gjithë reducers për secilin shteg. Kodi do të jetë si ne vijim.
import { combineReducers } from "redux";
import alert from './alert';
import auth from './auth';
import profile from './profile';
import product from './product';
import order from './order';
import reservation from './reservation';
import cart from './cart';
import employee from './employee';
import client from './client';
export default combineReducers({
alert, auth, profile, product, order, reservation, cart, employee, client
});
Për momentin të gjithë reducers janë të zbrazët, pra janë krijuar vetëm fajllat. Reducers
mund ti kuptojmë si mbajtës të gjendjës për një shteg të caktuar.
Për përdorimin e reducers, fillimisht duhet të krijohen tipet e aksioneve (Actions Types),
d.m.th se si të veproj një Reducer në një aksion/funksion të caktuar.
Tipet e aksioneve i krijojmë në skedarin Actions pastaj krijojmë fajllin types.js.
Për shembull, tipet për funksionet/aksionet e profile janë:
// tipet per alert
export const SET_ALERT = 'SET_ALERT';
export const REMOVE_ALERT = 'REMOVE_ALERT';
-
35
9. Pasi që tipet e funksioneve janë krijuar, tani krijojmë Reducers. Importojmë tipet e
funksioneve, krijojmë gjendjën fillestare dhe në bazë të tipit krijojmë reducer.
10. Pas krijimit të Reducers për secilën komponentë, duhet të krijojmë funksionet e
duhura për secilin shteg, ngjajshëm si në Back End. Por në Front End do të përdorim
Axios për të bërë HTTP kërkesa.
Procedura për të krijuar aksionet për një shteg të caktuar është si vijon: importojmë axios
dhe tipet për shtegun e caktuar nga fajlli types.js, dhe në fund krijohen funksionet për
HTTP kërkesat e nevojshme.
11. Procedura e fundit për shfrytëzimin e funksioneve të krijuara, është integrimi në
komponentet që kanë nevojë për ato funksione. Kjo bëhet fillimisht duke importuar
funksionin nga fajlli i caktuar në skedarin Actions, pastaj duhet ta shtojmë në metodën
PropTypes të komponentës, dhe së fundmi në funksionin connect që mundëson
ndërlidhjen e aksioneve/funksioneve me komponentën.
Pas përfundimit këtyre hapave, aplikacioni ynë do të duket si në figurat 7 deri 25.
Shtegu fillestar „/“, figura 7.
Figura 7. Pamje e faqes fillestare
-
36
Shtegu „/gallery“ për pamje të galerisë së restorantit, figura 8.
Figura 8. Pamje e galerisë së restorantit
Shtegu “/login” për kyçje në sistem, figura 9.
Figura 9. Pamje e formës për kyçje
Shtegu “/register” për regjistrim të klientëve, figura 10.
Figura 10. Pamje e formës për regjistrim
-
37
Shtegu “/error404” për informim që shtegu i kërkuar nuk ekziston, figura 11.
Figura 11. Pamje nga shtegu që nuk ekziston
Shtigjet e klientit:
Shtegu për porosi “/cart”, figura 12.
Figura 12. Pamja e parë për të bërë porosi
Shtegu “/checkout” hapi i fundit para bërjes së porosisë, figura 13.
Figura 13. Pamja finale per porosi
-
38
Shtegu “/reservation” për të bërë rezervim, figura 14.
Figura 14. Pamje e formës për të bërë rezervim
Shtegu “/profile” për shfaqje të profilit personal të klientit, figura 15.
Figura 15. Pamje nga profili personal i klientit
Shtegu “/myorders” për shfaqje të porosive të bëra nga klienti, figura 16.
Figura 16. Pamje nga porositë e bëra nga klienti
-
39
Shtegu “/myreservations” për shfaqje të rezervimeve të bëra nga klienti, figura 17.
Figura 17. Pamje nga rezervimet e bëra nga klienti
Shtigjet e punëtorit:
Shtegu “/dashboard” menyja kryesore për punëtorët, figura 18.
Figura 18. Pamje nga dashboard-i i punëtorit
Shtegu ”/eprofile” për paraqitje të profilit të punëtorit, figura 19.
Figura 19. Pamje nga profili personal i punëtorit
-
40
Shtegu “/employees” për shfaqje të të gjithë punëtorëve, figura 20.
Figura 20. Pamje nga lista e punëtorëve
Shtegu “/clients“ për të shfaqur listën e klientëve, figura 21.
Figura 21. Pamje nga shtegu për shfaqjen e listës së klientëve
Shtegu “/reservations“ për shfaqje të të gjitha rezervimeve, figura 22.
Figura 22. Pamje nga shtegu për shfaqjën e listës së të gjitha rezervimeve
-
41
Shtegu “/products“ për shfaqje të të gjitha produkteve, figura 23.
Figura 23. Pamje nga shtegu për shfaqjen e listës së të gjitha produkteve
Shtegu “/orders“ për të shfaqur listën e porosive të bëra nga klientët, figura 24.
Figura 24. Pamje nga shtegu për shfaqjen e listës së të gjitha porosive të bëra
Shtegu “/orders/:id“ për të shfaqur një porosi të caktuar, figura 25.
Figura 25. Pamje nga shtegu për shfaqjen e një porosie të caktuar
-
42
7. PËRFUNDIMI
Në këtë punim diplome është zhvilluar një web aplikacion për rezervime dhe porosi
online në restorant, duke shfrytëzuar gjuhën programuese Javascript dhe kornizat/libraritë
e saj.
Ky aplikacion ofron mundësinë e:
informimit rreth restorantit si dhe funksioneve që ofron aplikacioni;
regjistrimit dhe kyçjes në sistem
shikimit dhe ndryshimit të profilit personal;
bërjes së porosisë/rezervimit, shikimin/ndryshimin e porosive/rezervimeve të bëra
bërjes së rezervimit, shikimin e rezervimeve të bëra
regjistrimit/shikimit/ndryshimit/fshirjes së punëtorëve
regjistrimit/shikimit/ndryshimit/fshirjes së produkteve
shikimit të klientëve;
Aplikacioni është i lidhur me bazën e të dhënave ku ruhen të dhënat në kohë reale, si dhe
është i hostuar në platformën Heroku dhe është i çasshëm online përmes linkut
https://restapp-jh.herokuapp.com.
Së pari kemi filluar me gjuhët programuese, gjuhën programuese Javascript, dallimin në
mes të Front End-it dhe Back End-it, React dhe Redux për pamjën e përdoruesit,
MongoDB dhe Mongoose për menaxhimin e databazës dhe pyetësit, Node dhe Express
për pjesën e serverit. Pastaj kemi sqaruar llojet e kërkesave, dhe definimin e kërkesave
për sistemin tonë. Kemi krijuar bazën e të dhënave për sistemin tonë, dhe kemi sqaruar
arkitekturën e sistemit tonë. Dhe së fundmi kemi zhvilluar sistemin për rezervime, porosi
online në restorant.
-
43
REGJISTRI I TABELAVE
Tabela 1. Gjuhët programuese në bazë të kategorive [5] ................................................... 5
Tabela 2. Fjalët kyçe në Javascript [7]................................................................................. 7
Tabela 3. Përparësitë dhe mangësitë e ReactJS [16] ......................................................... 11
Tabela 4. Konceptet në MongoDB dhe SQL [11]............................................................. 13
Tabela 5. Dallimet në mes të NoSQL dhe SQL [11] ........................................................ 13
REGJISTRI I FIGURAVE
Figura 1. Skemë e Front End dhe Back End [6].................................................................. 5
Figura 2. Tri bërthamat e uebit ............................................................................................. 7
Figura 3. Skemë se si funksionon Redux-i [17] ................................................................ 12
Figura 4. Skemë se si funksionon uebfaqja ....................................................................... 23
Figura 5. Shtresat e sistemit tonë [18] ............................................................................... 23
Figura 6. Shtresat e pamjes së përdoruesit [19]................................................................. 24
Figura 7. Pamje e faqes fillestare ....................................................................................... 35
Figura 8. Pamje e galerisë së restorantit ............................................................................ 36
Figura 9. Pamje e formës për kyçje .................................................................................... 36
Figura 10. Pamje e formës për regjistrim .......................................................................... 36
Figura 11. Pamje nga shtegu që nuk ekziston ................................................................... 37
Figura 12. Pamja e parë për të bërë porosi ........................................................................ 37
Figura 13. Pamja finale per porosi ..................................................................................... 37
Figura 14. Pamje e formës për të bërë rezervim................................................................ 38
Figura 15. Pamje nga profili personal i klientit ................................................................. 38
Figura 16. Pamje nga porositë e bëra nga klienti .............................................................. 38
Figura 17. Pamje nga rezervimet e bëra nga klienti .......................................................... 39
Figura 18. Pamje nga dashboard-i i punëtorit ................................................................... 39
Figura 19. Pamje nga profili personal i punëtorit.............................................................. 39
Figura 20. Pamje nga lista e punëtorëve ............................................................................ 40
Figura 21. Pamje nga shtegu për shfaqjen e listës së klientëve ........................................ 40
Figura 22. Pamje nga shtegu për shfaqjën e listës së të gjitha rezervimeve .................... 40
Figura 23. Pamje nga shtegu për shfaqjen e listës së të gjitha produkteve...................... 41
Figura 24. Pamje nga shtegu për shfaqjen e listës së të gjitha porosive të bëra .............. 41
Figura 25. Pamje nga shtegu për shfaqjen e një porosie të caktuar ................................. 41
-
44
8. LITERATURA
1. Ian Sommerville, Software Engineering 10th edition, Pearson, 2013
2. Marijn Haverbeke, Eloquent Javascript 3rd edition, No Starch Press, 2018
3. Alex Banks and Eve Porcello, Learning React: Functional Web Development with
React and Redux, O’Reilly Media, 2017
4. Kylie Simpson, You don’t know JS Book Series, O’Reilly Media, 2015
5. https://medium.com/web-development-zone/a-complete-list-of-computer-
programming-languages-1d8bc5a891f, çasur në Prill 2020
6. https://flatironschool.com/blog/front-end-vs-back-end-development, çasur në Prill
2020
7. https://www.w3schools.com/js/js_reserved.asp, çasur në Prill 2020
8. https://www.w3schools.com/js/js_variables.asp, çasur në Prill 2020 9. https://mongoosejs.com/docs/further_reading.html çasur në Prill 2020
10. https://redux.js.org/introduction/getting-started çasur në Prill 2020
11. https://www.tutorialspoint.com/mongodb/index.htm çasur në Prill 2020
12. https://www.tutorialspoint.com/expressjs/index.htm çasur në Prill 2020
13. https://www.w3schools.com/nodejs/nodejs_intro.asp çasur në Prill 2020
14. https://www.geeksforgeeks.org/mern-stack/ çasur në Prill 2020
15. https://www.udemy.com/course/the-complete-javascript-course,çasur në Janar 2020
16. https://www.altexsoft.com/blog/engineering/the-good-and-the-bad-of-reactjs-and-
react-native/, çasur në Prill 2020
17. https://www.tutorialspoint.com/redux/redux_data_flow.htm, çasur në Prill 2020
18. https://www.mongodb.com/blog/post/the-modern-application-stack-part-1-
introducing-the-mean-stack, çasur në Prill 2020
19. https://blog.mgechev.com/2016/04/10/scalable-javascript-single-page-app-angular2-
application-architecture/, çasur në Prill 2020
https://medium.com/web-development-zone/a-complete-list-of-computer-programming-languages-1d8bc5a891fhttps://medium.com/web-development-zone/a-complete-list-of-computer-programming-languages-1d8bc5a891fhttps://flatironschool.com/blog/front-end-vs-back-end-developmenthttps://www.w3schools.com/js/js_reserved.asphttps://www.w3schools.com/js/js_variables.asphttps://mongoosejs.com/docs/further_reading.htmlhttps://redux.js.org/introduction/getting-startedhttps://www.tutorialspoint.com/mongodb/index.htmhttps://www.tutorialspoint.com/expressjs/index.htmhttps://www.w3schools.com/nodejs/nodejs_intro.asphttps://www.geeksforgeeks.org/mern-stack/https://www.udemy.com/course/the-complete-javascript-course/https://www.altexsoft.com/blog/engineering/the-good-and-the-bad-of-reactjs-and-react-native/https://www.altexsoft.com/blog/engineering/the-good-and-the-bad-of-reactjs-and-react-native/https://www.tutorialspoint.com/redux/redux_data_flow.htmhttps://www.mongodb.com/blog/post/the-modern-application-stack-part-1-introducing-the-mean-stackhttps://www.mongodb.com/blog/post/the-modern-application-stack-part-1-introducing-the-mean-stackhttps://blog.mgechev.com/2016/04/10/scalable-javascript-single-page-app-angular2-application-architecture/https://blog.mgechev.com/2016/04/10/scalable-javascript-single-page-app-angular2-application-architecture/
1. Hyrja dhe motivimi2. Teknologjitë e shfrytëzuara per zhvillimin e sistemit2.1. Gjuhët programuese2.2. Dallimi në mes të termit Front End dhe Back End2.3. Gjuha programuese Javascript2.3.1. Sintaksa e gjuhës programuese Javascript
2.4. ReactJS dhe ReduxJS2.5. MongoDB dhe MongooseJS2.7. NodeJS dhe ExpressJS
3. Definimi i kërkesave funksionale dhe jo-funksionale4. Krijimi i bazës së të dhënave për rezervime online në restorant5. Arkitektura e sistemit6. Zhvillimi i sistemit të propozuar për rezervime online në restorant6.1. Krijimi i Back End-it6.2. Krijimi i Front End-it dhe lidhja me Back End
7. PËRFUNDIMIREGJISTRI I TABELAVE8. LITERATURA