Diplomski Rad - David Fejes

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 62

UNIVERZITET U NOVOM SADU

FAKULTET TEHNIČKIH NAUKA U


NOVOM SADU

David Feješ

IMPLEMENTACIJA MIKROSERVISNE
APLIKACIJE ZA AUTOMATIZACIJU PROCESA
PORUČIVANJA HRANE

DIPLOMSKI RAD
Osnovne akademske studije

Novi Sad, 2023.


1
УНИВЕРЗИТЕТ У НОВОМ САДУ ⚫ ФАКУЛТЕТ ТЕХНИЧКИХ НАУКА
21000 НОВИ СА Д, Трг Доситеја Обрадовића 6

КЉУЧНА ДОКУМЕНТАЦИЈСКА ИНФОРМАЦИЈА

Редни број, РБР:


Идентификациони број, ИБР:
Тип документације, ТД: Монографска публикација
Тип записа, ТЗ: Текстуални штампани материјал
Врста рада, ВР: Дипломски (Bachelor) рад
Аутор, АУ: Давид фејеш
Ментор, МН: доц. др Владимир Мандић, доцент
Наслов рада, НР: Имплементација микросервисне апликације за аутоматизацију процеса
поручивања хране
Језик публикације, ЈП: Српски/латиница
Језик извода, ЈИ: Српски
Земља публиковања, ЗП: Србија
Уже географско подручје, УГП: Војводина
Година, ГО: 2023.
Издавач, ИЗ: Ауторски репринт
Место и адреса, МА: Нови Сад, Трг Доситеја Обрадовића 6
Физички опис рада, ФО: 7/62/0/13/19/0/0
(поглавља/страна/цитата/табела/слика/графика/прилога)

Научна област, НО: ИМТ – Информационе технологије


Научна дисциплина, НД: Инжењерство информационих система
Предметна одредница/Кључне речи, ПО: Микросервиси, кориснички интерфејс, аутоматизација процеса
УДК
Чува се, ЧУ: Библиотека Факултета техничких наука, Нови Сад
Важна напомена, ВН:
Извод, ИЗ: У овом раду је приказана имплементација једног решења микросервисне
архитектуре за аутоматизацију процеса наручивања хране.

Датум прихватања теме, ДП: 06.09.2023.


Датум одбране, ДО: 20.10.2023.
Чланови комисије, КО: Председник: др Соња Ристић, редовни професор
Члан: др Мирослав Стефановић, доцент Потпис ментора
Члан, ментор: др Владимир Мандић, ванредни професор

2
UNIVERSITY OF NOVI SAD ⚫ FACULTY OF TECHNICAL SCIENCES
21000 NOVI SAD, Tr g Dositeja Obradovića 6

KEY WORDS DOCUMENTATION

Accession number, ANO:


Identification number, INO:
Document type, DT: Monographic publication
Type of record, TR: Textual printed material
Contents code, CC: Bachelor thesis
Author, AU: David Feješ
Mentor, MN: Vladimir Mandić, PhD
Title, TI: Implementation of a microservice application for automating the food ordering
process

Language of text, LT: Serbian


Language of abstract, LA: Serbian
Country of publication, CP: Republic of Serbia
Locality of publication, LP: Vojvodina
Publication year, PY: 2023.
Publisher, PB: Author’s reprint
Publication place, PP: Novi Sad, Trg Dositeja Obradovića 6
Physical description, PD: 7/62/0/13/19/0/0
(chapters/pages/ref/tables/pictures/graphs/appendixes)

Scientific field, SF: IMT – Information Technologies


Scientific discipline, SD: Information Systems Engineering
Subject/Key words, S/KW: Microservices, user interface, process automation
UC
Holding data, HD: Library of Faculty of technical sciences, Novi Sad
Note, N:
Abstract, AB: Following work presents the implementation of a solution for a microservices
architecture aimed at automating the food ordering process.

Accepted by the Scientific Board on, ASB: 06.09.2023.


Defended on, DE: 20.10.2023.
Defended Board, Sonja Ristić PhD, full professor
President:
DB:
Member: Miroslav Stefanović PhD, assistant professor Menthor's sign
Member, Mentor: Vladimir Mandić, PhD, associate professor.

3
Sadržaj
Spisak slika ....................................................................................................................................... 6

Spisak tabela ..................................................................................................................................... 7

Spisak listinga................................................................................................................................... 8

1. Uvod .......................................................................................................................................... 9

1.1. Kontekst i motivacija problema ............................................................................................ 9

1.2. Zadatak i cilj rada ................................................................................................................ 10

1.3. Struktura rada ...................................................................................................................... 11

2. Teorijski koncepti rešenja ....................................................................................................... 12

2.1. Mikroservisi i mikroservisna arhitektura ............................................................................ 12

2.1.1. Domenski vođen dizajn ............................................................................................ 13

2.2. Implementacija mikroservisa u .NET C# ............................................................................ 15

2.2.1. Entity Framework Core ............................................................................................ 16

2.2.2. Swagger .................................................................................................................... 16

2.2.3. Ocelot ....................................................................................................................... 16

2.3. Implementacija korisničkog interfejsa korišćenjem REACT okvira ................................... 16

2.3.1. Redux ........................................................................................................................ 17

2.3.2. Axios ......................................................................................................................... 19

2.3.3. MUI .......................................................................................................................... 19

2.3.4. React Router ............................................................................................................. 20

2.3.5. React Toastify ........................................................................................................... 20

3. Zahtevi rešenja ........................................................................................................................ 21

3.1. Funkcionalni zahtevi ........................................................................................................... 21

3.2. Nefunkcionalni zahtevi........................................................................................................ 24

4
4. Dizajn rešenja .......................................................................................................................... 25

4.1. Slučajevi upotrebe ............................................................................................................... 26

4.1.1. Slučaj upotrebe procesa glasanja .............................................................................. 26

4.1.2. Slučaj upotrebe izbora hrane .................................................................................... 27

4.1.3. Slučaj upotrebe procesa naručivanja ........................................................................ 28

4.2. Dizajn mikroservisa ............................................................................................................. 28

4.2.1. Restoran mikroservis ................................................................................................ 30

4.2.2. Glasanje mikroservis ................................................................................................ 30

4.2.3. Porudžbina mikroservis ............................................................................................ 31

4.3. Dizajn korisničkog interfejsa............................................................................................... 31

5. Implementacija i evaluacija rešenja ........................................................................................ 33

5.1. Implementacija po mikroservisima ..................................................................................... 33

5.1.1. Keycloak servis ......................................................................................................... 33

5.1.2. Restoran mikroservis ................................................................................................ 35

5.1.3. Glasanje mikroservis ................................................................................................ 37

5.1.4. Porudžbina mikroservis ............................................................................................ 46

5.2. Implementacija korisničkog interfejsa unutar REACT okvira ............................................. 50

6. Ograničenja rešenja ................................................................................................................. 57

7. Zaključak i budući rad............................................................................................................. 58

Literatura ........................................................................................................................................ 60

Biografija ........................................................................................................................................ 62

5
Spisak slika

Slika 1 Primer monolitne arhitekture. Preuzeto i adaptirano na osnovu [3] .................................. 12


Slika 2 Primer mikroservisne arhitekture. Preuzeto i adaptirano na osnovu [3] ........................... 13
Slika 4 Dijagram ciklusa ažuriranja stanja u Redux-u. Preuzeto i adaptirano sa [12] ................... 19
Slika 5 Arhitektura rešenja............................................................................................................. 25
Slika 6 Dijagram slučajeva upotrebe glasanja ............................................................................... 26
Slika 7 Dijagram slučaja upotrebe izbora hrane ............................................................................ 27
Slika 8 Dijagram slučaja upotrebe naručivanja hrane.................................................................... 28
Slika 9 Dijagram klasa ................................................................................................................... 29
Slika 10 Početni ekran Keycloak servisa ....................................................................................... 34
Slika 11 Dijagram klasa Restoran mikroservisa ............................................................................ 35
Slika 12 Dijagram klasa Glasanje mikroservisa ............................................................................ 38
Slika 13 Dijagram klasa Porudžbina mikroservisa ........................................................................ 47
Slika 14 Prikaz stranice restorana korisničkog interfejsa .............................................................. 53
Slika 15 Slika padajućeg menija pri zadršci na restoranu.............................................................. 54
Slika 16 Stranica dodavanja novog restorana ................................................................................ 54
Slika 17 Stranica glasanja kada glasanje nije otvoreno sa strance kancelarijskog menadžera ...... 55
Slika 18 Stranica glasanja pri otvorenom glasanju sa strance kancelarijskog menadžera ............. 55
Slika 19 Stranica pravljenja porudžbine ........................................................................................ 56

6
Spisak tabela

Tabela 1 Koncepti DDD-a ............................................................................................................. 14


Tabela 2 Osnovni pojmovi Redux-a ............................................................................................. 18
Tabela 3 Funkcionalni zahtevi KeyCloak servisa .......................................................................... 21
Tabela 4 Funkcionalni zahtevi Restoran servisa ........................................................................... 21
Tabela 5 Funkcionalni zahtevi Glasanje servisa ........................................................................... 22
Tabela 6 Funkcionalni zahtevi Porudžbina servisa ....................................................................... 23
Tabela 7 Nefunkcionalni zahtevi ................................................................................................... 24
Tabela 8 Moduli React aplikacije .................................................................................................. 32
Tabela 9 Lista metoda restoran kontrolera .................................................................................... 37
Tabela 10 Lista metoda porudžbina kontrolera ............................................................................. 49
Tabela 11 Lista metoda grupa narudžbina kontrolera ................................................................... 49
Tabela 12 Lista metoda stavki porudžbine kontrolera .................................................................. 50
Tabela 13 Lista biblioteka korišćena pri izradi korisničkog interfejsa .......................................... 50

7
Spisak listinga

Listing 1 Deo Context-a Restoran mikroservisa ............................................................................ 36


Listing 2 Interfejs restoran servisa ................................................................................................. 36
Listing 3 Komunikacija sa Restoran mikroservisom ..................................................................... 39
Listing 4 Komunikacija sa Porudžbina mikroservisom ................................................................. 40
Listing 5 Metoda JoinVoting ......................................................................................................... 41
Listing 6 Metoda CreateVote......................................................................................................... 42
Listing 7 Metoda CloseVoting....................................................................................................... 43
Listing 8 Interfejs servisa glasanja ................................................................................................ 43
Listing 9 Servisna metoda dodavanja glasanja .............................................................................. 44
Listing 10 Servisna metoda zatvaranja današnjeg glasanja ........................................................... 44
Listing 11 Interfejs servisa glasova ................................................................................................ 45
Listing 12 Servisna metoda dodavanje glasa ................................................................................. 46
Listing 13 Interfejs porudžbina servisa.......................................................................................... 48
Listing 14 Metoda dodavanja porudžbine unutar porudžbina servisa ........................................... 48
Listing 15 index.tsx ....................................................................................................................... 51
Listing 16 Keycloak servis unutar korisničkog interfejsa ............................................................. 52

8
1.Uvod

Prva veb stranica je nastala 1989. godine u Evropskom centru za nuklearna istraživanja.
Nastankom World Wide Web-a, Tim Berners-Li je imao za cilj da automatizuje deljenje informacija
između akademske zajednice [1]. Njegova stranica bila je zasnovana na hiperlinkovima Danas, 30.
godina kasnije, veb stranice su evoluirale u veb apikacije koje imaju različite svrhe. Neki od
primera upotrebe veb aplikacija jesu aplikacije za komunikaciju, koje omogućavaju korisnicima
povezivanje, nezavisnono od geografske udaljenosti. Ovaj tip aplikacija donosi dosta benefita
oblastima kao što su trgovina, bankarstvo, obrazovanje, zdravstvo, transport. Pored ovih, postoje
aplikacije za informisanje, zabavu, biznis kao i širok spektar ostalih oblasti. Pružaju mogućnost
korisnicima za lakši pristup informacijama i uslugama. Napredak tehnologije omogućio je globalnu
povezanost, čime se geografske granice brišu. Veb aplikacije su postale neizostavan deo
svakodnevnog života.
Kao rezultat globalizacije, a zatim i pandemijom korona virusa, primećen je značajan porast
korišćenja usluga aplikacija dostave. Prouzrokovano potrebom da se ostane kod kuće, ljudi su se
sve više oslanjali na tehnologiju. Putem računara ili mobilnih uređaja aplikacije su korišćene za
naručivanje hrane, distribuciju medicinske opreme i lekova. Dosta su olakšale poslovanje na polju
logistike i dostave. Nakon pandemije, ostala je kultura dostave hrane, samim tim je dovela do toga
da količina korisnika aplikacija za naručivanje nije pala, naprotiv, taj broj je nastavio da raste. Veb
aplikacije doprinose olakšanju i unapređenju različitih aspekata života i poslovanja.

1.1. Kontekst i motivacija problema

Aplikacije za naručivanje hrane omogućavaju korisnicima brzo i lako naručivanje hrane uz


dostavu na kućnu adresu. Omogućavaju širok izbor hrane, bez potrebe odlaska po porudžbinu.
Benefiti uključuju praktičnost, prilagođavanje narudžbi prema individualnim željama tako da nema
bacanja hrane, pored toga štedeći vreme. Omogućavaju zakazivanje za željano vreme, kao i
praćenje statusa porudžbine. Neke aplikacije imaju mogućnost praćenja dostavljača. Benefiti
postaju mnogo veći u slučaju narudžbina za veći broj ljudi. Na našem tržištu postoje nekoliko

9
aplikacija za dostavu kao što su Glovo1 i Wolt2. Obuhvataju širok asortiman, preko prehrambenih
proizvoda, elektronike, kozmetike, do medicinskih sredstava i lekova.
Jedan od osnovnih problema u organizacijama koju čine veći broj ljudi, bilo da su to
skupovi, poslovne organizacije, kompanije ili događaji jeste logistika ishrane. Proces naručivanja
hrane u organizacijama može biti nepotrebno dugotrajan, što u krajnjoj liniji dovodi do mogućeg
nezadovoljstva među zaposlenima. Javlja se problem izbora mesta odakle će se hrana poručiti, koji
će proizvodi činiti narudžbinu, samog poručivanja, a kasnije i do evidentiranja svake porudžbine i
naplate. Stvara se potreba ubrzavanja samog procesa naručivanja hrane, uz minimalne napore.
Vodeći se ovom pretpostavkom, cilj ovog rada jeste kreiranje aplikacije za automatizaciju procesa
poručivanja hrane.
Aplikacijom koja će voditi računa o narudžbinama na nivou organizacije, stvara se
mogućnost pravljenja individualne porudžbine za svakog zaposlenog, uz praćenje istorije
prethodnih porudžbina. Pored toga, benefiti ovakvog informacionog sistema mogu dovesti do
evidencije svih porudžbina, što u krajnjoj liniji dovodi do praćenja troškova i potencijalnog
smanjivanja istih.

1.2. Zadatak i cilj rada

Zadatak ovog rada jeste aplikacija za poručivanje hrane, implementirana primenom


mikroservisne arhitekture. Aplikacija je koncipirana za internu uoptrebu unutar okruženja
kompanije. Analizom realnog problema došlo se do zaključka je potrebno razviti informacioni
sistem koji će obuhvatiti proces poručivanja hrane, počevši od izbora restorana koji će se odrediti
putem glasanja na dnevnom nivou, zatim pravljenjem individualnih porudžbina od strane svakog
aktivnog korisnika sistema, preko evidencije porudžbina za svakog korisnika, pa sve do istorije
svih narudžbina. Ovim će se omogućiti lako i precizno praćenje svih porudžbina što omogućava
lakšu finansijsku evidenciju. Sistem omogućava grupisanje porudžbina na nivou restorana, što
omogućava korisnicima da podele troškove dostave. Aplikacija vodi evidenciju o restoranima koji
su u opticaju za dnevna glasanja izbora restorana, pružajući mogućnost korisnicima da dodaju nove

1
https://glovoapp.com
2
https://wolt.com

10
i ažuriraju postojeće. Cilj ovog rada jeste automatizovati proces poručivanja hrane čime će se
uštedeti vreme korisnicima sistema.

1.3. Struktura rada

Sadržaj koji prikazan u nastavku rada je podeljen na 7 poglavlja.


U poglavlju 2. su opisani osnovni teorijski koncepti mikroservisne arhitekture kao i razlika
iste u odnosu na monolitnu arhitekturu. Prikazana je implementacija mikroservisne arhitekture
unutar .NET okruženja. Bilo je govora o međusobnoj komunikaciji mikroservisa, kao i o domenski
vođenom dizajnu. Na kraju predstavljena je implementacija korisničkog interfejsa koriščenjem
React biblioteke, kao i o korišćenim bibliotekama i njihovim namenama i načinima na koji
funkcionišu.
U poglavlju 3. predstavljeni su zahtevi rešenja koje treba da ispuni informacioni sistem za
automatizovanje procesa poručivanja hrane.Obuhvaćeni su funkcionalni i nefunkcionalni zahtevi.
Funkcionalni zahtevi su podeljeni po mikroservisima kako bi se preciznije razgraničili servisi.
Poglavlje 4 predstavlja dizajn samog sistema. Na samom početku predstavljen je dizajn
rešenja obuhvatajući sve servise. Nakon toga su predstavljeni slučajevi upotrebe, dok sam kraj čini
dizajn svakog od servisa.
Poglavlje 5 prikazuje detaljnu implementaciju mikroservisa, kao i korisničkog interfejsa.
Backend deo aplikacije je implementiran u .NET okruženju. Biće reči o SignalR-u, kao apstrakciji
koja je omogućila komunikaciju u stvarnom vremenu implementiranu u sklopu glasanja, kao i o
Entity Framework Core-u, okviru za objektno relaciono mapiranje. Frontend deo aplikacije je
implementiran upotrebom REACT okvira. Pored toga korišćena je biblioteka Redux Toolkit,
biblioteka za upravljanje stanjem u JavaScript aplikacijama. Implementacija u potpunosti prati
dizajn koji je prikazan u 4. poglavlju. Na kraju poglavlja je bilo govora o evaluaciji rešenja.
Poglavlje 6 se govori o uočenim ograničenjima koja su primećenja tokom implementacije
rešenja. Pored tehničkih, predstavljena su i neka domenska ograničenja koja predstavljaju
potencijalna unapređenja rešenja.
Poslednje poglavlje rada predstavlja zaključak, u kome je predstavljen kratak osvrt na
celokupan rad. Na osnovu toga će se izneti zaključci o samom rešenju, kao i pravci u kojima bi ono
moglo da se razvija u budućnosti.

11
2.Teorijski koncepti rešenja

U poglavlju koje sledi biće reči o mikroservisima i mikroservisnoj arhitekturi. Govoriće se


o razlikama između monolitne i mikroservisne arhitekture, prednostima i izazovima, kao i o
implementaciji mikroservisne arhitekture u .NET okruženju. Nakon toga fokus će biti na
implementaciji korisničkog interfejsa korišćenjem React okvira.

2.1. Mikroservisi i mikroservisna arhitektura

Mikroservisi i mikroservisna arhitektura predstavljaju pristup razvoja softvera u kom se


aplikacija deli na manje, nezavisne celine, nazvane servisi, koji su u međusobnoj komunikaciji [2].
Servisi su nezabisno razvijani što omogućava mikroservisnoj arhitekturi razvoj servisa u različitim
programskim jezicima, korišćenjem različitih tehnologija, pružajući razvojnim timovima slobodu
u izboru tehnologije koji će na najbolji način odgovoriti korisničkim zahtevima. Kako bi što bolje
razumeli mikroservisnu arhitekturu, napraviće se analogija sa monolitnom arhitekturom.
Monolitna arhitektura predstavlja pristup razvoja softvera u kom se različite
funkcionalnosti sistema razvijaju unutar jednog programa razvijanog u jednoj tehnologiji [3]. Slika
1. prikazuje kako izgleda monolitna arhitektura.

Slika 1 Primer monolitne arhitekture. Preuzeto i adaptirano na osnovu [3]

Mikroservisna arhitektura ima drugačiji pristup. Razdvajanjem funkcionalnosti,


objedinjenim u servisima, mikroservisna arhitektura olakšava razvoj softvera omogućavajući

12
razvojnim timovima da u isto vreme razvijaju različite funkcionalnosti, samim tim je pogodna za
kontinualnu isporuku. Mikroservisna arhitektura omogućava korišćenje različitih baza podataka.
Na slici 2 je prikazan primer mikroservisne arhitekture.

Slika 2 Primer mikroservisne arhitekture. Preuzeto i adaptirano na osnovu [3]

Jedan od izazova pri razvoju mikroservisne arhitektura predstavlja međusobna


komunikacija servisa. Postoje dva obrasca komunikacije među servisima [4]. Sinhrona i asinhrona
komunikacija. Korišćenjem obrasca sinhrone komunikacije, poziv se upućuje drugom servisu
koristeći protokole kao što su HTTP (Hypertext Transfer Protocol) ili gRPC(Remote Procedure
Calls). Pozivajući servis čeka na odgovor pozivanog servisa. Pozivajući servis se blokira dokle god
ne dobije odgovor. Suprotno tome, primenom asinhrone komunikacije, pozivajući servis ne čeka
na odgovor pozivanog servisa, već nastavlja svoje izvršavanje. Ovo je korisno u situacijama kada
pozivani servis treba da izvrši operaciju koja zahteva više vremena i resursa, bez potrebe da se
blokira rad pozivajućeg servisa.
Još jedan izazov predstavlja i jasno definisanje granica između servisa. Rešenje ovog
izazova se može pronaći u korišćenju domenski vođen razvoj softvera.

2.1.1. Domenski vođen dizajn

13
Domenski vođen dizajn predstavlja način razmišljanja i skup praksi usmerenih prema
ubrzanom razvoju softvera baziranih na složenim domenima. Osnova tog pristupa predstavlja
duboko razumevanje poslovnog domena i problema koji softver treba da reši [5]. Cilj je razviti
softver koji se fokusira na modelu domena, umesto na tehnologiji u kojoj će biti implementiran. U
narednoj tabeli su predstavljeni osnovni koncepti DDD-a.

Tabela 1 Koncepti DDD-a

Koncept Opis
Entitet (Entity) Jedan od osnovnih koncepata modela. Objekat koji je
suštinski definisan svojim kontinuitetom i identitetom, a ne
atributima.
Vrednosni objekti (Value objects) Objekti koji opisuju karakteristiku ili atribut, ali nema svoj
identitet. Koriste se za prenošenje vrednosti.
Servisi (Services) Operacije koje se izbršavaju unutar domena. Glavna svrha
servisa je izdvajanje operacija koje se ne uklapaju u
objekte.
Agregati (Aggregates) Klaster povezanih objekata koje predstavljaju celinu.
Spoljne reference su ograničene na jednog člana agregata,
koji predstavlja korenski entitet.
Fabrike (Factories) Mehanzmi za pravilno instanciranje objekata, koriščeni za
složene domenske objekte.
Repozitoriji (Repositories) Sloj za pristup podacima koji omogućava čitanje, čuvanje
i upravljanje entitetima. Predstavlja abstraktan sloj između
domenskog modela i baze podataka.

Agregati predstavljaju logičke celine, sastoje se od povezanih objekata koji poseduju


korenski entitet(root entity) preko kog se vrši spoljnji pristup. Unutar agregata primenjuju se pravila
doslednosti koja obezbeđuju kontistentnost podataka.
Unutar klastera nalaze se objekti sa identifikacijom i kontinuitetom koji se nazivaju entiteti.
Sva kompunikacija sa drugim agregatima vrši se isključivo preko korenskog entiteta koji

14
predstavlja pristupnu tačku. Vrednosni objekti nemaju svoj identiet, već je njihova svrha prenos
vrednosti u određenom vremenskom trenutku.
Agregati treba da obezbede sve operacije i funkcionalnosti neophodne za upravljanje
entitetima unutar istog, kao i za očuvanje konzistentnosti. Servisi unutar agregata se koriste za
izolaciju kompleksnih operacija.
Fabrike se koriste za pravljenje složenih objekata. Pravljenje entiteta može biti složen
proces ukoliko se zahteva validacija i postavljanje nekog inicijalnog stanja. Svrha fabrika jeste
apstrakcija ovog procesa i pružanje mogućnosti jednostavnog pravljenja agregata sa svim
ograničenjima domena.

2.2. Implementacija mikroservisa u .NET C#

.NET predstavlja besplatnu platformu otvorenog koda za razvoj različitih vrsta aplikacija [6].
Sastoji se od programskih jezika, alata i biblioteka. U ovom radu je korišćen .NET Core [7] koji
služi za razvoj više platformskih, visoko performantnih aplikacija. Moguće je razviti veb, mobilne,
konzolne, IoT(Internet of Things) aplikacije. Korišćenjem .NET Core 6.0 verzije razvijena su 3
mikroservisa i jedan Gateway. Za implementaciju je korišćen programski jezik C#.
C# je savremeni objektno orijentisani programski jezik koji vrši strogu kontrolu tipova
podataka. Ovim se omogućava razvijanje sigurnih i pouzdanih aplikacija bez mogućnosti da
pogrešni tipovi podataka ostanu neopaženi.
Implementirano rešenje se sastoji iz 4 aplikacije pisane u .NET Core-u. To su 3 mikroservisne
aplikacije i 1 API Gateway. Mikroservisne aplikacije su kreirane na osnovu šablona ASP.NET Core
Web API unutar .NET razvojnog okruženja. Za kreiranje API Gateway-a je korišćen šablon
konzolne aplikacije.
Unutar aplikacija korišćene su biblioteke kao što su Entity Framework Core3,
Swagger4,Ocelot5.

3
https://learn.microsoft.com/en-us/ef/core/
4
https://swagger.io/
5
https://ocelot.readthedocs.io/en/latest/

15
2.2.1. Entity Framework Core

Entity Framework Core je laka, proširiva verzija Entity Framework tehnologije. Predstavlja
objektno-relacioni maper koji omogućava programerima rad sa bazama podataka upotrebom .NET
objekata i smajuje ili potpuno eliminiše potrebu za pisanjem koda za pristup podacima [8].

2.2.2. Swagger

Swagger predstavlja skup pravila, alata i specifikacija za razvoj i opis REST API-ja [9]. Glavna
svrha je olakšati komunikaciju između različitih komponenata sistema, omogućavajući računarima
i ljudima da razumeju mogućnosti REST API-ja bez potrebe pristupa izvornom kodu. Omogućava
automatizaciju generisanja dokumentacije što olakšava razvoj i testiranje. Pored toga pomaže pri
usaglašavanju sa ostalim API-jima kao i pri standardizaciji specifikacija.

2.2.3. Ocelot

Ocelot je .NET API Gateway je alat koji pruža mogućnost za laku implementaciju jedinstvene
pristupne tačke u mikroservisnoj arhitekturi koja će upravljati, rutirati i filtrirati zahteve ka
različitim mikroservisima Laka implementacija podrazumeva da nema potrebe za dodatnim
konfiguracijama unutar mikroservisa.

2.3. Implementacija korisničkog interfejsa korišćenjem REACT okvira

React je JavaScript biblioteka razvijena od kompanije Meta6 i služi za izradu Single Page
aplikacija. To su aplikacije koje koje dinamički menjaju svoj sadržaj, bez podrebe za ponovnim
učitavanjem cele aplikacije, stvarajući iluziju promene stranica dok se korisnik zapravo sve vreme
nalazi na jednoj stranici. React pruža mogućnost razvoja dinamičkih i interaktivnih veb aplikacija.
Aplikacije su bazirane na komponentama korisničkog interfejsa, koje se mogu iznova koristiti, a

6
https://about.meta.com/

16
njihoviom kombinovanjem stvara se mogućnost izgradnje kompleksnih interfejsa. Komponente
omogućavaju React-u skalabilnost što doprinosi boljem iskustvu programera.
React koristi JSX(JavaScript XML). JSX je sintaksa slična XML-u(Exstensible Markup
Language) koje se koristi kao proširenje JavaScript-u [10]. Omogućava programerima pisanje
komponenti korišćenjem sitakse slične HTML-u (HyperText Markup Language) u JavaScript-u
omogućavajući pisanje logike i vizualnog prikaza na jednom mestu. Njegova osnovna svrha jeste
manipulacija DOM-om(Document Object Model).
React koristi virtuelni DOM (Virtual DOM, VDOM). VDOM predstavlja koncept u kom React
koristi kopiju DOM-a koja se čuva u memoriji i nad kojom se proverava koji delovi stvarnog DOM-
a zahtevaju izmene, pre nego što se one zaista unesu. Proces sinhronizacije virtuelnog i stvarnog
DOM-a se naziva usklađivanje [11]. Ovim pristupom se zaobilazi ručna manipulacija DOM-om,
već omogućava deklarativni pristup u izradi korisničkih interfejsa, pružajući poboljšanje
performansi, povećava se sigurnost aplikacije zato što React ima kontrolu nad ažuriranjem DOM-
a. Pored toga postoje i benefiti skalabilnosti, zato što VDOM omogućava bolju optimizaciju.
Pri izradi ovog rada korišćen je TypeScript7 Typescript je programski jezik razvijen od strane
Microsoft-a, koristi se za razvoj klijentskih i serverskih aplikacija. Predstavlja nadskup JavaScript-
a, dodavajući statičku tipizaciju. Jedan od glavnih benefita TypeScript-a jeste eliminisanje tipskih
grešaka.
CSS (Cascading Style Sheets) predstavlja jezik za stilizovanje veb stranica. Pod ovim se smatra
određivanje boja, fontova, veličina, margina i još mnogih drugih stvari. CSS-om se može odrediti
dizajn i raspored u zavisnosti uređaja na kom se koristi aplikacija. SASS 8 (Syntactically Awesome
Style Sheets) predstavlja skriptni jezik za stilizovanje koji se prevodi u CSS. Omogućava korišćenje
promenjivih, operacija, ugnježdavanja pravila, funkcija i još mnogo toga. SASS pomaže pri
skaliranju i održavanju velikih aplikacija.
Pored React biblioteke pri izradi rada su koričćene i druge JavaScript biblioteke kao što su
Redux Toolkit, Axios, MUI, React Router i Toastify.

2.3.1. Redux

7
https://www.typescriptlang.org/
8
https://sass-lang.com/

17
Redux predstavlja JavaScript biblioteku koja služi za upravljanje stanjem aplikacije.
Funkcioniše tako što objedinjuje sve podatke u jednom predvidivom kontejneru, tako da su oni
centralizovani. Ovo omogućava deljenje podataka među komponentama aplikacije, što doprinosi
boljoj skalabilnosti. Redux ima jasan tok podataka i kako bi razumeli način na koji se podaci kreću,
prvo moramo definisati pojmove.

Tabela 2 Osnovni pojmovi Redux-a

Koncept Opis
Skladište (store) Centralizovano skladište predstavlja stanje aplikacije. Čuva sve
podatke bitne za aplikaciju. Sastoji se od reduktora.
Stanje (state) Predstavlja globalno stanje aplikacije koje je čuva unutar
skladišta.
Akcije (actions) Događaji koji se definišu u aplikaciji. Predstavljaju objekte koje
imaju svoj tip. Neretko sadrže obeležje koje sadrži dodatne
informacije i naziva se sadržaj (payload).
Reduktor (reducer) Reduktori su čiste funkcije koje prihvataju trenutno stanje i
akciju. Reduktori prave kopiju trenutnog stanja, kopiju ažuriraju
u skladu sa ulaznom akcijom i vraćaju izmenjenu kopiju koje
predstavlja novo stanje.
Emitovanje (dispatch) Jedini način ažuriranja stanja aplikacije. Predstavlja metodu kojoj
se prosleđuje akcija.
Selektori (selectors) Funkcije pomoću kojih se izvlače specifične informacije iz
skladišta.

Redux se bazira na jednosmernom toku podataka koji govori o tome da korisnički interfejs
poziva akciju, akcija se emituje do reduktora koji vrši ažuriranje stanja i dovodi do novog stanja,
koje se zatim prosleđuje korisničkom interfejsu koji se zatim osvežava i prikazuje trenutno stanje
aplikacije. Na narednoj slici prikazan je cikljus Redux apikacije.

18
Slika 3 Dijagram ciklusa ažuriranja stanja u Redux-u. Preuzeto i adaptirano sa [12]

U sklopu ovog projekta korišćen je Redux Toolkit9, predstavlja preporučeni pristup pisanja
Redux aplikacija. Redux Toolkit implementira predložene najbolje prakse, pojednostavljujući način
pisanja Redux aplikacija i eliminiše većinu šablonskog koda(boilerplate).

2.3.2. Axios

Axios10 je JavaScript bibloteka koja se koristi za obavljanje pravljenje HTTP poziva u okviru
veb aplikacija. Veoma je jednostavna za korišćenje i poseduje podršku obećanjima(promises).
Pored toga, Axios vrši automatsko mapiranje JSON podataka u JavaScript objekte tako da nema
potrebe za ručnim transformisanjem.

2.3.3. MUI

9
https://redux.js.org/redux-toolkit/overview
10
https://axios-http.com/

19
MUI11 predstavlja biblioteku koja se sastoji od komponenti korisničkog interfejsa i omogućava
programerima lakši razvoj aplikacija. Jedan od prednosti korišćenja ove biblioteke jeste velika
sloboda prilagođavanja komponenti vizualnom dizajnu aplikacije.

2.3.4. React Router

React Router12 predstavlja JavaScript biblioteku koji služi za rutiranje u React aplikacijama.
Omogućava dinamičko upravljanje sadržajem putem URL-ova (Uniform Resource Locator) bez
potrebe za osvežavanjem stranice. Poseduje funkcije i komponente za definisanje ruta i praćenje
URL-a. Korišćenjem React Router-a razvijaju se dinamički korisnički interfejsi bogati sadržajem.

2.3.5. React Toastify

React Toastify13 je JavaScript biblioteka koja omogućava prikaz kratkih poruka na određeno
vreme, u sklopu korisničkog interfejsa. Ova poruka može biti poruka uspešnog izvršavanja neke
akcije, upozorenje, obaveštenje, informacija o grešci i još mnogo toga. Korišćenjem ove aplikacije
stvara se bolje korisničko iskustvo jer pruža informaciju o svim bitnim aktivnostima koje se
dešavaju unutar aplikacije.

11
https://mui.com/
12
https://reactrouter.com/en/main
13
https://fkhadra.github.io/react-toastify/introduction

20
3.Zahtevi rešenja

U narednoj sekciji biće predstavljeni funkcionalni i nefunkcionalni zahtevi koje veb aplikacija
treba da zadovolji. Nakon toga zahtevi će biti podeljeni preba tipu uloge koji korisnik ima.

3.1. Funkcionalni zahtevi

Funkcionalni zahtevi predstavljaju specifične funkcionalnosti koje veb aplikacija mora da


ispuni kako bi zadovoljila svoj cilj. U nastavku će funkcionalni zahtevi biti podeljeni po
mikroservisima.
Prvi po redu su zahtevi koje treba da ispuni Keycloak servis.

Tabela 3 Funkcionalni zahtevi KeyCloak servisa

Redni broj Zahtev Opis zahteva


1. Logovanje Sistem treba da obezbedi autentifikaciju
korisnika koji mu pristupa.
2. Autorizovan pristup Sistem treba da obezbedi autorizaciju pri
resursima pristupu resursima
3. Registrovanje korisnika Sistem treba da obezbedi dodavanje novih
korisnika.
4. Ažuriranje korisnika Sistem treba da obezbedi mogućnost ažuriranja
podataka registrovanih korisnika
5. Brisanje korisnika Sistem treba da obezbedi mogućnost brisanja
registrovanih korisnika.

Slede funkcionalni zahtevi Restoran servisa.

Tabela 4 Funkcionalni zahtevi Restoran servisa

Redni broj Zahtev Opis zahteva

21
6. Evidencija restorana Sistem treba da omogući evidenciju svih
registrovanih restorana u aplikaciji
7. Navigiranje do sadržaja Sistem treba da obezbedi pristup meniju samog
restorana restorana.
8. Kreiranje restorana Sistem treba da obezbedi mogućnost registracije
novih restorana
9. Ažuriranje restorana Sistem obezbeđuje mogućnost ažuriranja
podataka registrovanih restorana
10. Brisanje restorana Sistem omogućava brisanje registrovanih
restorana.

U nastavku su predstavljeni funkcionalni zahtevi Glasanje mikroservisa.

Tabela 5 Funkcionalni zahtevi Glasanje servisa

Redni broj Zahtev Opis zahteva


11. Evidencija svih glasanja Sistem omogućava evidenciju istorije glasanja.
12. Evidencija pojedinačnog Sistem treba da obezbedi evidenciju glasanja
glasanja
13. Evidencija današnjeg Sistem pruža mogućnost evidencije glasanja koje
glasanja se dešava na današnji dan.
14. Evidencija rezultata Sistem pruža mogućnos evidencije rezultata
današnjeg galsanja današnjeg glasanja u vidu liste restorana koji su
izabrani
15. Kreiranje glasanja Sistem omogućava kreiranje glasanja. Glasanje
je ograničeno tako da može biti kreirano samo
jedno glasanje u toku dana.
16. Pridruživanje glasanju Sistem daje mogućnost pristupa aktivnom
glasanju.
17. Zatvaranje glasanja Sistem pruža mogućnost zatvaranja današnjeg
glasanja.

22
18. Kreiranje glasova Sistem omogućava kreiranje glasova za današnje
glasanje. Može se kreirati samo jedan glas po
korisniku za jedno glasanje.
19. Ažuriranje glasova Sistem obezbeđuje mogućnost promene glasa
korisnika.
20. Brisanje glasova Sistem omogućava brisanje glasova korisnika.

Nakon Glasanje servisa, slede funkcionalni zahtevi Porudžbina mikroservisa

Tabela 6 Funkcionalni zahtevi Porudžbina servisa

Redni broj Zahtev Opis


21. Evidencija svih porudžbina Sistem pruža mogućnost evidencije istorije
porudžbina.
22. Evidencija korisnikovih Şistem omogućava korisniku da pogleda istoriju
porudžbina porudžbina.
23. Evidencija pojedinačne Sistem omogućava evidenciju pojedinačne
porudžbine porudžbine
24. Pravljenje porudžbine Sistem omogućava pravljenje porudžbine.
Porudžbina se pravi na dnevnom nivu i kao takva
može postojati samo jedna devno.
25. Pravljenje grupe porudžbina Sistem omogućava pravljenje grupe porudžbina
koje predstavljaju sve stavke porudžbine grupe
korisnika za određeni restoran. Kao takva,
postoji jedna porudžbina za jedan restoran u
okviru glasanja.
26. Evidencija grupa porudžbina Sistem pruža mogućnost evidencije grupa
porudžbina.
27. Evidencija današnjih grupa Sistem obezbeđuje pristup grupama porudžbina
porudžbina koje su kreirane za današnje glasanje.
28. Brisanje grupa porudžbina Sistem omogućava brisanje grupa porudžbina.

23
29. Evidencija stavki Sistem pruža mogućnost evidencije svih stavki
porudžbina porudžbina.
30. Kreiranje stavki porudžbine Sistem omogućava korisniku kreiranje stavki
porudžbine.
31. Ažuriranje stavki porudžbine Sistem obezbeđuje korisniku mogućnost izmene
stavki porudžbine
32. Brisanje stavki porudžbine Sistem omogućava korisniku brisanje stavki
porudžbine.

3.2. Nefunkcionalni zahtevi

Nefunkcionalni zahtevi se odnose na karakteristike koje aplikacija treba da ispuni.

Tabela 7 Nefunkcionalni zahtevi

Redni broj Zahtev Opis zahteva


1. Performanse Sistem treba brzo da odgovara na korisničke
zahteve.
2. Pouzdanost Sposobnost sistema da se pravilno izvršava bez
nepredviđenih dešavanja.
3. Sigurnost Sistem treba da obezbedi zaštićenost od
neovlašćenog pristupa i zloupotreba.-

24
4.Dizajn rešenja

Nakon definisanja zahteva koje rešenje pora da ispuni, u narednom poglavlju biće detaljno
objašnjeno na koji način je rešenje implementirano. U prvom delu sekcije biće predstavljena
arhitektura aplikacije, prikazujući sve servise. Nakon toga slede UML (Unified Modeling
Language) dijagrami slučajeva upotrebe koji će predstaviti interakciju između korisnika i sistema.
Na kraju poglavlja biće predstavljen dizajn korisničkog interfejsa.
Na narednoj slici je predstavljena arhitektura aplikacije.

Slika 4 Arhitektura rešenja

Korisnici komuniciraju sa sistemom preko korisničkog interfejsa implementiran upotrebom


React-a. React aplikacija komunicira sa 2 servisa: API Gateway koji predstavlja pristupnu tačku
backend delu aplikacije, kao i Keycloak servisu.
Keycloak server se koristi za upravljanje identitetima i služi kao jedinstvena pristupna tačka
svim servisima koji ga koriste. U ovom slučaju to je backend deo aplikacije. Keycloak servis

25
obezbeđuje React aplikaciji token koji se šalje pri svakom zahtevu upućenom API Gateway-u. API
Gateway token proverava sa Keycloak servisom i na osnovu odgovora dozvoljava ili zabranjuje
pristup ostalim mikroservisima.
API Gateway predstavlja centralni servis u mikroservisnoj arhitekturi i predstavlja ulaznu tačku
za sve zahteve. Njegova glavna svrha jeste centrailzacija i kontrola API-ja. Odlučuje kojem će
mikroservisu biti prosleđen zahtev.
Mikroservisi su razvijani upotrebom .NET Core-a. Svaki mikroservis poseduje bazu podataka
koja predstavlja Microsoft SQL Server.

4.1. Slučajevi upotrebe

U ovom delu biće predstavljeni dijagrami koji predstavljaju grafički prikaz svih slučajeva
upotrebe u sistemu. Oni ukazuju na granice sistema i prikazuju njegovu interakciju sa spoljnjim
korisnicima.

4.1.1. Slučaj upotrebe procesa glasanja

Prvi slučaj upotrebe opisuje proces glasanja.

Slika 5 Dijagram slučajeva upotrebe glasanja

26
U ovom slučaju upotrebe opisan je proces glasanja. U ovoj interakciji učestvuju 2 tipa
korisnika: kancelarijski menadžer i korisnik.
Oba tipa korisnika imaju pravo pregleda i dodavanja restorana. Ovo je veoma bitno zato što
daje slobodu svim korisnicima da dodaju željane restorane.
Deo gde kancelarijski menadžer ima posebna ovlašćenja jeste glasanje. Samo kancelarijski
menadžer ima pravo na otvaranja dnevnog glasanja i otvoreno glasanje može samo jednom biti
zatvoreno. Nakon zatvaranja glasanja, ne može se otvoriti novo do sledećeg dana. Kada je glasanje
otvoreno, oba tipa korisnika imaju pravo glasanja za restoran iz koga žele tog dana da naruče hranu.
Ograničavajući faktor jeste što korisnik može kreirati samo jedan glas, ali dokle god je glasanje
otvoreno korisnik može promeniti svoj glas i glasati za neki drugi restoran.
Nakon zatvaranja glasanja, biraju se 2 restorana sa najviše glasanja. Ovim sužavanjem izbora
se smanjuje posao kancelarijskog menadžera koji je kasnije zadužen za naručivanje hrane. Kada je
glasanje zatvoreno, korisnici imaju 1 sat da unesu koje proizbode žele da naruče, kao i iz kog
restorana.

4.1.2. Slučaj upotrebe izbora hrane

Sledećom slikom predstavljen je dijagram slučajeva upotrene izbora hrane.

Slika 6 Dijagram slučaja upotrebe izbora hrane

27
Nakon popunjava forme i isteka sat vremena, na kancelarijskom menadžeru ostaje da naruči
proizbode, koristeći listu svih narudžbina za svakog korisnika. Nakon prijema dostave,
kancelarijski menadžer unosi cenu dostave, koja se deli na sve korisnike koji su naručili iz datog
restorana.

4.1.3. Slučaj upotrebe procesa naručivanja

Na narednoj slici predstavljen je slučaj upotrebe naručivanja hrane u formi dijagrama.

Slika 7 Dijagram slučaja upotrebe naručivanja hrane

Ovim dijagramima opisani su svi slučajevi upotrebe koji se mogu dogoditi. Služe za lakše
razumevanje funkcionalnih zahteva.

4.2. Dizajn mikroservisa

28
U okviru serverske strane, definisani su 3 mikroservisa od kojih svaki komunicira sa zasebnom
bazom podataka, kao i API Gateway. Za implementaciju mikroservisa korišćen je .NET Core,
Entity Framework Core koji predstavlja alat ta objektno relaciono mapiranje, dok je izbor baze
podataka pao na relacionu bazu podataka MS SQL. Svaki mikroservis sadrži servise koji
predstavljaju služe za obradu biznis logike i komunikaciju sa bazom podataka. Pored toga,
poseduju modele koji predstavljaju strukturu podataka koja će biti pohranjena u bazi podataka. Na
sledećoj slici će biti prikazan dijagram klasa.

Slika 8 Dijagram klasa

29
I konačno, kontroleri su odgovorni za obradu HTTP zahteva. U nastavku će svaki
mikroservis biti posebno objašnjen.

4.2.1. Restoran mikroservis

Restoran mikroservis predstavlja .NET Core Web API koji služi za manipulaciju
restoranima. Jedini model koji ovaj mikroservis poseduje jeste Restoran. Na osnovu kreiranog
modela, uz pomoć Entity Framework Core-a kreirana je prva migracija, a zatim ažurirana baza
podataka. Ovo je dovelo do kreiranja baze podataka. Repozitorijum sadrži osnovne CRUD (create,
read, update, delete) operacije. U slučaju čitanja implementirana je paginacija uz mogućnost
filtriranja podataka na osnovu naziva restorana i adrese.

4.2.2. Glasanje mikroservis

Mikroservis koji se bavi glasanjem predstavlja kompleksnije rešenje. Modeli koje ovaj
mikroservis poseduje su glasanje(voting) i glas(vote). Svako glasanje se održava za tačno određeni
datum i sadrži listu glasova. Model glasa nosi informaciju o tome koji korisnik je glasao, za koji
restoran je glasao, kao i kom glasanju pripada dati glas. Implementacija servisa obuhvata više
metoda, tako da pored izlistavanja glasava i prikazivanja podataka o smecifičnom glasanju na
osnovu Id-ja, postoje metode za prikaz današnjeg glasanja, ukoliko postoji, kao i list restorana koji
su danas izglasani. Ovo se postiže komunikacijom sa Restoran mikroservisom. Pored toga
uključene su metode brisanja glasanja, ali i kreiranja i zatvaranja glasanja. Ove 2 posebne metode
se ne aktiviraju preko kontrolera, već upotrebom SignalR biblioteke.
Mikroservis poseduje 2 konekcije ka 2 različita mikroservisa. Komunikacija se uspostavlja
upotrebom interfejsa IHttpClientRespository14. Komunikacija sa Restoran mikroservisom se
uspostavlja radi prihvatanja restorana na osnovu Id-ja korišćenjem HTTP GET metode.
Komunikacija sa Porudžbina mikroservisom se sastoji upotrebom 2 metode. To su kreiranje
porudžbine i kreiranje grupe porudžbina.

14
https://learn.microsoft.com/en-us/dotnet/api/system.net.http.ihttpclientfactory?view=dotnet-plat-ext-7.0

30
U sklopu mikroservisa postoji jedan Hub15 . Predstavlja komponentu SignalR biblioteke i
olakšava komunikaciju u realnom vremenu između klijentske aplikacije i mikroservisa.
Implementirane su metode pridruživanja glasanju, davanja glasa, kao i zatvaranja glasanja. Razlog
implementacije zatvaranja glasanja unutar Hub-a jeste što se pri zatvaranju glasanja moraju
izlogovati iz sesije klasanja svi povezani korisnici.
Mikroservis poseduje 2 kontrolera, jedan koji poziva glasanje servis i drugi koji poziva servis
koji upravlja glasom.

4.2.3. Porudžbina mikroservis

Ovaj mikroservis obuhvata podatke i aktivnosti vezane za samu produžbinu. Model podataka
se sastoji od porudžbine. Jedna porudžbina se pravi za svaki dan. Porudžbina poseduje listu grupa
porudžbina. Porudžbine se grupišu po restoranima. Pored toga poseduju podatak od ceni dostave i
listi stavki porudžbine. Stavka proudžbine se sastoji od proizvoda i korisnika koji kreira proizvod.
Za svaki od modela kreiran je po jedan servis. U sklopu servisa porudžbine, pored osnovnih
CRUD operacija, uključen je prikaz današnje proudžbine. Servis grupa porudžbina takođe
uključuje izlistavanje podataka koji su nastali danas. I konačno, servis koji se bavi stavkom
narudžbine poseduje osnovne funkcije izlistavanja podataka, kreiranja, ažuriranja i brisanja.

4.3. Dizajn korisničkog interfejsa

Dizajn korisničkog interfejsa predstavlja ključni aspekt korisničkog iskustva. U daljem tekstu
biće predstavljen dizajn korisničkog interfejsa rešenja korišćenjem React okvira, korišćenjem
TypeScript-a. Jedan od osnovnih ciljeva pri dizajniranju rešenje je bio pravilno struktuiranje
aplikacije radi održivosti, čistini i lakoći razvoja. Umesto tradicionalnog pristupa razvoju aplikacija
u kom se fajlovi struktuiraju na osnovu tipa, korišćena je struktura koja prati funkcionalnosti same
aplikacije. Ovo omogućava istovremen rad na više nezavisnih delova aplikacije. Funkcije su
podeljene po modulima, tako da aplikacija poseduje 5 modula. Svaki modul se sastoji od unapred

15
https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.signalr.hub?view=aspnetcore-7.0

31
određene strukture. Tu strukturu čine API pozivi, komponente koje služe za prikaz podataka,
kontejneri unutar kojih je implementirana logika, tipovi, rute i reduktor segmenta(slice).

Tabela 8 Moduli React aplikacije

Redni Modul Opis modula


broj
1. Authorizacija (auth) Modul obuhvata svu logiku neophodnu za
autorizaciju i autentifikaciju korisnika. Poziva
Keycloak servis.
2. Opšti (common) Predstavlja sadržaj koji se deli među svim
modulima. Sastoji se od UI komponenti, tipova i
pomoćnih metoda.
3. Restoran (restaurant) Modul koji služi za upravljanje i prikazivanje
restorana.
4. Glasanje (voting) Predstavlja funkcije i pomponente za prikaz i
manipulaciju glasanja. Obuhvata funkcije
SignalR-a.
5. Porudžbina (order) Predstavlja sadržaj neophodan za prikaz i
upravljanje porudžbinama.

Pored modula, struktura projekta sadrži konfiguraciju skladišta Redux-a. Pri konfigurisanju
skladišta definišu se reduktori. Definisana su 4 reduktora: autorizacija, restoran, glasanje i
porudžbina.
I poslednje, definisani su stilovi. Unutar komponenti, pored JSX fajla nalazi se i definicija
stilova u sklopu SCSS fajlova. Postoje globalni SCSS fajlovi smešteni u folderu Stilovi. Unutar tog
foldera definisane su promenjive, globalni stilovi i funkcije.
Strukturu foldera zaokružuje .ENV fajl koji predstavlja listu promenjivih specifičnu za razvojno
okruženje u obliku parova ključ-vredonst. Unutar ovog fajla smeštene su putanje ka Keycloak i API
Gateway servisu.

32
5. Implementacija i evaluacija rešenja

U narednom poglavlju biće detaljno objašnjena implementacija mikroservisa, kao i React


korisničkog interfejsa na osnovu dizajna iz prethodne sekcije. Biće objašnjeno kako su se
mikroservisi podelili po kontejnerima, kao i šta je korišćeno za orkestraciju istih. Na kraju ovog
poglavlja biće reči o evaluaciji implementiranog rešenja.

5.1. Implementacija po mikroservisima

Za implementaciju mikroservisne arhitekture korišćeni su Docker koji je služio za pakovanje


mikroservisa u kontejnere, dok je Minikube alat korišćen za orkestraciju kontejnera. U nastavku će
biti objašnjen svaki od ovih pojmova, dok je fokus rada na implementaciji mikroservisa.
Dokcer omogućava pravljenje vritualnih aplikacija u zatvorenim okruženjima sa neophodnim
postavkama za rad same aplikacije, što omogućava izolaciju aplikacija od njihovih zavisnosti.
Pored toga Doker olakšava horizontalno skaliranje aplikacija. Ovo dosta olakšava i ubrzava proces
implmenetacije.
Minikube16 predstavlja besplatan alat otvorenog koda koji omogućava brzo i jednostavno
postavljanje i upravljanje lokalnim Kubernetes17 klasterom. Kubernetes predstavlja platformu
otvorenog koda za orkestraciju aplikacijama u kontejnerima, omogućavajući automatizovano
upravljanje, sklairanje i praćenje.
U nastavku biće prikazana implementacija svakog mikroservisa. Biće objašnjeni Keycloak
servis, API Gateway, kao i ostala 3 mikroservisa.

5.1.1. Keycloak servis

Keycloak je softversko rešenje otvorenog koda koje služi za upravljanje identitetom i


pristupom. Osnovna svrha Keycloak-a jeste mogućnost centralizovanog upravljanja identitetima

16
https://minikube.sigs.k8s.io/docs/
17
https://kubernetes.io/

33
korisnika i kontrole pristupa različitim aplikacijama. Predstavlja brzo i pouzdano rešenje za potrebe
funkcionalnih zahteva.
Keycloak servis je uspešno implementiran i konfigurisan upotrebom Docker slike.
Pokretanjem slike pravi se kontejner i aplikacija se pokreće na portu 80:80.

Slika 9 Početni ekran Keycloak servisa

Nakon uspešnog pristupa Keycloak servisu napravljena je prva oblast(realm). Predstavlja


izolovani prostor za upravljanje identitetima, kao i za autorizaciju i autentifikaciju korisnika. Može
imati svoje korisnike i aplikacije. Oblast nosi naziv Food Order.
Sledeći korak jeste registrovanje aplikacije. Aplikacija je registrovana upotrebom protokola
OpenID-Connect18. OpenID-Connect predstavlja protokol za autorizaciju koji se temelji na OAuth

18
https://openid.net/developers/how-connect-works/

34
2.019 i omogućava verifikaciju identiteta korisnika na siguran način. Koristi se u sklopu mobilnih i
veb aplikacija.

5.1.2. Restoran mikroservis

Implementacija Restoran mikroservisa vođena je dizajnom definisanim u prethodnom poglavlju.


Funkcionalnosti ovog servisa su upravljanje svim restoranima, što uključuje njihovo izlistavanje,
sa ili bez filtera, dodavanje novih restorana, ažuriranje postojećih, kao i brisanje. Na sledećoj slici
nalazi se dijagram klasa Restoran mikroservisa.

Slika 10 Dijagram klasa Restoran mikroservisa

Pošto Restoran mikroservis predstavlja mali i jednostavan mikroservis, stoga poseduje


samo jednu klasu, Restoran.
Pored modela, postoje dto-ovi (data transfer object). Dto olakšava prenos podataka između
različitih slojeva aplikacije. Postoje 4 dto-a: dto koji predstavlja model unutar kog je isključen Id,
dto koji predstavlja model koji uključuje Id, dto za dodavanje novih restorana koji se sastoji iz
obeležja imena, adrese, telefona i url-a. Takođe, ovo su elementi dto-a za ažuriranje restorana.
Komunikacija sa bazom podataka uspostavljena je putem Entity Framework Core-a. Na
narednom listingu predstavljen je deo koda Context-a, na kome je prikazana definicija tabele baze
podataka koja nosi naziv Restaurants. Pored toga, nalazi se metoda OnConfiguring koja se koristi
za konfigurisanje opcija pristupa bazi podataka. Konfiguracija govori o upotrebi SQL servera kao

19
https://oauth.net/2/

35
i baze podataka, ka kojoj je putanja definisana u appsettings JSON fajlu. Pored toga, postavljena je
opcija automatskog ponovnog pokušaja uspostavljanja veze u slučaju neuspeha.

public DbSet<Restaurant> Restaurants { get; set; }

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)


{
optionsBuilder.UseSqlServer(
configuration.GetConnectionString("RestaurantDB"),
options => options.EnableRetryOnFailure());
}

Listing 1 Deo Context-a Restoran mikroservisa

Strukturu projekta čine i pomoćne metode. Pod pomoćnim metodama se smatra maper, koji
služi za pretvaranje jednog tipa objekata u drugi. Tako postoje metode koje mapiraju objekte
modela u dto-ove. Unutar helper metoda uključen je maper koji mapira listu objekata u listu
objekata sa paginacijom. Taj maper prima generički tip podataka.
Servisi sadrže biznis logiku koja je definisana u poglavlju zahteva. Pri instanciranju servisa,
konstruktor prima jedan parametar i to kontakst koji služi za komunikaciju sa bazom podataka
putem Entity Framework Core-a. Na sledećem listignu je predstavljen interfejs restoran servisa.

public interface IRestaurantService


{
PagedList<RestaurantDtoWithId> GetRestaurants(RestaurantFilter restaurantFilter);

List<RestaurantDtoWithId> GetRestaurantsByIds(Guid[] restaurantIds);

RestaurantDtoWithId GetRestaurant(Guid restaurantId);

RestaurantDto CreateRestaurant(RestaurantCreateDto restaurantDto);

RestaurantDto UpdateRestaurant(Guid restaurantId, RestaurantUpdateDto restaurantDto);

void DeleteRestaurant(Guid restaurantId);

bool SaveChanges();
}

Listing 2 Interfejs restoran servisa

U nastavku je prikazana tabela koja prikazuje metode koje Restoran mikroservis poseduje.

36
Putanja: /api/restaurants

Tabela 9 Lista metoda restoran kontrolera

Metoda Putanja Naziv Opis


GET Lista restorana Aplikacija vraća listu paginacije
koja sadrži restorane
POST Dodavanje restorana Aplikacija pravi novi restoran
GET /{restoranId} Prikaz restorana na Aplikacija vraća restoran za
osnovu Id-ja prosleđeni Id
PUT /{restoranId} Ažuriranje restorana Aplikacija vrši ažuriranje
restorana na osnovu proslđenog
Id-ja i objekta
DELETE /{restoranId} Brisanje restorana Aplikacija briše restoran sa
prosleđenim Id-jem

5.1.3. Glasanje mikroservis

Glasanje mikroservis predstavlja najveći i najkompleksniji servis. Vodi se definisanim


zahtevima. Ovaj servis koristi 2 protokola: HTTP i WebSocket20. U sklopu ovog servisa korišćen
je SignalR kako bi obezbedio komunikaciju u realnom vremenu. Ovo je od krucijalne važnosti u
implementaciji glasanja.
Na narednoj slici predstavljen je dijagram klasa Glasanje mikroservisa.

20
https://developer.mozilla.org/en-US/docs/Web/API/WebSocket

37
Slika 11 Dijagram klasa Glasanje mikroservisa

U ovom mikroservisu nalaze se 2 modela. To su glas i glasanje. Baza podataka se sastoji


od 2 tabele. Pored modela, postoje i dto-ovi koji služe za prikaz modela sa i bez Id-ja. Pored toga
postoje dto-ovi za svaki model koji služe za dodavanje novih. Pored navedenih dto-ova, postoje i
dto-ovi restorana i narudžbina.
Mikroservis Glasanje poseduje vezu sa preostala 2 mikroservisa. U nastavku će biti
prikazana komunikacija sa restoran mikroservisom.

38
public class RestaurantApiClient
{
private readonly IConfiguration configuration;
private readonly IHttpClientFactory httpClientFactory;
private readonly string restaurantApiUrl;

public RestaurantApiClient(IConfiguration configuration, IHttpClientFactory


httpClientFactory)
{
this.configuration = configuration;
this.httpClientFactory = httpClientFactory;
restaurantApiUrl = configuration["APIs:RestaurantAPI"];
}

public async Task<RestaurantDto> GetRestaurantByIdAsync(string restaurantId)


{
var httpClient = httpClientFactory.CreateClient();
var response = await
httpClient.GetAsync($"{restaurantApiUrl}/restaurants/{restaurantId}");

if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync();
RestaurantDto restaurantDto =
JsonConvert.DeserializeObject<RestaurantDto>(content);
return restaurantDto;
}
else
{
throw new Exception("Cant access to Restaurants");
}
}
}

Listing 3 Komunikacija sa Restoran mikroservisom

Ovaj kod predstavlja implementaciju RestaurantApiClient klase koji omogućava


komunikaciju se Restoran mikroservisom. Koristi se HttpClient za izvršavanje HTTP zahteva.
Putanja ka Restoran mikroservisu nalazi se u fajlu appsettings.json. Klasa poseduje jednu metodu,
koja služi za dohvatanje restorana na osnovu prosleđenog Id-ja.
Druga klasa koja komunicira sa mikroservisom nosi naziv OrderApiClient. Ova klasa je
dosta slična Restoran klasi, ali je razlika u tome što ona služi za dodavanje objekata. Na sledećem
listingu se nalazi OrderApiClient.

39
public class OrderApiClient
{
private readonly IConfiguration configuration;
private readonly IHttpClientFactory httpClientFactory;
private readonly string orderApiUrl;

public OrderApiClient(IConfiguration configuration, IHttpClientFactory httpClientFactory)


{
this.configuration = configuration;
this.httpClientFactory = httpClientFactory;
orderApiUrl = configuration["APIs:OrderAPI"];
}

public async Task<OrderDto> CreateOrder()


{

var httpClient = httpClientFactory.CreateClient();

var response = await httpClient.PostAsync($"{orderApiUrl}/orders", null);

if(response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
OrderDto orderDto = JsonConvert.DeserializeObject<OrderDto>(responseContent);
return orderDto;
}
else
{
throw new Exception("Cant create order");
}
}

public async Task<OrderGroupDto> CreateOrderGroup(OrderGroupCreateDto orderGroupCreateDto)


{
var httpClient = httpClientFactory.CreateClient();
var jsonContent = System.Text.Json.JsonSerializer.Serialize(orderGroupCreateDto);
var content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
var response = await httpClient.PostAsync($"{orderApiUrl}/orderGroups", content);

if (response.IsSuccessStatusCode)
{
var responseContent = await response.Content.ReadAsStringAsync();
OrderGroupDto orderGroupDto =
JsonConvert.DeserializeObject<OrderGroupDto>(responseContent);
return orderGroupDto;
}
else
{
throw new Exception("Failed to create Order Group");
}
}
}

Listing 4 Komunikacija sa Porudžbina mikroservisom

40
Ova klasa poseduje metode za dodavanje porudžbina i grupe porudžbina. U slučaju
neuspešnog izvršavanja bacaju se specifični izuzeci koji daju opis koji deo koda nije uspešno
izvršen.
Glasanje mikroservis poseduje Hub. Predstavlja klasu koja omogućava dvosmernu
komunikaciju sa klijentskom aplikacijom. U nastavku će biti predstavljene neke od metoda Hub-a.
Prva metoda jeste pridruživanje glasanju. Ova metoda se poziva u slučaju da je glasanje
otvoreno. Omogćava korisnicima pristup glasanju. Nakon toga, metoda poziva servis glasa,
prihvata listu današnjih glasova i šalje ih svim korisnicima.

public async Task JoinVoting(string userId)


{
if (!connectedUsers.Contains(userId))
{
await Groups.AddToGroupAsync(Context.ConnectionId, userId);
connectedUsers.Add(userId);

List<VoteDtoWithId> votes = voteService.GetVotesByVoting(voting.Id);


string votesJson = JsonConvert.SerializeObject(votes);

await Clients.All.SendAsync("VotesMessage", votesJson);


}

Listing 5 Metoda JoinVoting

Nakon što se korisnik pridružio glasanju, on ima pravo slanja glasa. Sledeća metoda služi
za dodavanja glasa korisnika.

41
public async Task CreateVote(string user, string userId, string restaurantId)
{
try
{
string votingId = voting.Id.ToString();
var restaurantDto = await restaurantApiClient.GetRestaurantByIdAsync(restaurantId);

if (restaurantDto != null)
{
VoteCreateDto voteDto = new()
{
RestaurantId = restaurantId,
UserId = userId,
UserName = user,
VotingId = votingId
};

VoteDtoWithId createdVote = voteService.CreateVote(voteDto);


if (createdVote != null)
{

List<VoteDtoWithId> votes = voteService.GetVotesByVoting(voting.Id);


string votesJson = JsonConvert.SerializeObject(votes);
await Clients.All.SendAsync("VotesMessage", votesJson);
await Clients.All.SendAsync("CreatedVoteMessage", $"<b>{user}</b> voted for
<b>{restaurantDto.Name}</b>.");
}
}
}
catch (Exception ex)
{
throw new Exception($"Error in CreateVote: {ex.Message}");
}
}

Listing 6 Metoda CreateVote

Ulazni parametri ove metode su Id korisnika i Id restorana. Ova metoda zahteva


komunikaciju sa Restoran mikroservisom kako bi se prihvatili svi potrebni podaci za Id restorana
koji je ulazni parametar. Ako je dohvaćen restoran, metoda formira objekat tipa VoteCreateDto
koji se prosleđuje servisu radi upisa glasa u bazu podataka. Nakon dodatog glasa, obaveštavaju se
svi korisnici u glasanju da je korisnik koji je pozvao ovu metodu glasao za željani restoran.

Poslednja metoda koja čini ovaj Hub jeste metoda zatvaranja glasanja.

42
public async Task CloseVoting()
{
foreach (var connectionId in UserHandler.ConnectedIds)
{
await Clients.Client(connectionId).SendAsync("ClosedVotingMessage", "Voting closed.");
await Groups.RemoveFromGroupAsync(connectionId, connectionId);
}

await votingService.CloseTodaysVoting();
UserHandler.ConnectedIds.Clear();
}

Listing 7 Metoda CloseVoting

Metoda zatvaranja glasanja koristi SignalR kako bi obavestila svakog povezanog korisnika
da je glasanje zatvoreno, a nakon toga ga uklanja iz grupe. Ovim postupkom se obezbeđuje da neće
postojati povezan korisnik na glasanje koje je zatvoreno. Nakon toga, poziva se servis za glasanja
koje zatvara današnje glasanje. Ovim su sve metode Hub-a obuhvaćene, slede servisi.
Prvi servis koji će biti predstavljen jeste servis glasanja. Obuhvata sve metode za uspešno
manipulisanje glasanjem.

public interface IVotingService


{
PagedList<VotingDtoWithId> GetVotings(VotingFilter filter);

VotingDtoWithId GetVoting(Guid votingId);

VotingDtoWithId GetTodaysVoting();
List<string> GetTodaysRestaurants();

VotingDtoWithId CreateVoting();

void DeleteVoting(Guid votingId);

Task CloseTodaysVoting();

bool SaveChanges();
}

Listing 8 Interfejs servisa glasanja

Sledi detaljno objašnjenje metoda dodavanja i zatvaranja glasanja. Pošto je definisano


pravilo da može postojati samo jedno glasanje dnevno, ova provera je obuhvaćena unutar servisne
metode.

43
public VotingDtoWithId CreateVoting()
{
DateTime today = DateTime.Today;
Voting existingVoting = context.Votings.FirstOrDefault(voting => voting.Date == today);

if (existingVoting != null)
{
return existingVoting.VotingToVotingDtoWithId();
}

VotingCreateDto votingDto = new()


{
Date = today
};

Voting voting = votingDto.CreateDtoToVoting();


context.Add(voting);
SaveChanges();
return voting.VotingToVotingDtoWithId();
}

Listing 9 Servisna metoda dodavanja glasanja

Sledeća metoda jeste metoda zatvaranja današnjeg glasanja. Zatvaranje glasanja predstavlja
komplikovaniji proces od procesa dodavanja glasanja.

public async Task CloseTodaysVoting()


{
DateTime today = DateTime.Today;
Voting voting = context.Votings.FirstOrDefault(voting => voting.Date == today);
voting.IsClosed = true;
SaveChanges();

OrderDto orderDto = await orderApiClient.CreateOrder();

List<string> restaurantIds = GetTodaysRestaurants();

foreach(string restaurantId in restaurantIds)


{
RestaurantDto restaurant = await
restaurantApiClient.GetRestaurantByIdAsync(restaurantId);

OrderGroupCreateDto orderGroupCreateDto = new()


{
OrderId = orderDto.Id,
RestaurantId = restaurantId,
RestaurantName = restaurant.Name
};

await orderApiClient.CreateOrderGroup(orderGroupCreateDto);
}
}

Listing 10 Servisna metoda zatvaranja današnjeg glasanja

44
Početak servisne metode čini promena obeležja objekta glasanja. Nakon toga poziva se
Porudžbina mikroservis koji vrši dodavanje glasanja. Poziva se lista današnjih restorana, koju čine
2 restorana sa najviše glasova, na čije se podatke čeka odgovor Restoran mikroservisa. Nakon toga,
poslednja stavka ove servisne metode jeste pravljenje grupa porudžbina za svaki restoran. Pored
servisa koji se bavi glasanjem, sledi servis koji se bavi glasovima.

public interface IVoteService


{
PagedList<VoteDtoWithId> GetVotes(VoteFilter filter);
List<VoteDtoWithId> GetVotesByVoting(Guid votingId);

VoteDtoWithId GetVote(Guid voteId);

VoteDtoWithId CreateVote(VoteCreateDto voteDto);

VoteDtoWithId UpdateVote(Guid voteId, VoteUpdateDto voteDto);

void DeleteVote(Guid voteId);

bool SaveChanges();
}

Listing 11 Interfejs servisa glasova

Metoda dodavanja glasova predstavlja jednu od bitnijih metoda za ovaj mikroservis. U


sklopu ove servisne metode implementirana je logika koja zadovoljava prethodno definisane
zahteve.

45
public VoteDtoWithId CreateVote(VoteCreateDto voteDto)
{
Voting voting = context.Votings.FirstOrDefault(v => v.Id == Guid.Parse(voteDto.VotingId));
Vote existingVote = context.Votes.FirstOrDefault(v =>
v.UserId == Guid.Parse(voteDto.UserId) && v.VotingId == Guid.Parse(voteDto.VotingId));

if (voting == null)
throw new HttpRequestException("Voting item not found", null,
HttpStatusCode.NotFound);

if (existingVote != null)
{
if (existingVote.RestaurantId != Guid.Parse(voteDto.RestaurantId))
{
DeleteVote(existingVote.Id);
}
else
{
return existingVote.VoteToVoteDtoWithId();
}
}

Vote vote = voteDto.CreateDtoToVote();


context.Add(vote);
context.SaveChanges();
return vote.VoteToVoteDtoWithId();
}

Listing 12 Servisna metoda dodavanje glasa

Da bi se novi glas za određenog korisnika napravio, prvo se mora proveriti da li je taj korisnik već
glasao na današnjem glasanju. U slučaju da je korisnik glasao, i to za restoran koji nije isti kao
restoran koji se nalazi unutar ulaznih parametara ove metode, postojeći glas se briše. U slučaju da
korisnik prvi put glasa na današnjem glasanju, pravi se novi glas, upisuje se u bazu podataka i vraća
se novi glas u obloku dto-a.

5.1.4. Porudžbina mikroservis

Mikroservis koji vodi evidenciju o porudžbinama zasnovan je na zahtevima definisanim ranije.


Obuhvata 3 modela:porudžbina, grupa porudžbina i stavka porudžbine. Na narednoj slici je
prikazan dijagram klasa Porudžbina mikroservisa.

46
Slika 12 Dijagram klasa Porudžbina mikroservisa

Za svaki model postoje 3 tipa dto-ova: dto koji predstavlja model sa uključenim Id-jem, dto
koji isključuje Id i dto za kreiranje novog modela. Izuzetak je stavka porudžbine koji poseduje i
dto za ažuriranje modela. Komunikacija sa bazom podataka uspostavljena je uz pomoć Entity
Framework Core-a.
Mikroservis se sastoji od 3 servisa, za svaki model po jedan. Predstavljen je servis koji se odnosi
na samu porudžbinu, a akcenat će biti stavljen na dodavanje nove porudžbine, obzirom da se mora
ispoštovati zahtev da mora postojati samo jedna porudžbina za jedan datum.

47
public interface IOrderService
{
PagedList<OrderDtoWithId> GetOrders(OrderFilter filter);

OrderDtoWithId GetTodaysOrder();

OrderDtoWithId GetOrder(Guid orderId);

OrderDtoWithId CreateOrder();

void DeleteOrder(Guid orderId);

bool SaveChanges();
}

Listing 13 Interfejs porudžbina servisa

U narednom listingu predstavljena je metoda dodavanja porudžbine. Vrši se provera da li


postoji porudžbina za današnji datum. Ukoliko ona postoji, ta porudžbina predstavlja povratni
objekat metode. U slučaju da porudžbina za današnji datum ne postoji, pravi se nova za dati datum
i vraća se kao povratna vredonst metode.

public OrderDtoWithId CreateOrder()


{

DateTime today = DateTime.Today;


Order existingOrder = context.Orders.FirstOrDefault(order => order.Date == today);

if (existingOrder != null)
{
return existingOrder.OrderToOrderDtoWithId();
}

Order order = new()


{
Date = DateTime.Today
};
context.Add(order);
SaveChanges();
return order.OrderToOrderDtoWithId();
}

Listing 14 Metoda dodavanja porudžbine unutar porudžbina servisa

U nastavku će biti predstavljene pristupne tačke koje ovaj mikroservis poseduje, podeljene
po kontrolerima. Prvi kontroler koji je predstavljen je porudžbina kontroler.

Putanja: /api/orders

48
Tabela 10 Lista metoda porudžbina kontrolera

Metoda Putanja Naziv Opis


GET / Lista porudžbina Aplikacija vraća listu paginacije
koja sadrži porudžbine
POST / Dodavanje Aplikacija pravi novu porudžbinu
porudžbine za današnji datum
GET /{porudžbinaId} Prikaz porudžbine na Aplikacija vraća porudžbinu na
osnovu Id-ja osnovu prosleđenog Id-ja
DELETE /{porudžbinaId} Brisanje porudžbine Aplikacija briše porudžbinu na
osnovu prosleđenog Id-ja

Nakon porudžbina kontrolera, prikazane su metode grupa porudžbina kontrolera.

Putanja: /api/orderGroups
Tabela 11 Lista metoda grupa narudžbina kontrolera

Metoda Parametar Naziv Opis


GET / Lista grupa Aplikacija vraća paginiranu listu
porudžbina grupa porudžbina
POST / Dodavanje grupe Aplikacija pravi novu grupu
porudžbina porudžbine na osnovu ulaznog
objekta
GET /danas Lista današnjih grupa Aplikacija vraća listu grupa
porudžbina porudžbina za današnji datum
GET /{grupaPorudžbinaId} Prikaz grupe Aplikacija vraća grupu
porudžbine na osnovu porudžbine za prosleđeni Id
Id-ja
DELETE /{grupaPorudžbinaId} Brisanje grupe Aplikacija briše grupu
porudžbina porudžbine za prosleđeni Id

Poslednji kontroler jeste stavka narudžbine kontroler. Sledi tabela metoda.

49
Putanja: /api/orderItems
Tabela 12 Lista metoda stavki porudžbine kontrolera

Metoda Putanja Naziv Opis


GET / Lista stavki Aplikacija vraća listu paginacije
porudžbine koja sadrži stavke porudžbine
POST / Dodavanje stavke Aplikacija pravi novu stavku
porudžbine porudžbine
GET /{stavkaPorudžbineId} Prikaz stavke Aplikacija vraća stavku
porudžbine na osnovu porudžbine za prosleđeni Id
Id-ja
PUT /{stavkaPorudžbineId} Ažuriranje stavke Aplikacija vrši ažuriranje stavke
porudžbine porudžbine na osnovu
prosleđenog Idja i objekta
DELETE /{stavkaPorudžbineId} Brisanje stavki Aplikacija briše stavku
porudžbine porudžbine sa prosleđenim Id-
jem

5.2. Implementacija korisničkog interfejsa unutar REACT okvira

Korisnički interfejs je implementiran upotrebom TypeScript jezika i React okvira Pored


osnovne React biblioteke korišćene su još i:

Tabela 13 Lista biblioteka korišćena pri izradi korisničkog interfejsa

Biblioteka Opis
SignalR Biblioteka koja omogućava komunikaciju u realnom vremenu sa
serverskom aplikacijom.
MUI Biblioteka za izradu korisničkih interfejsa. Korišćene su samo
ikonice.
Keycloak Biblioteka koja obezbeđuje komunikaciju sa Keycloak serverom.

50
Axios Biblioteka koja olakšava slanje HTTP zahteva i rukuje veb
servisima.
React Avatar Komponenta za prikazivanje korisničkih avatara. Korišćena za
pravljenje avatara na osnovu korisnikovih inicijala.
Redux Toolkit Biblioteka za upravljanje stanjem aplikacije, omogućava
centralizovanje podataka.
React Router Biblioteka za upravljanje rutama i navigiranjem unutar aplikacije.
React Spinners Biblioteka korišćena za animirani indikator učitavanja.
React Toastify Biblioteka za praćenje obaveštenja. Predstavlja elegantno rešenje
slanja notifikacija korisniku.

U okviru razvoja korisničkog interfejsa, akcenat je stavljen na razvoj skalabilne aplikacije, gde
je glavni fokus bio na organizaciji i strukturi koda zasnovanoj na modulima, umesto tradicionalnog
pristupa organizacije prema tipu podataka. Moduli predstavljaju funkcionalne jedinice, za svaki
mikroservis postoji jedan modul. Ovim se postiže veća fleksibilnost i održivost sistema. U cilju
održanja konzistentnosti razvoja, korišćen je SASS koji obezbeđuje efikasnost i skalabilnost pri
razvoju stilova korisničkog interfejsa. Definisani su globalni stilovi koji se koriste unutar svakog
modula, čime je izbegnuto pisanje istog koda na različitim mestima.
Ulaznu tačku React aplikacije predstavlja index.tsx fajl

const container = document.getElementById('root')!;


const root = createRoot(container);

const renderApp = () =>


root.render(
<Provider store={store}>
<App />
</Provider>
);

KeyCloakService.CallLogin(renderApp);

Listing 15 index.tsx

51
Eksplicitan poziv funkciji CallLogin čini da korisnik može da pristupi aplikaciji samo ukoliko je
ulogovan putem Keycloak servisa. Sledeći listing predstavlja implementaciju Keycloak servisa
unutar korisničkog interfejsa.

const Login = (onAuthenticatedCallback: Function) => {


keycloakInstance
.init({ onLoad: 'login-required' })
.then(function (authenticated) {
authenticated ? onAuthenticatedCallback() : alert('non authenticated');
})
.catch((e) => {
console.dir(e);
console.log(`keycloak init exception: ${e}`);
});
};

const UserId = () => keycloakInstance.tokenParsed?.sub!;

const UserName = () =>


keycloakInstance.tokenParsed?.given_name + ' ' + keycloakInstance.tokenParsed?.family_name;

const UserRoles = () => {


if (keycloakInstance.resourceAccess === undefined) return [];
else return keycloakInstance.resourceAccess['MyApp'].roles;
};

const Logout = keycloakInstance.logout;

const isLoggedIn = () => !!keycloakInstance.token;

const getToken = () => keycloakInstance.token;

const doLogin = keycloakInstance.login;

const updateToken = (successCallback: any) =>


keycloakInstance.updateToken(5).then(successCallback).catch(doLogin);

Listing 16 Keycloak servis unutar korisničkog interfejsa

Strukturu svakog modula čine: API pozivi, UI komponente, kontejneri koji su zaduženi za
logiku, tipovi podataka koji se odnose na taj modul, rute i isečak reduktora.

52
Kada se korisnik uspešno uloguje u aplikaciju, biva preusmeren na stranicu restorana ukoliko
ne postoji aktivno glasanje.

Slika 13 Prikaz stranice restorana korisničkog interfejsa

Stranica porudžbina predstavlja listu porudžbina koja sadrži paginaciju. Pored toga,
porudžbine se mogu filtrirati na osnovu restorana, tako da se korisniku omogućava jednostavan
način evidencije istorije porudžbina. Kancelarijskom menadžeru se mogućnosti proširuju. Naime,
on ima mogućnost evidencije svih korisnika. To mu pruža mogućnost praćenja finansija na nivou
cele kompanije.

53
Slika 14 Slika padajućeg menija pri zadršci na restoranu

Svaki korisnik ima mogućnost dodavanja novog restorana. Sledi prikaz stranice za
dodavanje restorana.

Slika 15 Stranica dodavanja novog restorana

Forma za kreiranje restorana je veoma jednostavna. Cilj je omogućiti korisnicima lako


dodavanje restorana.
Klikom na Voting navigaciono dugme, otvara se stranica glasanja. Glasanje je nedostupno
ukoliko ono nije prethodno dodato za dati dan. Sledeća slika predstavlja prikaz izgleda stranice

54
glasanja sa strane kancelarijskog menadžera, u slučaju kada glasanje nije otvoreno. Kancelarijski
menadžer jedini može da napravi novo glasanje.

Slika 16 Stranica glasanja kada glasanje nije otvoreno sa strance kancelarijskog menadžera

Kada je glasanje otvoreno, korisnici imaju pravo glasanja za restoran u kome žele da ručaju
tog dana.Pored liste restorana, nalazi se ispis koji prikazuje za koji restoran je svaki korisnik glasao
od momenta kada je pristupljeno datoj sesiji glasanja. Jedino kancelarijski menadžer ima pravo
zatvaranja glasanja.

Slika 17 Stranica glasanja pri otvorenom glasanju sa strance kancelarijskog menadžera

Nakon zatvaranja glasanja korisnik biva preusmeren na pravljenje porudžbine. Proces


pravljenja porudžbine zahteva izbor restorana i dodavanja stavki porudžbine. Na sledećoj slici
prikazan je izgled stranice za pravljenje porudžbine.

55
Slika 18 Stranica pravljenja porudžbine

Nakon napravljene porudžbine, tok korisnika se završava. Posao kancelarijskog menadžera


jeste unos cene dostave za sve grupe porudžbina koje su napravljene. U prikazanom primeru, to su
2 restorana.
Stranica restorana izlistava sve registrovane restorane. Predstavlja listu koja poseduje
paginaciju, postoji mogućnost izbor koliko će se elemenata nalaziti u listi, postoji mogućnost
pretrage restorana. Klikom na restoran, u novom tabu se otvara meni restorana. Ovo pruža
mogućnost korisnicima da pogledaju koje proizvode restorani poseduju na svojim menijima.
Zadrškom kursora na restoranu, pojavljuje se opcija otvaranja padajućeg menija koji poseduje
opcije brisanja i izmene restorana.

56
6.Ograničenja rešenja

Tokom izrade samog rada primećena su neka od ograničenja koja će u nastavku biti detaljno
objašnjena. Rešenje koje je detaljno objašnjeno u ovom radu, testirano je samo na lokalnoj mašini
pod ograničenim uslovima, što čini ponašanje rešenja pri velikom broju korisnika nepoznato.
Jedno od većih ograničenja ovog rešenja predstavlja i međusobna komunikacija mirkoservisa.
Implementirano rešenje može imati problema sa performantnošću i skalabilnošću. Takođe, javlja
se problem latencije koje može dovesti do lošeg korisničkog iskustva. Slanje HTTP zahteva ne
predstavlja najpouzdanije rešenje.
Jedan od potencijalno većih ograničenja ovog rešenja jeste nedostatak sigurnosti. Naime, jedini
vid zaštite aplikacije jeste pristupanje API Gateway-u. U slučaju napada koji će poslati zahtev
direktno na mikroservis, zaobilazeći API Gateway, napadač ima direktan pirstup podacima.
Implementacija Keycloak servisa je predstavljala imala svoje izazove koji predstavljaju
ograničenja upotrebe takvog servisa. Keycloak servis zahteva veoma složenu konfiguraciju čija
postavka zahteva posebno učenje. Implementacija unutar servisa i korisničkog interfejsa je
potrajala, dok se dovodi u pitanje koliko resursa zahteva tako jedan veliki servis.
Što se tiče domenskih ograničenja aplikacija je ograničena na 3 glavne oblasti: restorane,
glasanje i porudžbine. Korisnik nema mogućnost ponovnih upotrebi stavke narudžbine koje je
izabrao u prethodnim porudžbinama, već svaki put unosi nove stavke. Proces glasanja je striktno
ograničen na vremenski period koji zada kancelarijski menadžer.
Navedena ograničenja predstavljaju osnovu razmišljanja o daljim unapređenjima aplikacije.
Rešenja nekih ograničenja ne bi zahtevala puno vremena i resursa, sa druge strane postoje
ograničenja koja bi zahtevala preispitivanje čitavog dizajna arhitekture rešenja.

57
7.Zaključak i budući rad

Cilj ovog rada bio je implementacija mikroservisne aplikacije za automatizaciju procesa


naručivanja hrane. Kako bi se došlo do traženog rešenja, prvo su predstavljene teorijske osnove.
Tek na osnovu teorijske osnove i dobro definisanih zahteva prešlo se u proces dizajniranja rešenja.
Napravljena su 3 mikroservisa, 1 API Gateway, 1 Keycloak servis i 1 React aplikacija. Mikroservisi
i API Gateway su pisani unutar .NET Core veb aplikacija, a komunikacija sa bazom podataka
uspostavljena je upotrebom Entity Framework Core-a.
Kroz pokazani primer predstavljeno je rešenje koje može automatizovati proces naručivanja
hrane unutar organizacije. Evidencija zaposlenih se nalazi na jednom mestu, što potencijalno može
dovesti do povezivanja sa drugim aplikacijama organizacije čime će pristup svim aplikacijama
postati centralizovan.
Cilj ovog rada je postignut, dok postoji mogućnost dodatnih unapređenja implementiranog
sistema. Naime, u prethodnoj sekciji su predstavljena ograničenja implementiranog rešenja, čija bi
revizija mogla dovesti do optimizacije sistema i poboljšanja funkcionalnosti. Uticaj navedenih
ograničenja se može smanjiti ili eliminisati. Prvo unapređenje bi bila promena načina međusobne
komunikacije mikroservisa. Upotrebom magistrale događaja (bus event) arhitekture može biti
dobro unapređenje za postojeće rešenje zato što smanjuje potrebu direktnog kontakta između
mikroservisa. Komunikacija će se obavljati preko magistrale. Drugo veliko unapređenje može
predstavljati proveru autorizacije i autentifikacije na nivou svakog mikroservisa. Ovim će se
eliminisati mogućnost pristupa nekom mikroservisu zaobilaženjem API Gateway-a. Domensko
unapređenje moglo bi predstavljati dodavanje proizvoda u sklopu rešenja. Ovo bi značilo da svaki
restoran poseduje meni, koji sadrži proizvode. Izazov implementacije ovog ograničenja jeste
nepostojanje API-ja koji će pružiti informacije o tome koji restoran poseduje koje proizvode.
Mogućnost ručnog unosa predstavlja jednu od opcija, ali bi zahtevalo mnogo vremena kao i potrebu
za stalnim usklađivanjem sa aktuelnim proizvodima i cenama.
Implementacija rešenja kroz mikroservise predstavlja dobru praksu zato što postoji mogućnost
lake skalabilnosti i proširenja funkcionalnosti, pored lakšeg razumevanja domena. Razdvajanje
sadržaja na funkcionalnosti proprećeno je i pri implementaciji korisničkog interfejsa čime je
održana konzistentnost razvoja rešenja. Napravljeno je rešenje koje je lako razumljivo, fleksibilno

58
čime je osigurana agilnost pri daljim unapređenjima kako bi se zadovoljili budući korisnički
zahtevi.

59
Literatura

[1] „The birth of the Web,“ [Na mreži]. Available:


https://home.web.cern.ch/science/computing/birth-
web#:~:text=The%20first%20website%20at%20CERN,software%20in%20the%20public%
20domain.. [Poslednji pristup 14 10 2023].
[2] M. Flower i J. Lewis, „Martin Flower,“ [Na mreži]. Available:
https://www.martinfowler.com/articles/microservices.html.
[3] K. Gos i W. Yabierowski, „IEEE,“ [Na mreži]. Available:
https://ieeexplore.ieee.org/abstract/document/9109514.
[4] Microsoft, „Design interservice communication for microservices,“ [Na mreži]. Available:
https://learn.microsoft.com/en-us/azure/architecture/microservices/design/interservice-
communication.
[5] E. Evans, Domain-Driven Design: Tackling Complexity in the Heart of Software, 2003.
[6] Microsoft, „What is .NET? Introduction and overview,“ [Na mreži]. Available:
https://learn.microsoft.com/en-us/dotnet/core/introduction.
[7] Microsoft, „Overview of ASP.NET Core,“ [Na mreži]. Available:
https://learn.microsoft.com/en-us/aspnet/core/introduction-to-aspnet-core?view=aspnetcore-
7.0.
[8] Microsoft, „Entity Framework Core,“ [Na mreži]. Available: https://learn.microsoft.com/en-
us/ef/core/.
[9] Microsoft, „ASP.NET Core web API documentation with Swagger / OpenAPI,“ [Na mreži].
Available: https://learn.microsoft.com/en-us/aspnet/core/tutorials/web-api-help-pages-using-
swagger?view=aspnetcore-7.0.
[10 Facebook, „JSX,“ [Na mreži]. Available: https://facebook.github.io/jsx/.
]
[11 React, „Virtual DOM and Internals,“ [Na mreži]. Available:
] https://legacy.reactjs.org/docs/faq-

60
internals.html#:~:text=The%20virtual%20DOM%20(VDOM)%20is,a%20library%20such%
20as%20ReactDOM..
[12 Redux, „Redux Fundamentals, Part 2: Concepts and Data Flow,“ [Na mreži]. Available:
] https://redux.js.org/tutorials/fundamentals/part-2-concepts-data-flow.
[13 Redux, „What is Redux Toolkit?,“ [Na mreži]. Available: https://redux.js.org/redux-
] toolkit/overview#:~:text=Redux%20Toolkit%20makes%20it%20easier,of%20skill%20level
%20or%20experience..

61
Biografija

David Feješ je rođen 30. januara 1999. godine u Vršcu. U rodnom gradu upisuje osnovnu
školu „Jovan Sterija Popović“. Nakon završene osnovne škole, školovanje nastavlja u školskom
centru „Nikola Tesla“ u Vršcu. Visoko obrazovanje započinje 2017. godine na Fakultetu tehničkih
nauka Univerziteta u Novom Sadu, smer „Inženjerstvo informacionih sistema“. 2023. godine
započinje svoju profesionalnu karijeru, te iste godine završava osnovne studije te stiče zvanje
„Diplomirani inženjer informacionih tehnologija“.

62

You might also like