UPOTREBA WEB API SERVERA ZA POTREBE DRUGE WEB APLIKACIJE
koristeći GET, POST, PUT, DELETE pozive preko JAVASCRIPT-a
Da bi se testirao web API server mogu se koristiti neki od postojećih web klijenata : POSTMAN, OPEN API itd, ali će u ovom članku biti opisano kako se kreira jednostavna ASP.NET Core aplikacija koja se kreira koristeći samo HTML, CSS i Javascript i koja koristi web API aplikaciju kada je potrebno da smešta podatke u bazu , edituje ili potražuje podatke iz baze podataka.
Aplikacija treba da prikazuje listu nekih proizvoda, jednog ili više, da omogući kreiranje novog proizvoda, da menja podatke o proizvodu ili da ga briše iz baze podataka.
Da bi ovo ostvarila aplikacija, koju ćemo u ovom tekstu nazvati "WebAppProductsViewerForWebApi" treba da ostvari zahteve GET, POST, PUT, PATCH, DELETE ka WEB API serveru. Pri tome će obe aplikacije biti potignute na lokalnom računaru, ali će biti na različitom portu.
Adresa WEB API će biti: https://localhost:5001/, dok će web aplikacija koja sa njom komunicira biti podignuta na adresi: https://localhost:5021/
Početna strana ove aplikacije se može videti na sledećoj slici:
Aplikacija treba da prikazuje listu nekih proizvoda, jednog ili više, da omogući kreiranje novog proizvoda, da menja podatke o proizvodu ili da ga briše iz baze podataka.
Da bi ovo ostvarila aplikacija, koju ćemo u ovom tekstu nazvati "WebAppProductsViewerForWebApi" treba da ostvari zahteve GET, POST, PUT, PATCH, DELETE ka WEB API serveru. Pri tome će obe aplikacije biti potignute na lokalnom računaru, ali će biti na različitom portu.
Adresa WEB API će biti: https://localhost:5001/, dok će web aplikacija koja sa njom komunicira biti podignuta na adresi: https://localhost:5021/
Početna strana ove aplikacije se može videti na sledećoj slici:
Na slici se vidi lista proizvoda čiji se podaci nalaze u SQL Server bazi podataka, a sa kojom aplikacija komunicira preko web API servera. Da bi se prikazala pomenuta lista iz javascript-a se upućuje ajax GET zahtev koji vraća podatke o svim proizvodima. Iznad liste je "Istaknut proizvod", dakle jedan proizvod, čiji podaci će iz baze biti dobijeni takođe pomoću GET zahteva ali u ovom slučaju onog koji za poslat id proizvoda vraća podatke o jednom proizvodu.
Takođe se mogu uočiti dugmad "New", "Edit" i "Delete", čijim se klikom otvaraju nove stranice Create,html i Edit.html sa formama za unos u slučaju prva dva, dok se za brisanje(Delete eng.) poziva samo metoda koja je na istoj stranici "Index.html". Ovim se omogućava upućivanje ajax poziva za kreiranje novog(POST), izmenu određenog(PUT ili PATCH), i brisanje određenog proizvoda. Kompletno kreiranje ove aplikacije i analiza se može videti u priloženom video materijalu.
Takođe se mogu uočiti dugmad "New", "Edit" i "Delete", čijim se klikom otvaraju nove stranice Create,html i Edit.html sa formama za unos u slučaju prva dva, dok se za brisanje(Delete eng.) poziva samo metoda koja je na istoj stranici "Index.html". Ovim se omogućava upućivanje ajax poziva za kreiranje novog(POST), izmenu određenog(PUT ili PATCH), i brisanje određenog proizvoda. Kompletno kreiranje ove aplikacije i analiza se može videti u priloženom video materijalu.
Izrada WebAppProductsViewerForWebApi aplikacije-video materijal
video 1 |
video 2 |
video 3 |
video 4 |
Web aplikacija koja prikazuje listu proizvoda, je jednostavna aplikacija koja koristi HTML, CSS i javascript. Takođe koristi i bootstrap framework za stilizovanje i dodavanje funkcionalnosti. Deo početne index.html stranica je prikazana u nastavku, dok se kompletan kod može videti na adresi: github.com/slobodantrs/aspdotnet.git
Statički fajlovi se nalaze u wwwroot folderu, a kako se to podešava kreira pogledajte na strani: Servisiranje statičkih web strana pomoću web servera
Glavna funkcionalnost, odnosno pozivi ka web API aplikaciji koja komunicira sa bazom podataka se odvija u main.js fajlu.
$(document).ready(function () {onStartLoad();}); let table; async function onStartLoad() {//call getData function getData().then((data) => { loadDataList(data); }) .catch((error) => { alert("Unable to get items." + error); });const idFeature=3; getFeatureData(idFeature).then((data) => { prikazFeatureData(data); }) .catch((error) => { alert("Unable to get items." + error); }); //log the data} async function getData() {//await the response of the fetch call /*Poziv GET metode u web API aplikaciji*/ let response = await fetch("https://localhost:5001/products"); //proceed once the first promise is resolved. let data = await response.json(); //proceed only when the second promise is resolved return data;} async function loadDataList(data) {let product_list = document.querySelector("#productList"); table = document.createElement("table"); table.classList.add("productsTable"); product_list.appendChild(table); let i = 0; let row; for (key in data) {} async function getFeatureData(id) {var obj = data[key]; if (obj instanceof Object) {}if (i % 4 == 0) {}row = document.createElement("TR"); row.classList.add("d-flex"); row.classList.add("flex-row"); row.classList.add("justify-content-around"); //It has 4 div elements in a row table.appendChild(row); //Add row in the table} let h1Title = document.createElement("h2"); let priceParagraph = document.createElement("p"); let colorParagraph = document.createElement("p"); let sizeParagraph = document.createElement("p"); let quantityParagraph = document.createElement("p"); let btnDiv=document.createElement("div"); let aEdit=document.createElement("a"); let aDelete=document.createElement("a"); btnDiv.classList.add("d-flex"); aEdit.classList.add("btn"); aEdit.classList.add("btn-success"); aEdit.classList.add("text-white"); aEdit.setAttribute('href','edit.html?id='+obj.productId); aEdit.style.width = '100%'; aEdit.innerText = 'Edit'; aDelete.classList.add("btn"); aDelete.classList.add("btn-danger"); aDelete.classList.add("text-white"); aDelete.style.width = '100%'; aDelete.style.cursor = 'pointer'; aDelete.innerText = 'Delete'; const urlDel='https://localhost:5001/products/Delete/'+obj.productId; aDelete.onclick= function(){Delete(urlDel);}; h1Title.innerHTML = h1Title.innerHTML + obj.name; priceParagraph.innerHTML = priceParagraph.innerHTML + "Price: " + obj.price + " $"; colorParagraph.innerHTML = colorParagraph.innerHTML + "Color: " + obj.color; sizeParagraph.innerHTML = sizeParagraph.innerHTML + "Size: " + obj.size; quantityParagraph.innerHTML = quantityParagraph.innerHTML + "Quantity: " + obj.quantity; let column = document.createElement("TD"); column.appendChild(h1Title); column.appendChild(priceParagraph); column.appendChild(colorParagraph); column.appendChild(sizeParagraph); column.appendChild(quantityParagraph); column.appendChild(btnDiv);/*new*/ btnDiv.appendChild(aEdit);/*new*/ btnDiv.appendChild(aDelete);/*new*/ row.appendChild(column); i++;//await the response of the fetch call /*Poziv GET metode unutar web API aplikacije */ let response = await fetch("https://localhost:5001/products/"+id); //proceed once the first promise is resolved. let data = await response.json(); //proceed only when the second promise is resolved return data;} async function prikazFeatureData(data) {/*var dataArr = data["data"]; varijanta kad se spakuju podaci u JSON */ let nameOfArticleFeature = document.querySelector("#prod1"); let priceOfArticleFeature = document.querySelector("#prodPrice"); nameOfArticleFeature.innerHTML = data.name; priceOfArticleFeature.innerHTML = data.price + " $";} /*New*/ async function Delete(url) {await swal({}title: "Are you sure?", text: "You will not be able to recover this imaginary file!", icon: "warning", buttons: true, dangerMode: true,}).then((willDelete) => {if (willDelete) {});$.ajax({} else { }url: url, dataSrc: function (data) {});var json = JSON.parse(JSON.stringify(data)); return json;}, type: "DELETE", datatype: "json", success: function (data) {if (data.success) {},toastr.success(data.success); window.location.reload();} else {toastr.err(data.message);}
Javascript fajl prikazan iznad je statički fajl koji se nalazi u js folderu, koji je kao i ostali statički fajlovi unutar wwroot foldera. Ovaj fajl je povezan sa index.html stranicom pomoću script taga:
<script type="text/javascript" src="js/main.js"></script>
Prvo se izvršava onStartLoad() funkcija koja zatim zove getData() funkciju. Ona se izvršava asinhrono i ima za cilj da prikupi podatke o proizvodima, pozivajući web API aplikaciju, koja će podatke pročitati iz baze i vratiti Promise objekat. Kada se svi podaci prikupe pomoću json() funkcije se pretvaraju u JSON objekat, a zatim se taj objekat vraća iz funkcije getData() kao njena povratna vrednost.
Ukoliko je status odgovora korektan (200) izvršava se dalje then(data) i podaci prosleđuju funkciji loadDataList(data), u suprotnom će se izvršiti funkcija catch(error) kojoj se prosleđuje poruka o grešci. Ako su podaci uspešno vraćeni iz web API aplikacije dalje se prosleđuju funkciji loadDataList(data), u slučaju potraživanja cele liste proizvoda, a u slučaju potraživanja jednog proizvoda, pozvaće se metoda getFeatureData(idFeature). Obe ove metode treba da podatke postave na index.html stranicu. Prva pravi listu proizvoda, dok druga prikazuje istaknuti artikal čiji je id=3.
Ukoliko je status odgovora korektan (200) izvršava se dalje then(data) i podaci prosleđuju funkciji loadDataList(data), u suprotnom će se izvršiti funkcija catch(error) kojoj se prosleđuje poruka o grešci. Ako su podaci uspešno vraćeni iz web API aplikacije dalje se prosleđuju funkciji loadDataList(data), u slučaju potraživanja cele liste proizvoda, a u slučaju potraživanja jednog proizvoda, pozvaće se metoda getFeatureData(idFeature). Obe ove metode treba da podatke postave na index.html stranicu. Prva pravi listu proizvoda, dok druga prikazuje istaknuti artikal čiji je id=3.
Kroz ovaj primer je pokazano kako web aplikacija koja u ovom slučaju ima funkciju klijenta, i upućuje zahteve web API servisu, potražujući podatke iz neke baze podataka. U ovom slučaju je pokazano kako se preko javacript-a prave ajax GET zahtevi.
Kompletan kod je dat na GitHub-u, dok sledeća tabela prikazuje kako da se formiraju i ostali ajax pozivi ka web API servisu, koji će proizvesti POST, PUT i DELETE zahteve.
Kompletan kod je dat na GitHub-u, dok sledeća tabela prikazuje kako da se formiraju i ostali ajax pozivi ka web API servisu, koji će proizvesti POST, PUT i DELETE zahteve.
WEB APLICATION | WEB API | ||
---|---|---|---|
description | ajax call | called method | returning value |
Zahtev za listu proizvoda | //await the response of the fetch call |
GetAllProducts() |
Task < ActionResult < IEnumerable < Product > > > |
Zahtev za proizvod sa određenim ID-om | "
//await the response of the fetch call |
GetProduct(int id) |
Task < ActionResult < Product > >
|
Unošenje novog proizvoda u bazu podataka | var uriCreate = uri + "/Create"; |
Post(Product product) |
Task < ActionResult < int > > |
Ažuriranje određenog proizvoda | var uriUpdate = uri + "/Update"; |
PutAsync(int id,Product product)
|
Task < ActionResult < int > >
|
Brisanje određenog proizvoda | const urlForDelete="..."; |
DeleteProduct(int id)
|
Task< ActionResult < int > >
|