REST en ROA
Ik had ooit een voorkeur voor SOAP in plaats van REST vanwege:
- Ondersteuning door toolkits
- Afhandeling van foutmeldingen
- Definitiebestand voor methoden
- Gestandaardiseerd
Maar als gevolg van mijn groeiende aversie tegen onnodige complexiteit heb ik REST nader onderzocht en kwam ik erachter dat REST hier ook aan voldoet en meer!
Vaak wordt een verkeerde definitie aangehouden van REST en wordt er een remote procedure call via HTTP bedoeld. Bijvoorbeeld:
- http://www.google.nl/search?q=REST (vraag zoekresultaat)
- http://voorbeeld.nl/showForum.action?forum=415&action=delete&id=24156 (verwijder een bericht)
Waardoor het een soort lichtgewicht vervanging is voor SOAP-RPC (maar het is eigenlijk RPC-style of REST-RPC hybrid). Typisch is dat er vaak één endpoint is voor meerdere methods.
Wat is REST dan wel?
REST staat voor Representational State Transfer. Het is meer een omschrijving van architectuurstijlen en daarom wordt in het boek RESTful Web Services de Resource Oriented Architecture (ROA) gedefinieerd, die voldoet aan de REST-eisen.
Een ROA heeft de volgende concepten
- Alles is een resource
En daarmee wordt *alles* bedoeld. Bij een forum is bijvoorbeeld elk onderwerp, elk bericht, elke gebruiker en elk commentaar een aparte resource. Ook resultaten van een algoritme (bijvoorbeeld zoeken) zijn resources.
- Een resource heeft een of meer URIs
Via de URI is een resource te benaderen. De URI dient beschrijvend te zijn, bijvoorbeeld: http://voorbeeld.bl/forum/415/24156
- Resources hebben representaties
Een resource kan meerdere representaties hebben, die afhankelijk van de wensen van de client worden geserveerd. Dit kan verschillende talen zijn, of verschillende detailniveau of bestandstype.
- State Transfer
Als een client een antwoord ontvangt wordt dan de client daarmee in een staat geplaatst. De client kan een willekeurige resource opvragen, maar doorgaans wil een client van de ene staat naar de volgende. De representatie bevat daarom verschillende links om naar andere staten te gaan. Een zoekresultaat bevat bijvoorbeeld links om naar de vorige en naar de volgende resultaten te gaan. De client kan daardoor vanuit een representatie naar de volgende.
en het heeft de volgende eigenschappen:
- Elke resource heeft een uniforme interface
In plaats van een explosie van methods (getX, setY, processZ) kent ROA maar 6 methodes: GET, PUT, DELETE, POST, HEAD en OPTIONS. Overloaded Post (het misbruiken van POST om een andere actie uit te voeren) is in ROA niet toegestaan.
- GET, HEAD, PUT en DELETE zijn idempodent. GET en HEAD zijn ook safe.
Idempodente acties kunnen zonder bijeffecten worden herhaald als het daarvoor is misgegaan. Safe betekent dat de resultaten geen effecten hebben op de server en het resultaat gecached kan worden.
- Gebruik van HTTP Headers voor metadata
Metadata voor aanvragen en antwoorden worden geplaatst in HTTP-header die zijn gestandaardiseerd. Indien nodig kunnen een eigen headers worden toegevoegd om te voorzien in extra functionaliteit.
- De server is stateless
Vorige aanvragen waren van de client worden niet bijgehouden. De client zal dus zelf elke keer alle benodigde informatie moeten opsturen. Dit maakt de implementatie van de client misschien wat lastiger, maar de implementatie van de server een stuk eenvoudiger en veel beter testbaar. Bijkomend voordeel is dat alles direct is op te vragen en dat er niet eerst een aantal voorgaande stappen doorlopen hoeven te worden.
- Verbondenheid
Resources zijn aan elkaar verbonden en staan niet op zichzelf. Dit is niet anders dan hoe het web nu werkt voor mensen.
ROA architecturen kenmerken zich door een grote hoeveelheid aan eindpoints die elk de uniforme interface aanbieden. De resources zijn onderling sterk aan elkaar verbonden door de koppelingen die in de representaties zijn geplaatst.
Samenvatting
ROA is conceptueel eenvoudig, gestandaardiseerd (HTTP standaard) en tegelijkertijd uitbreidbaar. Omdat HTTP breed wordt ondersteund is ook ROA goed ondersteund in een scala aan programmeertalen (Java, PHP, Javascript, Ruby). Het is daarmee een volwaardig, lichtgewicht alternatief voor SOAP.






“Alternatief voor SOAP” klinkt een beetje raar, alsof REST nieuwer is. Dat is natuurlijk niet zo. REST is zo oud als de nacht, of nou ja, zo oud als HTTP.
Daarom zou nooit de overweging moeten zijn of je “REST gaat doen”, maar of je iets anders [dan REST] zou willen inzetten. Vaak is dat niet het geval.
Rikkert Koppes - augustus 5, 2008 8:23
Ik zou SOAP gebruiken als de argumenten voor acties complex worden (bv. een SOAP method om een ‘order’ met ‘orderregels’ toe te voegen). Dit wil je in 1 transactie, en dus in 1 call naar de server.
Met SOAP is het dan eenvoudig om een samengesteld object als parameter te versturen.
Wanneer je met externe partijen moet communiceren is een WSDL nuttig als contract, ik ben benieuwd hoe je bij REST-services hierover afspraken maakt.
Edwin van der Elst - augustus 5, 2008 11:33
verzenden kan toch gewoon als form data? Dat is behoorlijk gespecificeerd. In het geval van orderregels heb je parameters als:
orderrule0.name = …
orderrule0.value = …
orderrule1.name = …
orderrule1.value = …
Web forms 2 repetition model kan je daar prima bij helpen, maar dat is niet eens noodzakelijk.
Rikkert Koppes - augustus 5, 2008 12:33
Als een functioneel of technische beschrijving niet volstaat, zou je kunnen kijken naar WADL (https://wadl.dev.java.net/). Je kunt ook een xml-document te PUTten of te POSTen waar je een XML Schema document voor kunt schrijven. Je kunt ervoor kiezen om zowel een hele order te kunnen bewerken en ook de afzonderlijke orderregels.
Of je kunt een formulier plaatsen in je presentatie om aan te geven wat er verzonden kan worden. HTML5 voorziet naast GET en POST ook in PUT en DELETE . Voordeel hiervan is dat de connectedness (verbondenheid) groter wordt.
@Rikkert: het was niet mijn bedoeling om REST of ROA als nieuw te presenteren. Ik kende de mogelijkheden van HTTP niet en zag het daarom niet eerder als alternatief. Overigens is ROA niet alleen een alternatief voor SOAP, maar ook voor RPC-styijl/REST-RPC-hybride constructies.
Lennaert - augustus 5, 2008 13:15
@Rikkert
Een ‘form’ op die manier gebruiken vind ik nogal lelijk. En dan blijf je met de vraag hoe dit geparsed moet worden.
Is het toevoegen van een getal (zoals orderrule0, 1, etc.) een standaard, tel je vanaf 0 of 1, welke velden kunnen er zijn, iemand anders bedenkt misschien ‘orderrule[0].name=…’
En het grootste probleem blijft dat er dan geen contract is (welke velden zijn verplicht, wat voor datatypes, etc.).
@Lenneart
WADL: Dat is de oplossing!
Het lijkt misschien geneuzel van mijn kant, maar ik heb al meegemaakt dat (externe) gebruikers van een service. zonder SOAP bibliotheek met het handje de XML opbouwden en dan probeerden de call uit te voeren. Ik was maar wat blij met de controles aan de server kant tegen de WSDL!
Ik vind het prettig om (bijvoorbeeld) bij verplichte velden zelf niet meer te hoeven controleren of ze echt wel ingevuld zijn en of een getal het juiste formaat heeft (bv. decimale scheidingsteken).
Edwin van der Elst - augustus 5, 2008 13:39
De HTML5 webforms 2 specificatie biedt een aardige lijst met uitbreidingen, waaronder verplichte velden en datatypes (zie http://www.whatwg.org/specs/web-forms/current-work/).
Je kunt een webforms2 formulier dus gebruiken als specificatie. Serverside moet er uiteraard nog wel gevalideerd worden, misschien zijn er bibliotheken die dat kunnen aan de hand van het formulier?
Lennaert - augustus 5, 2008 17:54
Ik vrees dat ik in GWBASIC versie 1.0 ben blijven steken. Len, neem even contact op aub dan kunnen we bijpraten.
Groet,
Matthieu
Matthieu van den Berg - oktober 17, 2008 9:31