REST vs WebSockets

1. Pregled

U ovom uputstvu proći ćemo kroz osnove komunikacije klijent-poslužitelj i istražiti to kroz dvije danas dostupne popularne opcije. Vidjet ćemo kako se WebSocket, koji je novi član, uspoređuje s popularnijim izborom RESTful HTTP-a.

2. Osnove mrežne komunikacije

Prije nego što zaronimo u detalje različitih opcija i njihove zasluge i nedostatke, osvježimo brzo krajolik mrežne komunikacije. To će vam pomoći da stvari stavite u perspektivu i ovo bolje razumijete.

Mrežne komunikacije najbolje se mogu razumjeti u smislu modela interkonekcije otvorenih sustava (OSI).

OSI model razdvaja komunikacijski sustav na sedam slojeva apstrakcije:

Na vrhu ovog modela nalazi se aplikacijski sloj koji nas zanima u ovom vodiču. Međutim, razgovarat ćemo o nekim aspektima u gornja četiri sloja dok uspoređujemo WebSocket i RESTful HTTP.

Aplikacijski sloj najbliži je krajnjem korisniku i odgovoran je za međusobno povezivanje s aplikacijama koje sudjeluju u komunikaciji. Postoji nekoliko popularnih protokola koji se koriste u ovom sloju poput FTP, SMTP, SNMP, HTTP i WebSocket.

3. Opisivanje WebSocket-a i RESTful HTTP-a

Iako se komunikacija može dogoditi između bilo kojeg broja sustava, nas posebno zanima komunikacija klijent-poslužitelj. Točnije, usredotočit ćemo se na komunikaciju između web preglednika i web poslužitelja. Ovo je okvir koji ćemo koristiti za usporedbu WebSocket-a s RESTful HTTP-om.

Ali prije nego što nastavimo dalje, zašto ne bismo brzo shvatili što su oni!

3.1. WebSockets

Kako formalna definicija ide, WebSocket je komunikacijski protokol koji sadrži dvosmjernu, full-duplex komunikaciju putem trajne TCP veze. Sad ćemo detaljno razumjeti svaki dio ove izjave.

WebSocket je IETF standardizirao kao komunikacijski protokol 2011. godine kao RFC 6455. Većina modernih web preglednika danas podržava protokol WebSocket.

3.2. ODMAH HTTP

Iako smo svi svjesni HTTP-a zbog njegove sveprisutne prisutnosti na Internetu, on je također komunikacijski protokol na aplikacijskom sloju. HTTP je protokol zasnovan na zahtjevu i odgovoru, opet ćemo to kasnije bolje razumjeti u vodiču.

REST (Reprezentativni državni prijenos) je arhitektonski stil koji postavlja niz ograničenja na HTTP za stvaranje web usluga.

4. Podprotokol WebSocket

Iako WebSocket definira protokol za dvosmjernu komunikaciju između klijenta i poslužitelja, ne postavlja nikakav uvjet za poruku koju treba razmijeniti. Ovo se ostavlja otvorenim za strane u komunikaciji da se dogovore u sklopu pregovora o potprotokolu.

Nije prikladno razviti podprotokol za netrivijalne primjene. Srećom, postoje mnogi popularni potprotokoli poput STOMP-a dostupni za upotrebu. STOMP je skraćenica od Simple Text Oriented Messaging Protocol i radi preko WebSocket-a. Spring Boot ima prvorazrednu podršku za STOMP, što ćemo iskoristiti u našem vodiču.

5. Brzo postavljanje u Spring Boot

Nema ništa bolje od gledanja radnog primjera. Dakle, sagradit ćemo jednostavne slučajeve korištenja i u WebSocketu i u RESTful HTTP-u da bismo ih dalje istražili, a zatim usporedili. Stvorimo jednostavnu komponentu poslužitelja i klijenta za oboje.

Stvorit ćemo jednostavan klijent koristeći JavaScript koji će poslati ime. I stvorit ćemo poslužitelj koji koristi Javu koji će odgovoriti pozdravom.

5.1. WebSocket

Da bismo koristili WebSocket u Spring Boot-u, trebat će nam odgovarajući pokretač:

 org.springframework.boot spring-boot-starter-websocket 

Sada ćemo konfigurirati STOMP krajnje točke:

@Configuration @EnableWebSocketMessageBroker javna klasa WebSocketMessageBrokerConfig provodi WebSocketMessageBrokerConfigurer {@Override public void registerStompEndpoints (StompEndpointRegistry registry) {registry.addEndpoint ("/ ws"; } @Override public void configureMessageBroker (MessageBrokerRegistry config) {config.setApplicationDestinationPrefixes ("/ app"); config.enableSimpleBroker ("/ tema"); }}

Idemo brzo definirati jednostavan poslužitelj WebSocket koji prihvaća ime i odgovara pozdravom:

@Controller javna klasa WebSocketController {@MessageMapping ("/ hello") @SendTo ("/ topic / greetings") javni pozdravni pozdrav (poruka poruke) baca iznimku {return new Greeting ("Hello," + HtmlUtils.htmlEscape (message.getName ()) + "!"); }}

Na kraju, izgradimo klijenta za komunikaciju s ovim WebSocket poslužiteljem. Kako ističemo komunikaciju između preglednika i poslužitelja, kreirajmo klijenta u JavaScript-u:

var stompClient = null; funkcija connect () {stompClient = Stomp.client ('ws: // localhost: 8080 / ws'); stompClient.connect ({}, funkcija (okvir) {stompClient.subscribe ('/ topic / greetings', function (response) {showGreeting (JSON.parse (response.body) .content);});}); } funkcija sendName () {stompClient.send ("/ app / hello", {}, JSON.stringify ({'name': $ ("# name"). val ()})); } funkcija showGreeting (poruka) {$ ("# pozdrav"). append (""+ poruka +""); }

Ovo dovršava naš radni primjer poslužitelja i klijenta WebSocket. U spremištu koda postoji HTML stranica koja pruža jednostavno korisničko sučelje za interakciju.

Iako ovo samo grebe površinu, WebSocket s Springom može se koristiti za izgradnju složenih klijenata za chat i još više.

5.2. ODMAH HTTP

Sada ćemo proći kroz sličnu postavku za uslugu RESTful. Naša jednostavna web usluga prihvatit će GET zahtjev s imenom i odgovoriti pozdravom.

Umjesto toga, ovaj put upotrijebimo web pokretač Spring Boota:

 org.springframework.boot spring-boot-starter-web 

Sada ćemo definirati krajnju točku REST koristeći snažnu podršku za napomene dostupnu na proljeće:

@RestController @RequestMapping (path = "/ rest") javna klasa RestAPIController {@GetMapping (path = "/ {name}", produce = "application / json") javni niz getGreeting (@PathVariable ("name") Naziv niza) {return "{\" pozdrav \ ": \" Pozdrav, "+ ime +"! \ "}"; }}

Na kraju, kreirajmo klijenta u JavaScript-u:

var request = nova XMLHttpRequest () funkcija sendName () {request.open ('GET', '// localhost: 8080 / rest /' + $ ("# name"). val (), true) request.onload = function () {var data = JSON.parse (this.response) showGreeting (data.greeting)} request.send ()} funkcija showGreeting (poruka) {$ ("# greetings"). append (""+ poruka +""); }

To je poprilično to! Opet, u spremištu koda postoji HTML stranica za rad s korisničkim sučeljem.

Iako dubok u svojoj jednostavnosti, definiranje REST API-ja proizvodnog razreda može biti puno opsežniji zadatak!

6. Usporedba WebSocket-a i RESTful HTTP-a

Stvorivši minimalne, ali radne primjere WebSocket-a i RESTful HTTP-a, sada smo spremni shvatiti kako se međusobno slažu. To ćemo ispitati prema nekoliko kriterija u sljedećim pododjeljcima.

Važno je napomenuti da, iako možemo izravno usporediti HTTP i WebSocket jer su oba protokoli aplikacijskog sloja, nije prirodno uspoređivati ​​REST s WebSocketom. Kao što smo ranije vidjeli, REST je arhitektonski stil koji koristi HTTP za komunikaciju.

Stoga naša usporedba s WebSocketom uglavnom će se odnositi na mogućnosti HTTP-a ili njihov nedostatak.

6.1. URL shema

URL definira jedinstveno mjesto web izvora i mehanizam za njegovo dohvaćanje. U komunikaciji klijent-poslužitelj, često želimo dobiti statične ili dinamičke resurse putem njihovog povezanog URL-a.

Svima nam je poznata shema HTTP URL-a:

// localhost: 8080 / odmor

Shema URL-a WebSocket ne razlikuje se puno:

ws: // localhost: 8080 / ws

Na početku se čini da su jedina razlika likovi pred dvotočkom, ali apstrahira puno toga što se događa ispod haube. Istražimo dalje.

6.2. Rukovanje

Rukovanjeodnosi se na automatski način pregovaranja o komunikacijskom protokolu između strana koje komuniciraju. HTTP je protokol bez državljanstva i radi u mehanizmu zahtjeva i odgovora. Na svakom HTTP zahtjevu uspostavlja se TCP veza s poslužiteljem preko utičnice.

Klijent zatim čeka dok poslužitelj ne odgovori resursom ili pogreškom. Sljedeći zahtjev klijenta ponavlja sve kao da se prethodni zahtjev nikada nije dogodio:

WebSocket djeluje vrlo različito u usporedbi s HTTP-om i započinje rukovanjem prije stvarne komunikacije.

Pogledajmo što obuhvaća rukovanje WebSocketom:

U slučaju WebSocket, klijent pokreće zahtjev za protokolom za rukovanje u HTTP-u, a zatim čeka dok poslužitelj ne odgovori prihvaćajući nadogradnju na WebSocket s HTTP-a.

Naravno, budući da se Handshake protokola događa preko HTTP-a, on slijedi slijed iz prethodnog dijagrama. No, nakon uspostavljanja veze, klijent i poslužitelj prelaze na WebSocket za daljnju komunikaciju.

6.3. Veza

Kao što smo vidjeli u prethodnom pododjeljku, jedna značajna razlika između WebSocket-a i HTTP-a jest ta što WebSocket radi na trajnoj TCP vezi, dok HTTP stvara novu TCP vezu za svaki zahtjev.

Sada očito stvaranje nove TCP veze za svaki zahtjev nije vrlo učinkovito, a HTTP toga nije bio svjestan. Zapravo, kao dio HTTP / 1.1, uvedene su trajne veze kako bi se umanjio ovaj nedostatak HTTP-a.

Štoviše, WebSocket je dizajniran od temelja za rad s trajnim TCP vezama.

6.4. Komunikacija

Prednost WebSocket-a nad HTTP-om specifičan je scenarij koji proizlazi iz činjenice da klijent može poslužitelju komunicirati na načine koji sa dobrim starim HTTP-om nisu bili mogući.

Na primjer, u HTTP-u obično klijent pošalje taj zahtjev, a zatim poslužitelj odgovara traženim podacima. Ne postoji generički način da poslužitelj samostalno komunicira s klijentom. Naravno, napravljeni su obrasci i rješenja kako bi se to zaobišlo poput Server-Sent Events (SSE), ali to nije bilo potpuno prirodno.

Uz WebSocket, radeći preko trajne TCP komunikacije, moguće je i poslužitelju i klijentu da šalju podatke neovisno jedni o drugima, i zapravo, mnogim stranama u komunikaciji! To se naziva dvosmjernom komunikacijom.

Još jedna zanimljiva značajka WebSocket komunikacija je u tome što je full-duplex. Sada, iako ovaj izraz može zvučati ezoterično; to jednostavno znači i poslužitelj i klijent mogu istovremeno slati podatke. Usporedite to s onim što se događa u HTTP-u gdje poslužitelj mora pričekati dok ne primi zahtjev u cijelosti prije nego što može odgovoriti podacima.

Iako blagodati dvosmjerne i full-duplex komunikacije možda neće biti očite odmah. vidjet ćemo neke slučajeve upotrebe u kojima otključavaju stvarnu snagu.

6.5. Sigurnost

Posljednje, ali ne najmanje važno, i HTTP i WebSocket iskorištavaju prednosti TLS-a za sigurnost. Dok HTTP nudi https kao dio njihove URL sheme da to koriste, WebSocket ima wss kao dio njihove URL sheme za isti učinak.

Dakle, zaštićena verzija URL-ova iz prethodnog pododjeljka trebala bi izgledati ovako:

// localhost: 443 / rest wss: // localhost: 443 / ws

Osiguravanje usluge RESTful ili WebSocket komunikacije predmet je velike dubine i ovdje se ne može obrađivati. Za sada, recimo samo da su obojica adekvatno podržani u tom pogledu.

6.6. Izvođenje

Moramo shvatiti da je WebSocket protokol s statusom u kojem se komunikacija odvija putem namjenske TCP veze. S druge strane, HTTP je u biti protokol bez državljanstva. To utječe na njihovu izvedbu s opterećenjem, ali to stvarno ovisi o slučaju upotrebe.

Budući da se komunikacija putem WebSocket-a odvija putem TCP veze za višekratnu upotrebu, općeniti troškovi po poruci niži su u usporedbi s HTTP-om. Stoga može doseći veću propusnost po poslužitelju. Ali postoji ograničenje do kojeg se jedan poslužitelj može prilagoditi i tu WebSocket ima problema. Nije lako horizontalno skalirati programe s WebSockets.

Ovdje svijetli HTTP. S HTTP-om svaki novi zahtjev može potencijalno doći na bilo koji poslužitelj. To implicira da za povećanje ukupne propusnosti možemo lako dodati više poslužitelja. To potencijalno ne bi trebalo imati utjecaja na aplikaciju koja radi s HTTP-om.

Očito je da sama aplikacija možda treba ljepljivost stanja i sesije što joj može olakšati izricanje nego učiniti.

7. Gdje ih trebamo koristiti?

Sada smo vidjeli dovoljno RESTful usluge putem HTTP-a i jednostavne komunikacije putem WebSocket-a da stvorimo svoje mišljenje o njima. Ali gdje bismo što trebali koristiti?

Važno je zapamtiti da iako je WebSocket nastao zbog nedostataka HTTP-a, to zapravo nije zamjena HTTP-a. Dakle, oboje imaju svoje mjesto i svoju upotrebu. Hajde brzo shvatiti kako možemo donijeti odluku.

Za glavninu scenarija tamo gdje je potrebna povremena komunikacija s poslužiteljem poput dobivanja evidencije zaposlenika, i dalje je razumno koristiti REST uslugu putem HTTP / S. No, za novije klijentske programe poput aplikacija za cijene dionica koje zahtijevaju ažuriranja u stvarnom vremenu s poslužitelja, vrlo je prikladno koristiti WebSocket.

Generalizirajući, WebSocket prikladniji je za slučajeve kada komunikacija temeljena na push-u i u stvarnom vremenu zahtjev prikladnije definira. Dodatno, WebSocket dobro funkcionira za scenarije u kojima poruku treba istodobno gurnuti na više klijenata. To su slučajevi u kojima će komunikacija klijenta i poslužitelja putem RESTful usluga biti teška, ako ne i prevelika.

Ipak, korištenje WebSocket i RESTful usluga putem HTTP-a mora se izvući iz zahtjeva. Kao što ne postoje srebrni meci, ne možemo samo očekivati ​​da ćemo odabrati jedan za rješavanje svakog problema. Stoga svoju mudrost, zajedno sa znanjem, moramo koristiti u dizajniranju učinkovitog komunikacijskog modela.

8. Zaključak

U ovom smo uputstvu pregledali osnove mrežne komunikacije s naglaskom na protokolima aplikacijskog sloja HTTP i WebSocket. Vidjeli smo nekoliko brzih demonstracija WebSocket-a i RESTful API-ja preko HTTP-a u Spring Boot-u.

I na kraju, usporedili smo značajke HTTP i WebSocket protokola i ukratko razgovarali o tome kada ih koristiti.

Kao i uvijek, kod za primjere dostupan je na GitHub-u.