# RESTful arhitektura (Web API) Ovaj materijal je dio Ishoda 2 (željeno). ## 7 Korištenje Web API aplikacije Statičke stranice u ASP.Net Core: - https://learn.microsoft.com/en-us/aspnet/core/fundamentals/static-files?view=aspnetcore-8.0 JavaScript jQuery AJAX metode: - https://api.jquery.com/jQuery.ajax/ - https://api.jquery.com/jQuery.get/ JavaScript Fetch API: - https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API JavaScript localStorage: - https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage/ ### Postavljanje baze podataka SQL Server Management Studio: - stvorite bazu podataka `Exercise7` - stvoriti strukturu baze podataka s podacima - struktura dio 1 (glavni entiteti): https://pastebin.com/5MTPzxrd - struktura dio 2 (autentifikacija): https://pastebin.com/9wsPtAV1 - podaci: https://pastebin.com/iwuDcyKx ### Postavljanje Web API aplikacije Raspakirajte arhivu `dwa-tasks-7-en.zip`. Koristit ćemo to rješenje kao Web API poslužitelj. > Kako je napravljena ta aplikacija? > Iskoristili smo sve što smo naučili o Web API RESTful servisu za izradu ove aplikacije: > > - kreirano novo Web API rješenje u Visual Studiju: > - naziv rješenja i projekta: exercise-07 > - isključena HTTPS podrška > - instalirana EF podrška: > - `dotnet tool install --global dotnet-ef --version 7` > - `dotnet add package Microsoft.EntityFrameworkCore --version 7` > - `dotnet add package Microsoft.EntityFrameworkCore.Design --version 7` > - `dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 7` > - instalirana JWT podrška: > - `dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer --version 7` > - `dotnet add package Microsoft.AspNetCore.Authentication.OpenIdConnect --version 7` > - konfiguriran EF connection string u `appsettings.json` > ```JSON > "ConnectionStrings": { > "AppConnStr": "server={your server};Database=Exercise7;User=sa;Password=SQL;TrustServerCertificate=True;MultipleActiveResultSets=true" > } > ``` > - "reverse engineered" baza podataka (stvorene klase entiteta i kontekst baze podataka prema stvarnoj bazi podataka) > - `dotnet ef dbcontext scaffold "Name=ConnectionStrings:AppConnStr" Microsoft.EntityFrameworkCore.SqlServer -o Models --force` > - postavljen kontekst u `Program.cs` da bude dostupan DI spremniku > ```C# > builder.Services.AddDbContext(options => { > options.UseSqlServer("name=ConnectionStrings:AppConnStr"); > }); > ``` > - konfiguriran JWT u `appsettings.json` (samo sigurnosni ključ) > ```JSON > "JWT": { > "SecureKey": "1xvawozgzh78q2m9xpdlshegaqaspkpe" > } > ``` > - konfigurirana JWT usluga i međuprogram u `Program.cs`: > > ```C# > // Configure JWT security services > var secureKey = builder.Configuration["JWT:SecureKey"]; > builder.Services > .AddAuthentication(JwtBearerDefaults.AuthenticationScheme) > .AddJwtBearer(o => { > var Key = Encoding.UTF8.GetBytes(secureKey); > o.TokenValidationParameters = new TokenValidationParameters > { > ValidateIssuer = false, > ValidateAudience = false, > IssuerSigningKey = new SymmetricSecurityKey(Key) > }; > }); > ``` > > ```C# > // Use authentication / authorization middleware > app.UseAuthentication(); > app.UseAuthorization(); // -> this should already be present > ``` > > - stvorena pomoćna klasa `JwtTokenProvider` koja obrađuje JWT: https://pastebin.com/ZnD36wjb > - u `Program.cs` dodana JWT podrška za Swagger login (za potrebe testiranja): https://pastebin.com/YdqbDfWy > - stvorena pomoćna klasa `PasswordHashProvider` za kriptografsku obradu raspršenja (engl. hash) lozinke: https://pastebin.com/buxhBfZx > - stvoren `UserController` koji upravlja registracijom i prijavom > - vidi `UserController` za detalje (objašnjeno u prethodnim vježbama) > - stvorene DTO klase za registraciju i prijavu: `UserRegisterDto` i `UserLoginDto` > - kreiran `AudioController` koji koristi `Audio` entitet s 1-na-N `Genre` i M-na-N `Tag` entitetima > - stvoren `AudioDto` > - stvorena klasa za mapiranje > - osigurano da neke radnje u `AudioControlleru` budu dostupne korisniku koji je prijavljen > - koristeći atribut `[Authorize]` > - osigurane su akcije `GetAll()`, `Post()`, `Put()` i `Delete()` > - samo akcije `Search` i `Get(int id)` nisu osigurane ## 7.1 Omogućavanje statičkih stranica u projektu Kada dohvaćamo podatke s web API poslužitelja, obično koristimo _statičke_ HTML stranice za dohvaćanje podataka s našeg poslužitelja. Statičke stranice su konvencionalno u mapi `wwwroot` korijenske mape projekta. - stvorite mapu `wwwroot` u korijenu projekta - možete vidjeti da izgleda drugačije, radi se o posebnoj mapi - stvorite `audios.html` statičku HTML stranicu u mapi `wwwroot` (desni gumb, Add > New Item..., filtrirajte "html") - dodajte sadržaj `

Audio list


` na stranicu - također morate podržati statičke datoteke pomoću odgovarajućeg međuprograma - dodajte međuprogram `app.UseStaticFiles()` u Program.cs - dodajte ga prije `app.UseAuthentication()` kako biste izbjegli provjeru JWT autentifikacijskog tokena prilikom dohvaćanja statičkih datoteka; ako biste ga dodali nakon toga, trebali biste slati JWT token za svaku od statičkih datoteka Testirajte svoju stranicu: - pokrenite aplikaciju - otvorite http://localhost:5127/audios.html u pregledniku Imajte na umu da ćete koristiti JavaScript za dohvaćanje podataka sa svoje krajnje točke. Uvijek možete koristiti jQuery da vam pomogne sa zahtjevima i rukovanjem DOM-om: - idite na https://releases.jquery.com/, odjeljak **jQuery 3.x** - kliknite minificirau verziju i kopirajte tag skripte - zalijepite ga u svoj HTML neposredno prije završetka body taga ## 7.2 Dohvaćanje podataka iz nezaštićenog izvora 1. Pronađite točnu adresu krajnje točke Lako ga je konstruirati pomoću atributa usmjeravanja, ali također možete koristiti Swagger. - pokrenite aplikaciju - koristite krajnju točku `/api/Audio/{id}` u Swaggeru da biste dobili jedan određeni audio sadržaj (npr. id=3) - obratite pažnju na polje `Request URL`, ono sadrži URL - e.g. `http://localhost:5127/api/Audio/3` 2. Provjerite radi li JavaScript Provjerite možete li stvarno koristiti JavaScript u svojim postavkama - dodajte tag Vaše skripte nakon prvog taga `jQuery` skripte - dodajte sljedeću skriptu: ```JavaScript $(function () { console.log("DOM ready"); }); ``` - u Development Tools alatu preglednika provjerite je li odgovarajuća poruka nakon učitavanja stranice ispisana u konzoli 3. Izdajte zahtjev i logirajte odgovor Sada možete zamijeniti jedan poziv `console.log()` dohvaćanjem podataka s vaše krajnje točke poslužitelja: ```JavaScript $(function () { let url = "http://localhost:5127/api/Audio/3"; $.get(url, function (data) { console.log(data); }); }); ``` > Imajte na umu da također možete koristiti u preglednik ugrađeni (engl. native) JavaScript API za dohvaćanje bez jQueryja. Za to koristite `async` funkciju u svojoj skripti > > ```JavaScript > document.addEventListener("DOMContentLoaded", async function () { > let url = "http://localhost:5127/api/Audio/3"; > const response = await fetch(url); > const data = await response.json(); > console.log(data); > }); > ``` ## 7.3 Rukovanje greškama Za rukovanje pogreškama u jQuery zahtjevu morate dodati `.fail()` rukovatelj pogreškama odmah nakon `$.get()`. To se radi pomoću tzv. "fluent interface" API-a. ```JavaScript $(function () { let url = "http://localhost:5127/api/Audio/5"; $.get(url, function (data) { console.log(data); }).fail(function() { console.error("There was an error while trying to load your data"); }) }); ``` > Napomena: kada koristite Fetch API, rukovanje pogreškama se vrši pomoću standardne sintakse try/catch. > Primjer: > > ```JavaScript > try { > const response = await fetch(url); > const data = await response.json(); > console.log(data); > } catch (error) { > console.error(`Request error: ${error.message}`); > } > ``` ## 7.4 Korištenje DOM-a Upotrijebimo rukovanje DOM-om za prikaz podataka na našoj stranici. Dodajte rezervirano mjesto (engl. placeholder) za prikaz podataka na vašoj stranici. ```HTML
``` Umjesto upotrebe `console.log`, generirajte podatke pomoću jQueryja. Na primjer: ```JavaScript $("#placeholder").append("