RAZVOJ MOBILNE APLIKACIJE PREVOZ BLAGA3 ANDROID APP LINKS Aplikacija upravlja prevoze in pakete, ki...
Transcript of RAZVOJ MOBILNE APLIKACIJE PREVOZ BLAGA3 ANDROID APP LINKS Aplikacija upravlja prevoze in pakete, ki...
UNIVERZA V MARIBORU
FAKULTETA ZA ELEKTROTEHNIKO,
RAČUNALNIŠTVO IN INFORMATIKO
Jan Tovornik
RAZVOJ MOBILNE APLIKACIJE PREVOZ BLAGA
Diplomsko delo
Maribor, julij 2017
i
RAZVOJ MOBILNE APLIKACIJE PREVOZ BLAGA
Diplomsko delo
Študent: Jan Tovornik
Študijski program: Visokošolski študijski program
Računalništvo in informacijske tehnologije
Mentor: doc. dr. Matej Črepinšek, univ. dipl. inž. rač. In inf.
Lektorica: Barbara Ferčič, univ. dipl. slov. in soc. kulture
ii
iii
ZAHVALA
Zahvaljujem se mentorju doc. dr. Mateju
Črepinšku za pomoč pri opravljanju
diplomskega dela.
Zahvala gre tudi mojim domačim in
prijateljem za podporo, vzpodbudo, ideje
in potrpežljivost ob pisanju diplomskega
dela.
iv
Razvoj mobilne aplikacije Prevoz blaga
Ključne besede: android, mongodb, mobilna aplikacija, prevoz blaga
UDK: 621.397.7:656.073.1(043.2)
Povzetek: V zaključnem delu so predstavljeni programska oprema Android Lint, ki vam pomaga pri
pisanju pravilnejše in robustnejše kode, Android App Links oz. posebne povezave, ki
uporabnika privedejo do določene vsebine v aplikaciji, JavaScript izvajalsko okolje Node.js
in podatkovna baza MongoDB.
Omenjene tehnologije so uporabljene pri izdelavi aplikacije Prevoz blaga za pametne
telefone Android. Namenjena je ljudem, ki pogosto potujejo in naročajo oz. kupujejo prek
spleta. Celotni postopek izdelave in razvoja aplikacije smo tudi opisali v zaključnem delu.
v
The development of the mobile application Prevoz
blaga
Key words: android, mongodb, mobile application, prevoz blaga
UDK: 621.397.7:656.073.1(043.2)
Abstract: In the thesis, we presented programming software Lint, which helps you with writting your
code in the correct and more robust code, Android App Links which leads the user to a
certain content in the application, programming language Node.js with whom we built a
server/API (application programming interface) and MongoDB database with Mongoose.
We built the application Prevoz blaga for android smart phones, which is targeting the
people who often travel to places and the people who often buy things in online shops. The
whole process of making and developing the application was also described in the thesis.
vi
KAZALO VSEBINE
1 UVOD .......................................................................................................................................... 1
2 ANDROID LINT ........................................................................................................................... 3
2.1 Opis in delovanje ................................................................................................................ 3
2.2 Primer delovanja ................................................................................................................ 4
3 ANDROID APP LINKS .................................................................................................................. 6
3.1 Opis in delovanje ................................................................................................................ 6
3.2 Prednosti pred Deep Links ................................................................................................. 7
3.3 Implementacija ................................................................................................................... 7
3.3.1 Korak 1: Intent filtri za povezave ................................................................................ 8
3.3.2 Korak 2: Logika intent filtrov ...................................................................................... 9
3.3.3 Korak 3: Združitev aplikacije s spletno stranjo ........................................................... 9
3.3.4 Korak 4: Preizkus delovanja povezav ....................................................................... 10
3.4 Deljenje prevoz/paketov .................................................................................................. 11
4 NODE.JS .................................................................................................................................... 12
4.1 Opis delovanja in primeri uporabe ................................................................................... 13
5 PODATKOVNA BAZA ................................................................................................................ 17
5.1 MongoDB.......................................................................................................................... 18
5.2 Primer uporabe podatkovne baze MongoDB .................................................................. 19
5.3 Mongoose......................................................................................................................... 21
5.4 Primer uporabe shem in modelov Mongoose ................................................................. 23
6 RAZVOJ APLIKACIJE .................................................................................................................. 28
6.1 Načrtovanje ...................................................................................................................... 28
6.2 Zaledna aplikacija ............................................................................................................. 29
6.3 Uporabniški vmesnik ........................................................................................................ 33
7 SKLEP ........................................................................................................................................ 37
8 VIRI IN LITERATURA ................................................................................................................. 38
vii
KAZALO SLIK
Slika 1.1: Logotip Android [1] ............................................................................................................. 2
Slika 2.1: Ročni zagon Android Linta .................................................................................................. 4
Slika 2.2: Izbira datotek za pregled .................................................................................................... 4
Slika 2.3: Izgled napake ...................................................................................................................... 5
Slika 3.1: Seznam aplikacij za odpiranje povezav (DL) ....................................................................... 6
Slika 3.2: Mesto pripomočka App Links Assistant .............................................................................. 8
Slika 3.3: Povezava in poti za AAL ...................................................................................................... 8
Slika 3.4: Uspešen preizkus združitve ............................................................................................... 10
Slika 3.5: Primer povezave ............................................................................................................... 10
Slika 3.6: App Links Assistant ........................................................................................................... 11
Slika 4.1: logotip Node.js [6]............................................................................................................. 13
Slika 4.2: Pravilno delovanje strežnika Node.js ................................................................................ 14
Slika 4.3: Uspešno delovanje posodobljenega strežnika Node.js .................................................... 15
Slika 5.1: Logotip podatkovnih baz MariaDB in MySQL [8] .............................................................. 17
Slika 5.2: Logotip mLab [10] ............................................................................................................. 19
Slika 5.3: Zbirke v PB MongoDB ....................................................................................................... 20
Slika 5.4: Logotip MongoDB [12] ...................................................................................................... 21
Slika 6.1: Glavni zavihki .................................................................................................................... 33
Slika 6.2: Obrazec za prijavo ............................................................................................................. 35
Slika 6.3: Celoten prikaz paketa ....................................................................................................... 35
Slika 6.4: Logotip aplikacije v času nalaganja ................................................................................... 36
viii
KAZALO IZVORNE KODE
Izvorna koda 3.1: Logika za pridobitev ID-ja..................................................................................... 9
Izvorna koda 4.1: Primer enostavnega strežnika Node.js …………………………………………………………… 13
Izvorna koda 4.2: Primer enostavnega modula ………………………………………………………………..……….. 14
Izvorna koda 4.3: Primer posodobljenega strežnika Node.js ………………………………..……………………. 15
Izvorna koda 5.1: Primer dokumenta JSON ………………………………………………………………..……………… 18
Izvorna koda 5.2: Primer sheme mongoose ………………………………………………………………………………. 21
Izvorna koda 5.3: Ustvarjanje in izvažanje modela ………………..………………………………………………….. 22
Izvorna koda 5.4: Shema prevoza …………..………………………………………………………………………………… 23
Izvorna koda 5.5: Krmilnik prevoza ………………………………………………………………………………………….… 23
Izvorna koda 5.6: Ustvarjanje prevoza – zahteva post ……………….……………………………………………… 24
Izvorna koda 5.7: Pridobivanje vseh prevozov – zahteva get …………..………………………………………… 25
Izvorna koda 5.8: Pridobivanje določenega prevoza – zahteva get ………..………………………………….. 25
Izvorna koda 5.9: Urejanje prevoza – zahteva put …………….………………………………………………………. 26
Izvorna koda 5.10: Brisanje prevoza – zahteva delete …………………..…………………………………………… 27
Izvorna koda 6.1: Glava metode za pošiljanje zahteve ………………..………………………………………..…… 30
Izvorna koda 6.2: Celotna poenostavljena metoda za pošiljanje zahteve …………..……………………… 31
Izvorna koda 6.3: Preverjanje številk stanj ………………………………………………………………………………… 32
ix
UPORABLJENE KRATICE
AAL Android App Links
DL Deep Links/Deep Linking
XML Extensible Markup Language
JSON JavaScript Object Notation
HTML Hyper Text Markup Language
API Application Programming Interface
PB podatkovna baza
KB kilobajt
MB megabajt
GB gigabajt
CPU Central Processing Unit (procesor)
SSD Solid State Drive (disk za shranjevanje podatkov)
RAM Random Access Memory (pomnilnik)
ID identifikacijska številka
UV uporabniški vmesnik
1
1 UVOD
Dandanes živimo v svetu, ki je povezan, kot še nikoli. Eden izmed razlogov za to je uporaba
povezljivih naprav, ki se povečuje z ogromno hitrostjo. Govorimo predvsem o uporabi
osebnih računalnikov, tabličnih računalnikov, pametnih telefonov in internetu stvari. Med
temi napravami trenutno prevladujejo pametni telefoni, ki postajajo vedno bolj dostopni,
kompatibilni in preprosti za uporabo. Pri teh pa prevladuje operacijski sistem Android (Slika
1.1), zato smo se zanj tudi odločili narediti aplikacijo, saj bo tako dostopna večini
uporabnikov pametnih telefonov kot tudi tabličnih računalnikov. Na spletu najdemo na
tisoče različnih aplikacij, od preprostih iger do kompleksnih pripomočkov, ki nam na
različne načine olajšujejo življenje. Eden izmed tovrstnih pripomočkov je tudi naša
aplikacija, ki pripomore k nižanju stroškov in časa dobavnih rokov ter prevozov.
Aplikacijo smo izdelali z namenom, da določenim ljudem olajšamo stvari. Ti ljudje so
pogosto nakupovalci v spletnih trgovinah in vozniki daljših relacij. Aplikacija bi, kar se tiče
spletnih nakupovalcev, znižala dobavno ceno in/ali skrajšala dobavni rok paketa oz.
naročila, voznikom pa bi znižala, če ne povrnila, stroške prevozov, ki jih opravljajo.
Aplikacija se lahko uporablja na več načinov, in sicer kot:
iskalec prevozov: pred kratkim ste nekaj naročili v spletni trgovini in se vam zdi
dobavni rok predolg in/ali dobavna cena previsoka. V aplikaciji poiščete prevoz, ki
gre skozi kraj, v katerem je trgovina oz. skladišče za osebni prevzem naročila. Zaradi
izbranega prevoza bi vaša pošiljka prišla hitreje in/ali ceneje do vas;
ponudnik prevozov: čaka vas dolga relacija vožnje z avtom, v katerem imate nekaj
prostora. Ker stroški niso tako nedolžni (gorivo, cestnina …), ponudite prevoz v
aplikacijo, da opravite vlogo dobavitelja. Z opravljenim prevozom si vsaj delno, če
ne v celoti, povrnete stroške;
2
ponudnik naročil: pred kratkim ste nekaj naročili v spletni trgovini in se vam zdi
dobavni rok predolg in/ali dobavna cena previsoka. V aplikacijo ponudite naročilo
oz. paket, ki ga lahko mimoidoči prevozniki prevzamejo in vam ga dostavijo hitreje
in/ali ceneje kot običajni dobavitelji.
iskalec naročil: čaka vas dolga relacija vožnje z avtom, v katerem imate nekaj
prostora. Ker stroški niso tako nedolžni (gorivo, cestnina …), v aplikaciji poiščete
naročilo oz. paket, ki ga osebno prevzamete in dostavite lastniku ter si s tem vsaj
delno, če ne v celoti, povrnete stroške opravljenega prevoza.
V diplomski nalogi smo predstavili pomembnejše uporabljene tehnologije za razvoj
omenjene programske opreme. Predstavili smo:
programsko orodje Android Lint, ki nam pomaga pri pisanju pravilnejše in
robustnejše kode;
Android App Links, s pomočjo katerih lahko vsebino aplikacije delimo z drugimi
uporabniki;
JavaScript izvajalsko okolje Node.js s katerim smo zgradili zaledni sistem;
delo s podatkovno bazo MongoDB, ki hrani vse ključne podatke za aplikacijo;
celoten razvoj aplikacije, od načrtovanja do same implementacije ter izgleda.
Vsaka tehnologija je predstavljena z razlago in primeri, ki so bili obravnavani med razvojem
aplikacije.
Slika 1.1: Logotip Android [1]
3
2 ANDROID LINT
Pri razvijanju aplikacije smo si pomagali s programskim orodjem Android Lint [2].
2.1 Opis in delovanje
Programsko okolje Android Studio, v katerem smo razvijali aplikacijo, privzeto vsebuje
programsko opremo Android Lint, ta nam je pomagala pri pisanju varnejše in stabilnejše
kode. Dostopna ni samo v okolju Android Studio, temveč tudi v ukazni vrstici in v okolju
Eclipse ter IntelliJ.
Gre za orodje, ki v napisani kodi preverja potencialne hrošče in napake ter morebitne
nevšečnosti, ki vas lahko doletijo v nadaljnjem pisanju kode.
Nekaj primerov napak, na katere vas Android Lint opozori:
Varnost aplikacije (potrebna je zamenjava trenutnega elementa z novejšim
elementom, povišati ciljno verzijo SDK za novosti in posodobitve).
Nepravilna postavitev elementov, ki vpliva na zmogljivost in hitrost delovanja.
Problematične ikone/slike (podvojene ikone, ikona nima podane gostote, ikone
napačnih velikosti …).
Različne napake v datoteki Manifest.
Napake z uporabnostjo (polje za vnašanje besedila nima podanega tipa vnosa npr.
tekst/števila).
Napake z dostopnostjo (manjkajoči opis elementa, ročno napisane tekstovne
vrednosti).
Implementirane, vendar nikoli uporabljene stvari (rezervirana spremenljivka ali
metoda, ki se nikoli ne uporabi).
4
2.2 Primer delovanja
Čeprav Android Lint sproti opozarja na nepravilnosti, ne pomeni, da vas opozori na vse
možne napake.
Da smo ugotovili, kaj vse je prežalo na naš projekt, smo to storili z ročnim zagonom
programa (Slika 2.1). Uporabili smo naslednji način: v urejevalniku kode smo z desnim
klikom na miško odprli možnosti, med katerimi smo izbrali »Analyze« in nato »Inspect
Code…«.
Slika 2.1: Ročni zagon Android Linta
Nato smo izbrali, kaj vse se je pregledalo. Izbrali smo lahko celoten projekt, določene
module, datoteke, ki še niso bile naložene na GitHub, ali datoteke, izbrane po naši meri
(Slika 2.2).
Slika 2.2: Izbira datotek za pregled
5
Po končanem pregledu so se nam rezultati prikazali v oknu z naslovom »Inspection
Results«. Rezultati so bili sortirani po kategorijah, ki so jih predstavljale napake (Slika 2.3).
Kot smo že omenili, napako lahko predstavlja del kode ali celotna datoteka (določeni
razred, ki se nikoli ne uporabi, ali ikona/slika, ki ji manjkajo nekateri podatki ali pa se nikoli
ne uporabi).
Če je šlo za napako v kodi, se nam je ob kliku nanjo prikazal del kode, kjer se je napaka
nahajala. Ponudile so se nam tudi alternativne rešitve, ki smo jih lahko izbrali, da se je
napaka odpravila (dodajanje manjkajoče lastnosti, sprememba napačnih vrednosti, izbris
datoteke, ki se nikoli ne uporabi …).
Slika 2.3: Izgled napake
V večini primerov je ponujena alternativna rešitev najučinkovitejša rešitev za odpravo
napake.
6
3 ANDROID APP LINKS
Aplikacija upravlja prevoze in pakete, ki jih lahko preko povezav tudi delimo. Omenjene
funkcionalnosti lahko dosežemo z uporabo aplikacijskih povezav oz. Android App Links
(AAL) [3].
3.1 Opis in delovanje
AAL predstavlja hitrejši način odpiranja spletnih povezav, katerih domene so v vaši lasti.
Gre za vrsto povezav, ki vas ob izbiri nanje, privedejo do točno določene vsebine v aplikaciji.
Ta ideja oz. funkcija ni povsem nova, saj izvira iz že znane funkcije Deep Linking ali Deep
Links (DL) oz. v našem primeru Mobile Deep Linking. Ta deluje zelo podobno in se od AAL
razlikuje samo v eni funkcionalnosti, kar predstavlja tudi slabost, in sicer pri izbiri na
povezavo se pojavi dialog oz. seznam vseh aplikacij, s katerimi lahko odprete povezavo,
medtem ko se pri AAL odpre točno določena aplikacija.
Funkcija AAL je bila prvič izdana za Androidovo različico Marshmallow (Android M), zato
deluje na napravah z Androidovo različico 6.0 in višje. Če naprava uporablja prejšnjo
različico, se namesto AAL uporabi DL, kar pomeni, da se ob izbiri na povezavo vedno pokaže
seznam aplikacij (Slika 3.1), s katerega je treba izbrati aplikacijo, ki bo odprla izbrano
povezavo. Vendar kljub temu lahko prikazovanje seznama aplikacij ustavimo, in sicer da ob
izbiri želene aplikacije izberemo tudi možnost »Vedno« oz. »Always«, s katero povemo, naj
ob nadaljnjem odpiranju teh povezav izbere aplikacijo, ki ste jo izbrali nazadnje.
Slika 3.1: Seznam aplikacij za odpiranje povezav (DL)
7
3.2 Prednosti pred Deep Links
- Aplikacijam je omogočeno, da se samodejno prepoznajo kot privzeta aplikacija za
odpiranje določenih tipov povezav.
- Uporabljajo se povezave HTTP na strani, ki so pod našo domeno, zato nobena druga
aplikacija ne more uporabljati naših povezav. Eden od pogojev za uporabo AAL je
potrditev, da je podana stran v naši lasti.
- Če za prikaz podatkov uporabljamo tudi spletno stran in ob izbiri na povezavo
aplikacija ni nameščena, odpiranje povezave prevzame brskalnik, ki prikaže podatke
na spletni strani, saj povezave kažejo na enake podatke tako v aplikaciji, kot na
spletni strani.
- Čeprav aplikacija ni nameščena, jo lahko zaženemo s podporo Android Instant Apps
in pogledamo podatke.
- Aplikacijo in njeno vsebino lahko odpremo z izbiro na povezavo:
v mobilnem brskalniku na spletni strani Google,
v aplikaciji Google iskanje (Google Search),
v iskalnem oknu Androida in
skozi Google pomočnika (Google Assistant).
3.3 Implementacija
Implementacija AAL je lahko zahteven proces, zato je v okviru okolja Android Studio nastal
pripomoček »App Links Assistant«, ki stvar olajša, poenostavi in pohitri.
Pripomoček smo našli na orodni vrstici pod zavihkom »Tools« (orodja) z izbiro na »App Links
Assistant« (Slika 3.2).
8
Slika 3.2: Mesto pripomočka App Links Assistant
Na desni strani Android Studia se nam je odprl pripomoček, ta nam je prikazoval navodila
in korake, ki smo jim morali slediti (Slika 3.6).
3.3.1 Korak 1: Intent filtri za povezave
Pri prvem koraku smo dodali spletno stran, njene poti (prefix) in pri vsaki poti določili del
aplikacije (ang.: activity), ki se bo odprl ob izbiri na povezavo.
V našem primeru (Slika 3.3) smo dodali spletno stran »https://tovornik.github.io« in dve
poti. Ena pot je za prevoze, kjer se bo odprl del aplikacije, ki prikazuje celotni prevoz
(CelotniPrevoz.java). Druga pot je za pakete, kjer se bo odprl del aplikacije, ki prikazuje
celotni paket (Celotnipaket.java).
Ob dodajanju poti nam je Android Studio samodejno urejal in dopolnjeval datoteko
»AndroidManifest.xml« z vsemi potrebnimi podatki.
Slika 3.3: Povezava in poti za AAL
9
3.3.2 Korak 2: Logika intent filtrov
Pri drugem koraku smo dodali kodo/logiko (Izvorna koda 3.1) v tisti del aplikacije, ki se ob
izbiri povezave zažene. S to kodo smo dobili podatke iz izbrane povezave, v našem primeru
je to bil ID prevoza/paketa.
Izvorna koda 3.1: Logika za pridobitev ID-ja
S pomočjo pridobljenega ID-ja smo vedeli, katere podatke (kateri prevoz/paket) smo morali
prikazati.
Pri tem načinu odpiranja aplikacije smo morali upoštevati, da se zažene samo en del (en
activity) aplikacije, zato se podatki, ki smo jih morebiti prenesli iz starševskega activityja, ne
pridobijo.
3.3.3 Korak 3: Združitev aplikacije s spletno stranjo
Pri tretjem koraku smo združili oz. povezali aplikacijo in podano spletno stran (Slika 3.3).
Podati smo morali spletno stran, ID aplikacije oz. projekta in tip certifikata za preverjanje
pristnosti. Po podanih podatkih se nam je samodejno ustvarila datoteka (.json), ki je
vsebovala vse potrebne podatke (ime aplikacije, ime paketa oz. ID aplikacije, certifikat za
preverjanje pristnosti …) za pravilno ravnanje s povezavami.
To datoteko smo morali dodati na točno določeno mesto na spletni strežnik. Z dodajanjem
datoteke na spletno stran smo na neki način potrdili, da je spletna stran naša.
Ko je bila datoteka naložena, smo lahko s pripomočkom App Links Assistant preverili, ali
smo pravilno naložili datoteko (Slika 3.4). Zraven datoteke so se preverile še različne stvari.
Ena izmed teh je bila tudi varna povezava spletne strani (HTTPS). Če stran nima zahtevanega
certifikata za šifriran promet, preizkus pade in povezave AAL ne bodo delovale.
10
Slika 3.4: Uspešen preizkus združitve
3.3.4 Korak 4: Preizkus delovanja povezav
Četrti korak pripomočka App Links Assistant je namenjen preizkušanju povezav. Pojavilo se
nam je okence, v katerem je bila že vnaprej vnesena naša spletna stran, ki smo jo sami
dopolnili in izbrali gumb »Run Test« (zaženi preizkus). Ta je nato na emulatorju ali na
telefonu simuliral odpiranje povezave, ki smo jo podali.
Če uporabljamo napravo z Androidovo različico 6.0 ali višje, se mora aplikacija samodejno
zagnati, če pa uporabljamo napravo z manjšo različico, se mora pokazati seznam aplikacij
(Slika 3.1).
Slika 3.5: Primer povezave
Na zgornji sliki (Slika 3.5) vidimo primer povezave, ki je odprla aplikacijo, in sicer paket, ki
ustreza podanemu ID-ju. Domena je bila vedno enaka, medtem ko je lahko bila pot v našem
primeru prevoz ali paket in ID je bil za vsako povezavo drugačen (spreminjal se je glede na
to, katere podatke oz. kateri prevoz/paket smo hoteli prikazati).
Že pred testom se nam je pod okencem, v katerega smo podali povezavo, prikazalo
sporočilo, ali smo pravilno podali povezavo.
11
Slika 3.6: App Links Assistant
3.4 Deljenje prevozov/paketov
Vsak prevoz/paket ponuja možnost, da ga delimo. Povezavo, kot jo vidite na sliki (Slika 3.5),
lahko pridobimo, ko si ogledujemo celoten prevoz/paket, in sicer z izbiro na ikono deli ( )
[4]. Povezava se samodejno sestavi in kopira v odložišče.
12
4 NODE.JS
Node.js [5] (Slika 4.1) je odprtokodno okolje za zaganjanje kode JavaScript na strežniku
(ang.: server-side). Primarno je bil namenjen za pisanje skript na strani odjemalca (ang.:
client-side), ki so bile vgrajene v spletnih straneh HTML, ki jih je poganjal JavaScript Engine
v brskalnikih. Sedaj pa se večinoma uporablja za pisanje skript na strani strežnika, kjer
ustvarja dinamične spletne strani oz. vsebino.
Največja razlika med Node.js in PHP je ta, da funkcije PHP zablokirajo, ko čakajo na
odgovor/rezultat, medtem ko funkcije Node.js ne zablokirajo, ker se izvedejo paralelno,
nato pa se odgovor čaka ter zazna prek klicev, ki so neodvisni od delovanja aplikacije.
Zraven programskega jezika JavaScript Node.js uporablja tako imenovane module, ki
predstavljajo različne osnovne funkcionalnosti. Uporabljajo se za podatkovne pretoke,
kriptografske funkcije, binarne podatke, vhodne in izhodne ukaze datotečnih sistemov,
upravljanje internetnih mrež,… Vsi moduli pa uporabljajo aplikacijski programski vmesnik
(API), saj s tem znižajo kompleksnost pisanja strežniških aplikacij.
Node.js ima dogodkovno temelječo arhitekturo, ki je zmožna hkrati (asinhrono) spremljati
oz. opravljati vhodne in izhodne ukaze. Ta način sestave omogoča zelo dobro podlago
zahtevnim spletnim igram.
Skripte Node.js se lahko zaganjajo na operacijskih sistemih Windows, Linux, Mac, NonStop
in na strežnikih Unix.
Čeprav kratica .js v imenu »Node.js« pomeni končnico datotek, ki so napisane s kodo
JavaScript, nima v imenu popolnoma nobene zveze s programskim jezikom JavaScript.
Kratica .js je preprosto del celotnega imena.
Node.js je napisal Ryan Dahl leta 2009. Navdih je dobil, ko je na Flickrju videl animacijo, ki
predstavlja napredek nalaganja datoteke (ang.: progress bar), ta pa ni vedela, koliko deleža
datoteke se je že preneslo na strežnik, in je moral delati dodatne poizvedbe, da je bil na
13
tekočem z napredkom nalaganja. Ryan si je takrat zaželel lažji način spremljanja napredka
in začel ustvarjati okolje Node.js.
Slika 4.1: logotip Node.js [6]
4.1 Opis delovanja in primeri uporabe
Za uporabo, smo si morali najprej prenesti Node.js in ga naložiti na računalnik. Nato smo
lahko preverili, ali se je Node.js uspešno naložil. Za preverjanje smo uporabili terminal in
vanj podali ukaz »node -v« (-v predstavlja različico (ang.: version)) ter ga potrdili s tipko
Enter. Če se je izpisala številka (različica), se je Node.js uspešno namestil.
Za najenostavnejši primer smo najprej ustvarili eno datoteko s končnico .js. Vanjo smo
prekopirali in shranili naslednjo kodo:
Izvorna koda 4.1: Primer enostavnega strežnika Node.js
14
Kratek opis delovanja pravkar napisane skripte: gre za strežnik, ki posluša na vratih 8080.
Kdorkoli dostopa na ta vrata v času delovanja strežnika se mu izpiše sporočilo
»Pozdravljeni!«.
Datoteke Node.js se zaženejo s pomočjo terminala, zato smo spet odprli terminal in se
pomaknili na mesto, kamor smo shranili našo datoteko s strežnikom. Program smo zagnali
z ukazom »node ime_datoteke.js« in s tem je začel računalnik delovati kot strežnik. Da smo
preverili delovanje strežnika, smo v brskalniku odprli naslov »localhost:8080«, in če je
strežnik deloval pravilno (Slika 4.2), je moral izpisati sporočilo, ki smo ga navedli v skripti
(»Pozdravljeni!«).
Slika 4.2: Pravilno delovanje strežnika Node.js
Kot smo že omenili, Node.js uporablja module [7] za njegovo funkcionalnost. Za lažjo
predstavo: pri Node.js-u moduli igrajo enako vlogo kot knjižnice v JavaScript-u ali v
programskem jeziku Java. Moduli se v skripto vključijo s funkcijo »require()« (slo.: pridobi).
Če se vrnemo nazaj na skripto (Izvorna koda 3.1), lahko v prvi vrstici vidimo
zahtevo/pridobitev/vključitev modula HTTP, na podlagi katerega smo lahko nato s funkcijo
»createServer()« ustvarili strežnik.
Ustvarimo lahko tudi svoje module, ki jih nato vključimo v skripte. Izdelali smo enostaven
modul (Izvorna koda 4.2), ki vrne trenuten čas in datum, ter ga shranili na enako mesto kot
strežnik:
Izvorna koda 4.2: Primer enostavnega modula
15
Ustvarili smo funkcijo »trenutenCasInDatum«, ki smo jo izpeljali iz besede »exports«, kar
je naredilo funkcijo dostopno drugim datotekam, med katerimi je bila tudi naša skripta s
strežnikom.
Za vključitev našega modula smo uporabili funkcijo »require()« na enak način, kot smo jo
uporabili za modul HTTP. Modul smo nato uporabili za klicanje funkcije, ki je vrnila trenutni
čas in datum.
Izvorna koda 4.3: Primer posodobljenega strežnika Node.js
Skripto smo zagnali v terminalnem oknu in v brskalniku odprli naslov »localhost:8080«, ki
nam je ob pravilnem delovanju vrnil pozdrav in trenutni datum ter čas.
Slika 4.3: Uspešno delovanje posodobljenega strežnika Node.js
Kot vidimo na sliki (Slika 4.3), je strežnik izpisal celoten zahtevani tekst, kar pomeni, da je
deloval pravilno.
16
Kratek opis delovanja posamezne vrstice skripte posodobljenega strežnika (Izvorna koda
4.3):
- 1. in 2. vrstica vključita HTTP in naš modul (./ pred imenom modula pomeni, da je
datoteka shranjena na enakem mestu kot ta skripta),
- 4. vrstica ustvari strežnik s funkcijo, ki sprejme zahtevo in odgovor,
- 5. vrstica poda statusno kodo 200 (OK) in tip teksta, ki bo prikazan, v našem primeru
navaden tekst,
- 6. in 7. vrstica izpišeta tekst (7. tudi pokliče funkcijo našega modula, ki vrne tekst),
- 8. vrstica zaključi zahtevo (lahko bi tudi kaj izpisala tako kot v prvem primeru
(Izvorna koda 4.1)),
- in zadnja, 9. vrstica pove strežniku, na katerih vratih mora poslušati.
Kljub temu da smo naš API za aplikacijo Prevoz blaga, napisali v Node.js, je opisan v
naslednjem poglavju, in sicer pod podpoglavjem Mongoose.
17
5 PODATKOVNA BAZA
Izbira podatkovne baze ni enostaven proces, saj je treba vedeti vrsto in velikost podatkov,
pogostost njihovega shranjevanja, način in pogostost branja podatkov in drugo.
Npr. vedeti smo morali, kakšne vrste/tipe podatkov bomo shranjevali (tekst, številke,
datoteke, binarna zaporedja, datumi, slike, posnetki itd.), kako pogosto se bodo zahteve
izvajale na podatkovni bazi (PB) (redko, pogosto, zelo pogosto), kako obširne bodo te
zahteve (če gre za tekst in številke, je velikost nekaj KB, če pa gre za sliko/-e ali posnetke,
je lahko velikost nekaj MB/GB) itd.
V našem primeru smo shranjevali dve vrsti podatkov:
- Tekstovni podatki (podatki uporabnikov, prevozov in paketov), pri čemer smo
izbrali podatkovno bazo MongoDB.
- Slike (prevoz/paket lahko ima svojo sliko), pri čemer smo izbrali podatkovno bazo
MariaDB (alternativa MySQL) (Slika 5.1).
Slika 5.1: Logotip podatkovnih baz MariaDB in MySQL [8]
18
5.1 MongoDB
MongoDB [9] (Slika 5.4) je odprtokodna, dokumentno orientirana podatkovna baza,
napisana za več platform, kot so operacijski sistem Windows, Linux, operacijski sistem X,
Solaris in FreeBSD. Gre za podatkovno bazo NoSQL, ki za shranjevanje podatkov uporablja
dokumente JSON (Izvorna koda 5.1) s shemami.
Izvorna koda 5.1: Primer dokumenta JSON
Nekaj razlik med podatkovnimi bazami SQL in NoSQL:
- Shranjevanje podatkov: SQL PB uporablja tabele, medtem ko NoSQL PB uporablja
dokumente.
- SQL PB uporablja že v naprej določene sheme, NoSQL PB pa uporablja dinamične
sheme.
- SQL PB je vertikalno razširljiva (več ko je podatkov, višja je tabela), medtem ko je
NoSQL PB horizontalno razširljiva (več ko je podatkov, daljši je dokument).
- Poraba virov: SQL PB se poveča in pohitri z dodajanjem strojne opreme (CPU, SSD,
RAM …), NoSQL PB pa potrebuje samo več virov (strežnikov), da se zmanjša
obremenitev.
- Primeri PB:
SQL: MySQL, Sqlite, MS-SQL, Oracle, PostgreSQL …
NoSQL: MongoDB, Redis, Cassandra, CouchDb, BigTable, RavenDb …
19
- Količina podatkov: SQL PB ni priporočljiva za shranjevanje ogromnih količin
podatkov, medtem ko je NoSQL zelo priporočljiva za ogromne količine podatkov, saj
ji dokumentna orientiranost to omogoča (shranjevanje podatkov v dokumente).
5.2 Primer uporabe podatkovne baze MongoDB
Za uporabo PB MongoDB smo imeli dve možnosti:
- MongoDB si prenesemo iz uradne spletne strani (www.mongodb.com) in jo
naložimo na računalnik.
- Obiščemo uradno spletno stran ponudnika MongoDB gostovanj, mLab [15] (Slika
5.2), ki zastonj ponuja in globalno gostuje PB MongoDB.
Slika 5.2: Logotip mLab [10]
Po namestitvi MongoDB na računalnik smo odprli terminalno okno in z ukazom »mongo –
version« preverili, ali je bila ta uspešna.
Po uspešni namestitvi smo ustvarili PB. V terminalnem oknu smo podali ukaz »mongo«, s
katerim smo zagnali ukazno lupino v MongoDB (orodje za delo s PB).
Osnovni ukazi ukazne lupine MongoDB (shell):
- show dbs – izpis že obstoječih PB,
- use ime_PB – pomakne se v podano PB, če pa ne obstaja, se ustvari nova,
- db – preveri, v kateri PB smo trenutno,
20
- db.createUser({ user : 'uporabniško_ime', pwd : 'geslo', roles : [ 'readwrite',
'dbAdmin' ]}); – ustvari uporabnika administratorja, s katerim podajamo ukaze,
- show collections – izpis vseh zbirk v trenutni bazi,
- db.createCollection('ime_zbirke'); – ustvari zbirko,
- db.ime_zbirke.insert({ 'ime' : 'Jan', 'priimek' : 'Tovornik' }); – vstavi podatek v zbirko,
- db.ime_zbirke.find(); – izpis vseh podatkov zbirke,
- db.ime_zbirke.find({ ime : 'Jan' }); – izpis tistih podatkov, ki imajo vrednost 'Jan' pri
ključu 'ime',
- db.ime_zbirke.find().
pretty() – preglednejši izpis podatkov
sort() – sortirani izpis podatkov
count() – izpiše številko podatkov
limit() – omeji število izpisanih podatkov
forEach() – gre čez vsaki vrnjeni podatek,
- db.ime_zbirke.update({ ime : 'Jan' }, { ime : 'Janez', priimek : 'Novak' }); – podatkom,
ki imajo vrednost 'Jan' pri ključu 'ime', spremeni 'ime' v 'Janez' in 'priimek' v 'Novak'
in
- db.ime_zbirke.remove({ ime : 'Jan' }); – izbriše podatke, ki imajo vrednost 'Jan' pri
ključu 'ime'.
Zbirke (ang.: collections) so kot tabele v relacijskih PB (SQL). Vsaka zbirka vsebuje
dokumente. V našem primeru (Slika 5.3) je imela PB, ki je dostavljala podatke aplikaciji
Prevoz blaga, tri zbirke (uporabnike, prevoze in pakete) in vsaka je vsebovala dokumente
(primer: podatki enega prevoza so bili shranjeni v enem dokumentu).
Slika 5.3: Zbirke v PB MongoDB
21
Na sliki (Slika 5.3) vidimo imena in trenutno število dokumentov vsake zbirke.
Zgoraj navedeni ukazi so nekateri izmed osnovnih ukazov za delo s PB MongoDB v ukazni
lupini. V uradni dokumentaciji je ukazov veliko več, vendar so zgoraj navedeni med
najpomembnejšimi in najuporabnejšimi.
Slika 5.4: Logotip MongoDB [12]
5.3 Mongoose
Za lažje in enostavnejše delo s PB MongoDB in Node.js se priporoča namestitev modula
Mongoose [16]. Gre za vrsto objektno orientiranega modula, ki nam olajša delo pri pisanju
skript Node.js.
Vse se začne s shemami. Vsaka shema kaže na določeno zbirko v MongoDB in določi obliko
dokumenta te zbirke (Izvorna koda 5.2).
Izvorna koda 5.2: Primer sheme mongoose
22
Shema je sestavljena iz enega ali več ključev. V našem primeru (Izvorna koda 5.2) je imela
shema štiri ključe: »uporabnisko_ime«, »starost«, »student« in »sport«. Vsak ključ ima
svoje lastnosti, na primer ključ »starost« je bil tipa »Number« oz. numeričnega tipa in je
imel spodnjo (0) ter zgornjo (120) mejo vrednosti.
Dovoljeni tipi vrednosti ključev v shemah:
- String (tekst),
- Number (slo.: število),
- Date (slo.: datum),
- Boolean (true/false),
- Array (slo.: polje),
- Mixed (mešane vrednosti),
- Buffer,
- ObjectId.
Kot smo že omenili, s shemo podamo strukturo dokumenta določeni zbirki. Zgornja shema
je podajala, da je moral uporabnik pri podajanju starosti zapisati numerično vrednost
(številko), ki ni bila manjša od 0 in ni bila večja od 120.
Za uporabljanje naše sheme smo jo morali najprej spremeniti v model, s katerim smo lahko
delali. Model smo prav tako izvozili in ga s tem naredili dostopnega drugim skriptam
(Izvorna koda 5.3).
Izvorna koda 5.3: Ustvarjanje in izvažanje modela
V nadaljevanju sta opisana delo in način uporabe naših modelov, ki so del projekta. Za lažjo
in preprostejšo razlago smo jih malo poenostavili (celotni postopek: [11]).
23
5.4 Primer uporabe shem in modelov Mongoose
Za delo z izvoženimi modeli smo ustvarili tako imenovane krmilnike (ang.: controllers), s
katerimi smo izvajali operacije/zahteve nad PB.
Za primer smo izbrali shemo (Izvorna koda 5.4) in krmilnik (Izvorna koda 5.5) prevoza:
Izvorna koda 5.4: Shema prevoza
Izvorna koda 5.5: Krmilnik prevoza
Enostavna razlaga skripte krmilnika prevoza (Izvorna koda 5.5):
- 1. vrstica vključi modul »express«, iz katerega nato, 2. vrstica, pridobi usmerjevalnik
»router«, ki služi kot »poslušalec« povezav/zahtev, na katere se tudi odziva.
- 3. vrstica vključi modul »body-parser«, na katerega se, v 4. vrstici, poveže
usmerjevalnik »router«.
- 5. vrstica pridobi model, ki smo ga iz sheme ustvarili ter izvozili. Shrani se v
spremenljivko, s katero smo lahko nadalje delali.
24
V krmilniku so bile vse metode, ki smo jih navedli pri delu z ukazno lupino v MongoDB.
Ustvarili smo metode za ustvarjanje prevozov, pridobivanje določenega ali vseh prevozov,
urejanje prevozov in njihovo brisanje.
Metode so se prožile glede na vrsto zahteve. Zahteve, ki jih je aplikacija pošiljala strežniku
(API) oz. krmilniku, so bile zahteve HTTP in so lahko bile tipa »post« (ustvarjanje prevoza),
»get« (pridobivanje prevoza), »put/update« (urejanje prevoza) in »delete« (brisanje
prevoza). V krmilniku je zahteve prepoznal usmerjevalnik »router«, ki je na podlagi vrste
zahteve prožil določene metode.
- Ustvarjanje prevoza
Zahteva tipa »post« (Izvorna koda 5.6), ki v poti (povezava) nima podanih
lastnosti/podatkov. Prožila se je funkcija »create«, ki je kot parametre sprejela
podatke prevoza, ki smo ga ustvarjali, in funkcijo, ki se je prožila ob enakem času in
vrnila uspeh zahteve. Vse potrebne podatke za ustvarjanje prevoza smo pridobili iz
telesa zahteve, ki jih je pridobil prvi parameter, prve funkcije, »req«. Druga funkcija
nam je ob uspešni zahtevi vrnila prevoz, ki smo ga pravkar ustvarili, ob neuspešni
zahtevi pa je prikazala sporočilo o napaki.
Izvorna koda 5.6: Ustvarjanje prevoza – zahteva post
25
- Pridobivanje vseh prevozov
Zahteva tipa »get« (Izvorna koda 5.7), ki v poti (povezava) nima podanih
lastnosti/podatkov. Prožila se je metoda »find«, ki je kot parameter sprejela
funkcijo, ki se je prožila ob enakem času in nam ob uspešni zahtevi vrnila seznam
prevozov, ob neuspešni zahtevi pa je prikazala sporočilo o napaki.
Izvorna koda 5.7: Pridobivanje vseh prevozov – zahteva get
- Pridobivanje določenega prevoza
Zahteva tipa »get« (Izvorna koda 5.8), ki v poti (povezava) vsebuje ID
(identifikacijsko številko) prevoza, ki smo ga pridobivali. Prožila se je metoda
»findById«, ki je kot parameter sprejela ID prevoza, ki smo ga pridobili iz povezave,
in funkcijo, ki se je prožila ob enakem času in nam ob uspešni zahtevi vrnila zahtevan
prevoz, ob neuspešni zahtevi pa je prikazala sporočilo o napaki.
Izvorna koda 5.8: Pridobivanje določenega prevoza – zahteva get
Na enak princip so se pridobivali prevozi glede na druge podatke. Namesto ID
prevoza smo podali kraj odhoda, kraj prihoda ali datum prevoza.
26
- Urejanje prevoza
Zahteva tipa »put« (Izvorna koda 5.9), ki v poti (povezava) vsebuje ID prevoza, ki
smo ga urejali. Prožila se je metoda »findByIdAndUpdate«, ki je sprejela naslednje
parametre:
1. parameter: ID prevoza, ki smo ga pridobili iz povezave,
2. parameter: podatki prevoza, ki smo jih spreminjali. Pridobili smo
jih iz telesa zahteve, ki ga je pridobil prvi parameter, prve funkcije,
»req«.
3. parameter: vrednost boolean. Če je bila ta vrednost »true« in
metoda »findByIdAndUpdate« ni našla prevoza z ID-jem v 1.
parametru, se je ustvaril novi prevoz s podanimi vrednostmi v 2.
parametru.
4. parameter: funkcija, ki se je prožila ob enakem času in nam vračala
uspeh poslane zahteve.
Ob uspešni zahtevi nam je funkcija v 4. parametru, vrnila urejen prevoz, ob
neuspešni zahtevi pa prikazala sporočilo o napaki.
Izvorna koda 5.9: Urejanje prevoza – zahteva put
27
- Brisanje prevoza
Zahteva tipa »delete« (Izvorna koda 5.10), ki v poti (povezava) vsebuje ID prevoza,
ki smo ga brisali. Prožila se je metoda »findByIdAndRemove«, ki je kot parametra
sprejela ID prevoza, ki smo ga pridobili iz povezave, in funkcijo, ki se je prožila ob
enakem času in nam je ob uspešni zahtevi vrnila sporočilo o uspešnem brisanju, ob
neuspešni zahtevi pa prikazala sporočilo o napaki.
Izvorna koda 5.10: Brisanje prevoza – zahteva delete
Vsi našteti scenariji so bili izpeljani iz usmerjevalnika »router«, ki je bil na koncu skripte
izvožen in tako dostopen drugim skriptam.
Predstavili smo krmilnik prevozov, ki je prikazoval princip/način delovanja krmilnikov
(krmilnik paketov in krmilnik uporabnikov delujeta na enak način).
Vsi ti krmilniki s svojimi metodami so bili združeni v eno glavno datoteko/skripto, v kateri
so bili zraven vključitve krmilnikov podani še drugi pomembni in občutljivi podatki, kot so
povezava na MongoDB PB, vrata (port), kjer so se poslušale zahteve, vključitve modulov,
itd. Ti podatki kot celota so predstavljali strežnik (API).
Naloga strežnika je usmerjanje prometa in posredno povezovanje uporabnikov (aplikacij) s
podatki (PB), kar smo pravkar pokazali s krmilniki in shemami.
28
6 RAZVOJ APLIKACIJE
Aplikacija se deli na dve večji kategoriji, in sicer na uporabniški vmesnik aplikacije (front-
end) in na zaledje aplikacije oz. strežniški del (back-end). Pred začetkom razvoja je bilo treba
izdelati načrt, kjer smo povezali vse komponente in podatke v celoto. Načrt predstavlja
strukturo aplikacije, po kateri se ravnamo v nadaljnjem razvoju.
V našem primeru smo se najprej lotili izdelave PB, nato strežnika in na koncu aplikacije.
6.1 Načrtovanje
Pred vsakim razvojem je treba najprej izdelati načrt poteka izdelave, ki se ga držimo med
celotnim razvijanjem.
Najprej smo si zastavili osnovno vprašanje: Kaj bo naša aplikacija delala?. Tako smo pridobili
naloge posameznega področja:
- Aplikacija kot celota:
Povezovala bo ljudi, ki opravljajo prevoze in iščejo naročila, ter ljudi, ki iščejo
prevoze in objavljajo naročila.
- Podatkovna baza:
Hranila in posredovala bo podatke o ljudeh (uporabnikih), o prevozih, ki jih
opravljajo uporabniki, in o paketih/naročilih, ki jih objavljajo uporabniki. Tako smo
dobili uporabnike, prevoze in pakete, ki so predstavljali »entitete« oz. v našem
primeru zbirke (MongoDB).
- Strežnik:
Posredno bo povezoval aplikacijo in PB. Pridobival bo zahteve od aplikacije, ki jih bo
izvrševal nad PB. V imenu aplikacije bo manipuliral s podatki zbirk v PB.
Manipuliranje je v tem primeru pomenilo iskanje, prikazovanje, dodajanje, urejanje
in brisanje podatkov, ki so predstavljali glavne funkcije strežnika.
29
- Uporabniški vmesnik:
Pomeni posrednika med uporabnikom in strežnikom. Za uporabniški vmesnik so
veljale enake funkcije kot za strežnik, vendar glavno vlogo je predstavljalo pravilno
in varno pridobivanje in prikazovanje podatkov ter izvrševanje zahtev na strežnik.
Uporabniški vmesnik mora biti pregleden in jasen, da uporabnika ne zmedemo in
privedemo v nerodne situacije. Omogočati mora vse zgoraj naštete funkcije za
upravljanje podatkov.
6.2 Zaledna aplikacija
Zaledje rešitve predstavljajo PB in strežnik, ki smo ju opisali v prejšnjem poglavju
(PODATKOVNA BAZA), ter koda/logika uporabniškega vmesnika aplikacije.
Logika uporabniškega vmesnika je vsebovala precej metod, ki so skrbele za pravilno
delovanje aplikacije.
Spodaj naštete metode so bile nekatere izmed najbolj uporabljenimi ter
najpomembnejšimi. Gre za metode, ki so:
- preverjale, ali so bili pri dodajanju prevoza/paketa podani vsi obvezni podatki,
- venomer preverjale stanje strežnika,
- pošiljale zahteve na strežnik,
- povezovale elemente uporabniškega vmesnika s kodo v ozadju,
- prikazovale podatke na zaslon,
- shranjevale stanje aplikacije,
- sproti posodabljale elemente prikaza,
- sporočale uporabniku o uspehih/napakah,
- povezovale aplikacijo s strežnikom,
- prenašale slike s PB itd.
Opisali smo najpomembnejšo in najbolj uporabljeno metodo: pošiljanje zahteve na
strežnik. Brez te metode bi bila aplikacija neuporabna, saj ne bi imela ničesar prikazati.
30
Za pošiljanje zahtev smo uporabili knjižnico »AsyncHttpClient« [13], s pomočjo katere smo
nato ustvarili objekt in z njim pošiljali zahteve. Metoda za pošiljanje zahtev sprejme 3
parametre, in sicer:
- 1. parameter: pot (povezava), ki je bila v našem primeru pot do katere od zbirk (če
smo ciljali na točno določeni dokument, smo njegov ID pridobili iz te poti),
- 2. parameter: parametri zahteve
če smo pridobivali celotno zbirko ali če smo dokument brisali,
parametrov ni bilo,
če smo pridobivali več točno določenih dokumentov, so bili
parametri podatki, po katerih smo dokumente sortirali,
če smo dokument urejali ali dodajali, so bili parametri podatki, ki smo
jih posodabljali/dodajali,
- 3. parameter: funkcija, ki je preverjala rezultat poslane zahteve.
Izvorna koda 6.1: Glava metode za pošiljanje zahteve
Zgornja koda (Izvorna koda 6.1) prikazuje metodo za pošiljanje zahteve. Naloga te metode
je vračanje določenega prevoza, katerega ID je bil podan v prvem parametru.
Kot vidimo, je za prvi parameter sprejela pot, ki je bila sestavljena iz glavne poti do
strežnika, iz zbirke prevozov in iz ID prevoza. Za drugi parameter ni sprejela nobenih
podatkov (parametrov zahteve), le vrednost »null«, ki predstavlja prazno vrednost. Za tretji
parameter pa je sprejela metodo za preverjanje rezultatov zahteve.
Funkcija, ki je bila zadolžena za poslušanje in sprejemanje rezultatov zahteve, se je delila
na dve manjši funkciji, in sicer na »onSuccess()«, ki se je prožila ob uspešni zahtevi, in na
»onFailure()«, ki se je prožila ob neuspešni zahtevi.
31
Izvorna koda 6.2: Celotna poenostavljena metoda za pošiljanje zahteve
Zgornja koda (Izvorna koda 6.2) prikazuje zelo poenostavljen način pošiljanja zahteve. Vsi
tipi zahtev so bili napisani po enakem principu.
Zahteve so se običajno pošiljale ob izbiri na gumb »dodaj«, »shrani«, »briši«, »preglej« itd.,
pri čemer je šlo za delo z dokumenti zbirk (prevozi, paketi in uporabniki).
Pred pošiljanjem zahtev se je v večini primerov zagnala in prikazala tudi animacija, ki je
predstavljala obravnavanje zahteve. Istočasno se je zagnal tudi odštevalnik, ki je skrbel, da
uporabniki ne bi za vedno obtičali pri animaciji. Odštevalnik je preprečeval neskončna
nalaganja zahtev, ki so se največkrat pojavila, ko je imela naprava slabo internetno
povezavo. Takrat se je zahteva lahko izgubila na poti do strežnika ali na poti nazaj do
aplikacije in tako animacija nalaganja nikoli ne bi izginila. Ta scenarij je preprečeval
odštevalnik, saj je prekinil zahtevo po določenem intervalu.
32
Ob uspešni zahtevi smo najprej prekinili odštevalnik in skrili animacijo nalaganja ter
prikazali pridobljene rezultate (v našem primeru pridobljeni prevoz).
Ob neuspešni zahtevi smo isto kot prej najprej prekinili odštevalnik in skrili animacijo
nalaganja, nato pa izpisali obvestilo o napaki. Funkcija »onFailure()« je sprejela tudi
parametre, s pomočjo katerih smo lahko zaznavali vrsto napake (vrnila se je številka stanja
(ang.: statusCode) [14]).
Vrnile so se samo številke stanj med 400 in 499 (vključno z njima). Pomen in razlaga
nekaterih številk stanja:
- 400 – strežnik ni mogel ali ni hotel sprejeti zahteve zaradi napake (npr.: napačno
podani parameter: zahtevan je numerični tip, poslan pa je bil tekstovni tip),
- 401 – uporabnik ni podal zahtevanih podatkov za preverjanje pristnosti (ni podal
uporabniškega imena in/ali gesla),
- 403 – zahteva je bila pravilna, vendar je strežnik ni mogel ali ni hotel sprejeti, ker
uporabnik morda ni imel zahtevanih pravic ali pa je potreboval neke vrste račun,
- 404 – vsebina ne obstaja (npr.: prevoza, ki ga iščemo, ni v PB),
- 405 – nedovoljena metoda/tip zahteve (zahtevan je tip »post«, poslan pa je bil tip
»get«) …
Zaradi različnih številk stanj smo jih v funkciji »onFailure()« preverjali in na podlagi številke
izpisali določena opozorila (Izvorna koda 6.3), da smo dali uporabniku vsaj približno vedeti,
kaj je sprožilo napako.
Izvorna koda 6.3: Preverjanje številk stanj
33
6.3 Uporabniški vmesnik
Kot smo omenili na začetku tega poglavja, je bila glavna naloga UV pravilno pridobivanje
podatkov od uporabnika in z njimi pošiljati zahteve.
Ker je moral biti UV pregleden, smo za izgled izbrali kombinacijo le dveh barv, in sicer bele
in modre s črno pisavo.
UV je sestavljen iz treh glavnih zavihkov (ang.: tabs) (Slika 6.1): iz zavihka za iskanje
prevozov in paketov, iz zavihka za prikazovanje svojih paketov in prevozov ter iz zavihka za
pregled in urejanje profila uporabnika.
Slika 6.1: Glavni zavihki
Opis in razlaga glavnih zavihkov:
- Iskanje:
Na tem zavihku se izvaja iskanje prevozov in paketov. Iskanje lahko filtriramo s
podajanjem krajev in datuma. Ob zadetkih se prikažejo zahtevani prevozi/paketi in
število le-teh. Prikazani prevozi/paketi ne prikazujejo vseh njihovih lastnosti. Za
celoten ogled določenega prevoza/paketa je treba izbrati dotičnega (Slika 6.3).
34
- Moje objave:
Na tem zavihku imamo pregled nad svojimi objavami. Vidimo lahko vse naše
prevoze in pakete, ki smo jih v preteklosti dodali in še niso bili obravnavani. Prikazani
prevozi/paketi ne prikazujejo vseh njihovih lastnosti. Za celoten ogled določenega
prevoza/paketa je treba izbrati dotičnega (Slika 6.3). Ob obeh kategorijah je gumb
za dodajanje novih prevozov oz. paketov. Če uporabnik ni prijavljen, se mu namesto
seznama prevozov in paketov prikaže prijava (Slika 6.2).
- Moj profil:
Na tem zavihku imamo pregled nad našim profilom. Podatke profila, ki se ob
dodajanju novih prevozov/paketov samodejno izpolnijo, lahko kadar koli uredimo.
Če uporabnik ni prijavljen, se mu namesto njegovih prevozov in paketov prikaže
prijava (Slika 6.2).
Nad glavami zavihkov sta bili v orodni vrstici dve ikoni. Skrajno desna ikona v obliki hrošča
( ) je služila za poročanje napak. Če ste odkrili kakšno napako, ste nam jo lahko sporočili z
izbiro na to ikono. Druga ikona v obliki oblaka, levo od skrajno desne, pa je predstavljala
stanje dosegljivosti strežnika. Prečrtan oblak ( ) je pomenil nedosegljivost strežnika,
prazen oblak ( ) je predstavjal povezovanje s strežnikom, polni oblak ( ) pa je predstavljal
dosegljivost strežnika. Ob pritisku na ikono se je izpisalo trenutno stanje strežnika.
35
Izgled drugega (Moje objave) in tretjega (Moj profil) zavihka, ko uporabnik ni bil prijavljen:
Slika 6.2: Obrazec za prijavo
Ob izbiri prevoza/paketa v prvem ali drugem zavihku se je odprl celotni prevoz/paket.
Slika 6.3: Celoten prikaz paketa
36
Ob izbiri celotnega pogleda prevoza/paketa se je prožila metoda, ki je poslala zahtevo za
pridobitev želenega prevoza/paketa, ta je nato prikazala njegove podatke. Če je bila
podana, se je prikazala tudi slika. V orodni vrstici smo lahko videli tri ikone, in sicer (od leve):
ikono za deljenje prevoza/paketa ( ), ikono za urejanje prevoza/paketa ( ) in ikono za
brisanje prevoza/paketa ( ).
O izbiri ikone za deljenje ( ) smo govorili v poglavju »Deljenje prevozov/paketov«. Ob izbiri
ikone za urejanje ( ) se nam je odprlo novo okno, ki je bilo podobno oknu za prikaz
celotnega prevoza/paketa, vendar smo lahko skoraj vse podatke spremenili in shranili. Ob
izbiri ikone za brisanje ( ) pa se nam je prikazalo obvestilo, da bo dejanje trajno, pri
katerem smo lahko potrdili ali preklicali brisanje prevoza/paketa.
Pri dodajanju prevoza/paketa se nam je odprlo okno, kot je okno za urejanje, pri čemer so
se samodejno izpolnili samo podatki našega profila. Preden se je poslala zahteva za
dodajanje, se je preverilo, ali so bili vsi obvezni podatki podani (kraj odhoda/prevzema, kraj
prihoda/dostave, datum in telefonska številka (pri prevozu še tip vozila)). Brez teh podatkov
nismo mogli dodati novega prevoza/paketa.
Ob zagonu aplikacije se je v času nalaganja prikazala slika z logotipom (Slika 6.4).
Slika 6.4: Logotip aplikacije v času nalaganja
37
7 SKLEP
V diplomski nalogi smo predstavili različna področja razvoja novodobnih mobilnih aplikacij.
Predstavili smo orodje Android Lint, ki nam je pomagalo pri izdelavi robustnejše in
pravilnejše kode, orodje Android App Links, s pomočjo katere smo omogočili deljenje
prevozov/paketov, okolje Node.js za pisanje skript v programskem jeziku JavaScript,
podatkovno bazo MongoDB, ki je hranila podatke aplikacije, in modul Mongoose za lažje
pisanje skript. V kombinaciji z okoljem Node.js in MongoDB modulom Mongoose smo
napisali strežnik, ki je posredno povezoval aplikacijo s podatkovno bazo.
Z zadovoljstvom smo predstavili izdelek, ki je lahko zelo uporaben. Z njim smo dosegli vse,
kar smo si zadali. Razvijanje aplikacije pa se ne ustavi tukaj, saj se nove ideje, kako jo
nadgraditi, porajajo vsakič znova.
Nekatere ideje za prihodnje razvijanje:
- Naročanje na obvestila o novih dodanih prevozih/paketih z določeno relacijo in
datumom. S tem bi preprečili nepotrebno odpiranje aplikacije in porabljanje virov.
- Pri dodajanju novih prevozov/paketov se ob podajanju krajev samodejno poiščejo
in prikažejo prevozi/paketi, ki se ujemajo s podanimi podatki. Tako bi hitreje
povezali ponudnike z iskalci in preprečili dodajanje nepotrebnih prevozov/paketov.
- Robustnejše iskanje prevozov in nadgradnja podatkovne baze, ki bi hranila več
podatkov za možno delanje določenih analiz in preverjanj.
- Preverjanje pristnosti podane telefonske številke.
Trenutno je naša največja naloga pridobiti uporabnike, ker želimo, da se naša aplikacija
oceni z vidika vsakdanjih ljudi, ki so tudi najbolj direktni in relevantni ocenjevalci.
Izdelava celotnega izdelka nam je predstavljala precejšen izziv, saj je bilo delo z zaledjem
aplikacije (back-end: strežnik in podatkovna baza) za nas novo področje. Med izdelavo
celotnega izdelka smo pridobili ogromno novega znanja, ki smo ga z zagonom in koristno
uporabili v podani aplikaciji.
38
8 VIRI IN LITERATURA
[1] android-logo.
Dostopno na: https://www.famouslogos.net/images/android-logo.jpg [20. 8. 2017]
[2] Android Lint – Android Studio Project Site.
Dostopno na: http://tools.android.com/tips/lint [20. 8. 2017]
[3] Handling Android App Links | Android Developers.
Dostopno na: https://developer.android.com/training/app-links/index.html [20 .8. 2017]
[4] Material icons - Material Design.
Dostopno na: https://material.io/icons/ [20. 8. 2017]
[5] Node.js – Wikipedia.
Dostopno na: https://en.wikipedia.org/wiki/Node.js [20. 8. 2017]
[6] Node.js_logo.
Dostopno na:
https://upload.wikimedia.org/wikipedia/commons/thumb/d/d9/Node.js_logo.svg/590px-
Node.js_logo.svg.png [20. 8. 2017]
[7] Node.js Modules.
Dostopno na: https://www.w3schools.com/nodejs/nodejs_modules.asp [20. 8. 2017]
[8] mysql-mariadb.
Dostopno na: https://dominicm.com/wp-content/uploads/2015/03/mysql-mariadb.png
[20. 8. 2017]
[9] MongoDB – Wikipedia.
Dostopno na: https://en.wikipedia.org/wiki/MongoDB [20. 8. 2017]
[10] mLab-logo-onlight.
Dostopno na: https://mlab.com/company/brand/img/downloads/mLab-logo-onlight.png
[21. 8. 2017]
[11] RESTful API design with Node.js – Hacker Noon.
Dostopno na: https://hackernoon.com/restful-api-design-with-node-js-26ccf66eab09
[21. 8. 2017]
[12] MongoDB-Logo.
Dostopno na: https://webassets.mongodb.com/_com_assets/cms/MongoDB-Logo-
5c3a7405a85675366beb3a5ec4c032348c390b3f142f5e6dddf1d78e2df5cb5c.png [21. 8. 2017]
39
[13] Android Asynchronous Http Client.
Dostopno na: http://loopj.com/android-async-http/ [21. 8. 2017]
[14] List of HTTP status codes – Wikipedia.
Dostopno na: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes [21. 8. 2017]
[15] MongoDB Hosting: Database-as-a-Service by mLab.
Dostopno na: https://mlab.com/welcome/ [21. 8. 2017]
[16] Mongoose ODM v4.11.8. Dostopno na: http://mongoosejs.com/ [21. 8. 2017]
40
41
42
43