I förra inlägget sade jag att REST var ett designmönster där man använder HTTP som applikationsprotokoll, inte som i SOAP som försöker vara protokollagnostiskt och som betraktar HTTP som ett transportprotokoll, ett slags TCP som kan ta sig genom brandväggar.
Nå, att REST använder HTTP som applikationsprotokoll betyder att applikationer skrivna efter REST-mönstret ärver egenskaperna från den kommunikationsmodell som HTTP bygger på.
Detta är ju inget konstigt. SOAP ärver egenskaperna från sin kommunikationsmodell. SOAPs modell kan vi kalla för RPC-modellen som i sin tur är en distribuerad variant av den vanliga ”message passing object oriented”-modellen (Java, C++, m fl).
Message-passing, det betyder att all interaktion med ett objekt går ut på att man skickar ett meddelande till det objektet (populärt kallat: ”anropa en metod på objektet”). Oavsett vad meddelandet ska göra (ta bort, lägga till, förändra, ingenting).
I RPC-modellen finns det ett ”objekt” (eller egentligen ett interface) på en annan datamaskin. Metoderna i detta interface kan man anropa, nästan som vore de lokala anrop (i alla fall är det så det ska kännas). Det är RPC-modellens styrka: den imiterar lokala anrop så gott det går. Och så funkar ju EJB, så funkar CORBA, så funkar XML-RPC och så funkar SOAP:
//ganska begripligt interface, enkelt att omvandla till
//distribuerat objekt såsom SOAP, CORBA EJB m fl.
public Customer findCustomer( String searchString);
public void saveCustomer( Customer customer);
public void removeCustomer( String customerId);
public double getCurrencyMultiplier( String currencyIso);
public String[] getCurrencies();
REST å sin sida handlar om webben. Och webben är bland annat följande:
- En gigantisk samling resurser, som oavsett vad de är för något, är åtkomliga via varsin URL. På lika villkor.
- En plats där man enkelt kan be om en resurs, och den kommer till en i form av en radda oktetter (bytes). Oavsett om det är ett foto eller om det är en väderprognos eller om det är ett javaprogram. På lika sätt.
- Även om webben är agnostisk i vad den skickar, så meddelar den prydligt vad oktettströmmen ska tolkas som: text/plain, image/png, application/x-java-jnlp-file, x-whatever/x-from-the-future.
- Att be om en resurs kallas för GET. Det finns även PUT för att placera en resurs på en URL, och DELETE för att ta bort en resurs på en URL.
- Det handlar om en tillståndslös kommunikation. I grund och botten struntar protokollet HTTP i om du bad om en viss resurs alldeles nyss, för HTTP är alla anrop lika. Tillståndet bestäms istället av vilken resurs klienten råkar titta på för tillfället.
- Däremot innehåller protokollet sätt att be en användare identifiera och autentiera sig, vilket ju är det vanligaste skälet till att man alls vill ha sessioner. Men autentieringen och auktorisationen äger alltså rum en gång per anrop.
Vad innebär denna skillnad? Jo…
Webbmodellen stödjer tre specialmeddelanden: Hämta resurs, Spara resurs, Ta bort resurs. Verben GET, PUT och DELETE. Precis som ett filsystem, fast med globalt åtkomliga objekt.
Kan du nu förklara för mig hur gränssnittet ovan (findCustomer() osv) skulle kunna se ut, om man istället tänkte i REST-banor?
Helt riktigt. När man modellerar system, så inser man att dessa tre verb är tillämpliga på i stort sett alla objekt. PUT är en införande, eller en förändrande, händelse, DELETE är en borttagande händelse. GET är ju helt enkelt att betrakta ett objekt, en betraktande händelse, en händelse som inte ska påverka objektet självt.
Vi ser att alla metoderna i vårt interface ovan är av dessa tre slag. Fast för olika resurser:
GET /customers?name~Ola*
GET /currencies
GET /currencies/USD
PUT /customers/Ola
DELETE /customers/Ola
Nästa gång ska vi titta mer på varför och hur.