En introduksjon til REST

Tue 02 August 2011

Dette er første artikkelen av en kort serie som skal vise hvordan vi kan lage en RESTful webservice i Java. Før vi ser på konkrete eksempler og verktøy må vi vite litt om hva REST er.

REST er forkortelse for "REpresentational State Transfer", og er et sett med regler som kan brukes for å designe et system. REST er først beskrevet av Roy Fielding i en PhD oppgave som ble publisert i 2000. Les mer om REST historien her: http://en.wikipedia.org/wiki/Representational_State_Transfer

Følgende punkter må være oppfyllt for at vi skal få et RESTful system:

  • Det må være et klient-server system.
  • Det må være tilstandsløst (stateless), med andre ord skal det ikke være behov for tjenesten å huske sesjoner. Hvert kall skal være uavhengig av hverandre.
  • Det må støtte cache system.
  • Hver ressurs må ha en unik adresse og et gyldig akesesspunkt.
  • Det må være lagdelt og skalerbart.
  • Det bør tilby "code on demand", men dette er valgfritt.

Et viktig poeng er at punktene ikke sier noe om teknologien som brukes. De definerer utelukkende hvordan data sendes mellom komponenter. På bakgrunn av dette kan et RESTful system implementeres i hvilken som helst nettverksarkitektur.

Et eksempel på et RESTful system er den statiske weben. Den støtter caching, er tilstandsløs og URLer peker til spesifikke filer (f.eks html) på webserveren. Dynamisk web derimot bryter som oftest med et eller flere av punktene over, som oftest grunnet bruk av sessions (på serversiden) eller cookies (på klientsiden).

Bestanddelene i et RESTful system

Vi har fire bestanddeler i et system som er RESTful. Under kommer en liten forklaring på hver av de.

Ressurser

En ressurs er noe som er adresserbart over web. Med andre ord noe som kan aksesseres og overføres mellom klient og server. En ressurs kan blant annet være en htmlfil, en flashfilm eller et bilde. Hvilken type ressurs det er snakk om bestemmes ved å sette content-type i headeren.

Represantasjoner

En representasjon er det som overføres mellom klient og server. Det består av en binærstøm og metadata som beskriver hvordan strømmen skal tolkes av klient / server. En representasjon kan f.eks være et bilde, en tekstfil, xmlstrøm eller en jsonstrøm. Er klienten en nettleser får vi ofte tilbake representasjonen av ressursen i form av en nettside (htmldokument), mens kommunikasjon imellom webservices gjerne benytter seg av en mer effektiv representasjon som xml.

URIs

URI er en forkortelse for "Uniform Resource Identifier" og er en link til en ressurs. Dette er den eneste måten klient og server kan snakke sammen på. Når vi snakker om RESTful webtjenester, er URI en hyperlink siden vi bruker web for å implementere webtjenester. Når vi snakker REST, er URI ment å være konstant over tid så lenge tjenesten kjører og ressursens kontekst er den samme.

Uten REST begrensingene vil vi som oftest aksessere ressurser basert på lokalisering, f.eks vanlige webadreser. Om vi endrer navnet på en fil på webserveren, må også URI endres.

HTTP request types

I en RESTful webtjeneste har vi fire hendelser vi kan utføre på en ressurs, i motsetning til en vanlig webtjeneste hvor vi har uendelig mange hendelser tilgjengelig. Ved å minimere antallet får man begrenset uklarheter / misforståelser i design og implementasjon.

De fire hendelsene vi har tilgjengelig er Create, Retrieve, Update og Delete (CRUD). Disse finner vi igjen i HTTP protokollen som Post, Get, Put og Delete.

Jeg skal nå prøve å vise et eksempel på hvordan vi kan bruke HTTP requests for å endre tilstand på en ressurs.

Anta at vi har en webtjeneste som holder styr på ansatte i en bedrift.

En typisk ansatt vil da se slik ut:

{codecitation class="brush: xml; gutter: false;" }

<ansatt>

<navn>Kristian</navn>

<alder>29</alder>

<katalog>/ansatte/kristian</katalog>

</ansatt>

Og en liste med ansatte:

{codecitation class="brush: xml; gutter: false;" }

<ansatte>

<ansatt>

<navn>Kristian</navn>

<alder>29</alder>

<katalog>/ansatte/kristian</katalog>

</ansatt>

<ansatt>

<navn>Tove</navn>

<alder>31</alder>

<katalog>/ansatte/tove</katalog>

</ansatt>

<katalog>/ansatte</katalog>

</ansatte>

Videre kan vi nå definere noen URIs:

http://minwebtjeneste.no/ansatte <--- gir oss en liste over ansatte

http://minwebtjeneste.no/ansatte/{navn} <--- gir oss en spesifikk ansatt identifisert på unikt navn.

Vi kan så prøve å gå til de definerte URI og resultatet er forhåpentligvis ikke direkte overraskende.

Eksempel 1 GET Request: http://minwebtjeneste.no/ansatte/kristian

Eksempel 1 Resultat:

{codecitation class="brush: xml; gutter: false;" }

<ansatt><navn>Kristian</navn><alder>29</alder><katalog>/ansatte/kristian</katalog></ansatt>

Eksempel 2 GET Request: http://minwebtjeneste/ansattte

Eksempel 2 Resultat:

{codecitation class="brush: xml; gutter: false;" }

<ansatte>

<ansatt><navn>Kristian</navn><alder>29</alder><katalog>/ansatte/kristian</katalog></ansatt>

<ansatt><navn>Tove</navn><alder>31</alder><katalog>/ansatte/tove</katalog></ansatt>

<katalog>/ansatte</katalog>

</ansatte>

En kort forklaring på hva som skjer i eksempel 1:

1: En javaklient gjør en HTTP request med type 'GET', og identifier 'kristian'.

2: Webserveren sender denne requesten til et RESTful rammeverk som behandler forespørselen.

3: REST rammeverket sender så dette videre til den domenespesifikke koden / programmet.

4: Programmet som kjører på serveren har ansvar for å grave frem data om en ansatt med navn Kristian, og returnere det tilbake i et passende format som klienten kan forstå. Vi får også en HTTP Status 200 dersom alt har gått greit, e.v.t en feilkode dersom noe har oppstått.

Fremgangsmåten i eksempel 2 er nærmest identisk, bare at vi har en annen identifier.

Vi bruker altså GET for å hente representasjoner.

Eksempel 3 POST / CREATE Request: http://minwebtjeneste/ansatte/kristian

Eksempel 3 Resultat: HTTP Status 200 (e.v.t HTTP Error Code)

En kort forklaring på det som skjer i eksempel 3:

1: En javaklient gjør en HTTP request med type 'POST'.

2: POST requesten sendes sammen med en XML representasjon av 'Kristian'.

3: Webserveren mottar og videresender til REST rammeverket, hvor koden for å lagre / opprette den nye ansatte blir kjørt.

4: Når den nye ressursen er lagret returneres en HTTP Status 200 om alt har gått greit, e.v.t en feilkode dersom noe har oppstått.

Vi bruker altså POST for å opprette representasjoner.

Eksempel 4 PUT / UPDATE Request:http://minwebtjeneste/ansatte/kristian

Eksempel 4 Resultat: HTTP Status 200 (e.v.t HTTP Error Code)

En kort forklaring på det som skjer i eksempel 4:

1: En javaklient gjør først en GET (utelatt siden den er identisk med eksempel 1). Dette gir oss mulighet til å se hvilken data som skal endres, og endre de.

2: Klienten sender en PUT request til http://minwebtjeneste/ansatte/kristian med de oppdaterte dataene i XML format.

3: Webserveren mottar og videresender til REST rammeverket, hvor koden for å oppdatere representasjonen blir kjørt.

4: Når representasjonen er oppdatert returneres det en status kode.

Vi bruker altså PUT for å oppdatere representasjoner.

Eksempel 5 DELETE Request: http://minwebtjeneste/ansatte/kristian

Eksempel 5 Resultat: HTTP Status 200 (e.v.t HTTP Error Code)

En kort forklaring på det som skjer i eksempel 5:

1: En javaklient gjør en DELETE request til http://minwebtjeneste/ansatte/kristian.

2: Webserveren mottar og videresender til REST rammeverket, hvor koden for å slette representasjonen blir kjørt.

3: Når representasjonen er slettet returneres det en status kode.

Vi bruker altså DELETE for å slette representasjoner.

Vi har altså hentet, oppdatert og slettet en ansatt ved hjelp av en URI, og tre allerede eksisterende HTTP kall.

Webservices i praksis

W3C definerer en webtjeneste som et system som utveksler XML med andre systemer via HTTP protokollen.

I praksis brukes ofte webtjenester av firma som ønsker å gjøre sin API tilgjengelig for andre utviklere. F.eks Google, Yahoo!, Amazon og Facebook tilbyr webservices.

Eksempeler: Flickr API, Amazon REST API, Google Search REST API

Det finnes flere REST rammeverk for Java dersom du ønsker å prøve selv. Vi kommer tilbake til disse i senere artikler.

Tagged as : diverse

Comments

Tagged as : diverse