Ik heb wat lovende reacties gekregen voor een eerdere post over REST. Dank daarvoor.
Maar ik heb ook wat misverstanden geschapen, geloof ik.
Is REST de opvolger van Java voor zover het de implementatie van het object-model betreft? Nee. REST is wat mij betreft alleen de implementatie van de structuur van het object-model: de samenhang tussen de grof-granulaire domein-objecten, en voor de communicatie tussen die objecten.
Althans: voorzover ze op het Web zijn gedistribueerd.
Dus de "binnenkant" van de objecten zal met een andere taal, Java, of Python, of Ruby, of voor mijn part Cobol, C of Erlang, worden geimplementeerd. En als de de objecten niet gedistribueerd behoeven te zijn, maar alleen maar "lokaal" in een applicatie worden gebruikt, is REST ook overbodig.
Maar ik denk wel dat die grof-granulaire objecten steeds meer (ook) als zelfstandige entiteiten op het Web beschikbaar moeten zijn, dat wel.
En ik denk ook dat REST niet het eindpunt is. Daarvoor is REST te weinig passend op wat je echt wil. Niet alleen is de "fit" met object-modellen niet 100%, maar vooral ook het feit dat het communicatie-protocol HTTP is, levert beperkingen op.
Natuurlijk is volgens de REST-adepten juist het gebruik van plain HTTP het grote voordeel, en ze hebben in veel opzichten gelijk. Maar bijvoorbeeld asynchroniteit zit niet in HTTP. Dat betekent dat als asynchrone messages nodig zijn (en dat is bijna altijd zo), dat moet worden opgelost binnen de resources of althans binnen de server die de resources beheert.
Een gestandaardiseerde abstractielaag bovenop REST, waarbij de URI-structuur in stand blijft, prettig zou zijn. Komt zo dan toch weer WS-* via de achterdeur binnen? Nee, dat is niet de bedoeling. Veel WS-* standaarden hebben op zichzelf nut, alleen: de implementatie is zeer toolgebonden, en erg ondoorzichtig.
Ik vraag me af: zou het mogelijk zijn een Erlang-achtige taal te maken die asynchroniteit inbouwt, en gewoon op HTTP is gebaseerd? Of gaat dat toch weer een lekkende abstractie worden?
Posts tonen met het label OO. Alle posts tonen
Posts tonen met het label OO. Alle posts tonen
vrijdag 11 juli 2008
dinsdag 8 juli 2008
Representaties
Kees schrijft:
"Wat is een "representation" van een object? Werkt het als een referentie naar dat object, kun je het bijvoorbeeld op die manier veranderen, of is het alleen data en niet het object zelf?"
Goede vraag. Het begrip "representation" binnen REST is inderdaad wat schimmig. Het is een view op een object, maw: een set gegevens, in een bepaalde formattering. Een weergave van iets in HTML is een representatie, de verzameling van orders gesorteerd op datum ook, enzovoort.
In feite is het begrip "representation" de afscherming van de inhoud van een object binnen de context van REST. Informatie vraag je aan een resource via de GET, en wat je krijgt is (per definitie) een representation.
De representation is dus alleen data, en niet het object/resource zelf. Daarvan, of althans: van de resource, heb je de URI. Je kunt de URI kopieren, maar niet de resource zelf.
Het is ook goed om in de gaten te houden dat de begrippen "object", "message", "reference", enzovoort eigenlijk vreemd zijn aan REST. Daar gaat het over "resources", "representations", "URIs". Je kunt (zie eerdere post) wel een zinnige projectie van de OO-begrippen naar de REST-begrippen maken, maar daarmee wordt het nog niet hetzelfde.
Wel denk ik dat het zinnig is de begrippensets wat beter op elkaar te laten passen. Bijvoorbeeld: in REST gebruik je de URI zowel voor resource-identificatie als voor (in OO-termen) parameter passing. Dat kan, het heeft voordelen, maar het zijn voor elk zinnig mens wel verschillende dingen. (Het is ook wel grappig om te zien in welke bochten de REST-puristen zich wringen om deze twee dingen in essentie toch wel hetzelfde te laten zijn.) Het zou helpen als er een duidelijke conventie of desnoods standaard was welk deel van de URI locatie is, en welk deel parameter passing.
"Wat is een "representation" van een object? Werkt het als een referentie naar dat object, kun je het bijvoorbeeld op die manier veranderen, of is het alleen data en niet het object zelf?"
Goede vraag. Het begrip "representation" binnen REST is inderdaad wat schimmig. Het is een view op een object, maw: een set gegevens, in een bepaalde formattering. Een weergave van iets in HTML is een representatie, de verzameling van orders gesorteerd op datum ook, enzovoort.
In feite is het begrip "representation" de afscherming van de inhoud van een object binnen de context van REST. Informatie vraag je aan een resource via de GET, en wat je krijgt is (per definitie) een representation.
De representation is dus alleen data, en niet het object/resource zelf. Daarvan, of althans: van de resource, heb je de URI. Je kunt de URI kopieren, maar niet de resource zelf.
Het is ook goed om in de gaten te houden dat de begrippen "object", "message", "reference", enzovoort eigenlijk vreemd zijn aan REST. Daar gaat het over "resources", "representations", "URIs". Je kunt (zie eerdere post) wel een zinnige projectie van de OO-begrippen naar de REST-begrippen maken, maar daarmee wordt het nog niet hetzelfde.
Wel denk ik dat het zinnig is de begrippensets wat beter op elkaar te laten passen. Bijvoorbeeld: in REST gebruik je de URI zowel voor resource-identificatie als voor (in OO-termen) parameter passing. Dat kan, het heeft voordelen, maar het zijn voor elk zinnig mens wel verschillende dingen. (Het is ook wel grappig om te zien in welke bochten de REST-puristen zich wringen om deze twee dingen in essentie toch wel hetzelfde te laten zijn.) Het zou helpen als er een duidelijke conventie of desnoods standaard was welk deel van de URI locatie is, en welk deel parameter passing.
vrijdag 4 juli 2008
Ik rest mijn case
In de zgn. REST-SOA-discussie lopen allerlei vragen door elkaar heen: hoe makkelijk moet een protocol zijn? hoe erg is het om ingewikkelde tools, zoals ESBs, nodig te hebben? heb je bijvoorbeeld transaction awareness nodig? enzovoort.
Dat zijn allemaal interessante en ook relevante vragen, maar ik denk dat het toch vooral om iets anders gaat, namelijk de manier waarop je objecten (en daarmee semantische modellen) kunt gebruiken op het Web.
Toen zo'n 20 jaar geleden OO doorbrak, werd hoog opgegeven van de voordelen: je maakte een model in objecten van het relevante domein, je implementeerde dat in een daartoe geëigende omgeving, en het werkte. Schaalbaarheid, onderhoudbaarheid, en wat niet al waren je deel.
En dat kon dankzij het feit dat goed ontworpen objecten een unieke identiteit hadden en vindbaar waren op een unieke lokatie, ze stelden functionaliteit beschikbaar via een interface, en de interne implementatie en gegevens waren afgeschermd van de buitenwereld. Objecten waren eigenlijk zelfstandige entiteiten die elkaar kennen en met elkaar samenwerken.
Natuurlijk bleek de werkelijkheid wat prozaïscher, en kon er erg veel misgaan. Maar desondanks: als eea goed werd aangepakt, konden de beloften worden ingelost. Althans: binnen de run-time omgeving van een OO-omgeving, bijvoorbeeld een SmallTalk-image. En dus: eigenlijk slechts binnen het geheugen van een applicatie en zolangs als die applicatie loopt.
Persistentie en distributie verstoorden dus de OO-droom, en maakten het nodig om ingewikkelde oplosssinngen te bedenken, waarmee verzekerd werd dat objecten bewaard en geditribueerd konden worden, en wel op een "transparante" wijze. En dus werd er heel wat afgemapt.
Het persistentie-probleem is min of meer opgelost. Er kwamen OO-databases die het applicatiegeheugen en de "echte" database naadloos ("transparant", jazeker) in elkaar over lieten lopen. Erg mooi, en vrijwel niemand gebruikte het. Maar ook de wat meer aardse oplossing via een ORM (object relational mapping) bleek na wat vijven en zessen goed werkend te krijgen.
Het distributie-probleem bleek persistenter. :) Hoe moest de "ruimte" van objecten in één applicatie op één machine worden uitgebreid naar andere ruimtes van andere applicaties op andere machines? Met andere woorden: hoe maken we van al die ruimtes één grote ruimte?
De meest voor de hand liggende oplossingsrichting was: maak bovenop het netwerk een protocol wat ervoor zorgt dat objecten war dan ook elkaar kunnen kennen en direct boodschappen sturen. Java RMI is van deze route een voorbeeld.
Dat werkte, althans tot op zekere hoogte. Binnen een closely-knitted LAN was het netwerk stabiel genoeg om van het netwerk te kunnen abstraheren. Maar daarbuiten bleek dat een fictie: het netwerk was niet stabiel genoeg, en dan kun je het ook niet transparant maken. Bovendien waren de RMI-objecten niet echt persistent, omdat ze in feite afhankelijk waren van de applicatie waarbinnen ze bestonden. En tenslotte was de bovenop het netwerk vereiste laag dusdanig ingewikkeld dat het nooit een algemene standaard kon worden. En dat is ook niet gebeurd: RMI kun je alleen binnen de Java-architectuur gebruiken, en die is niet universeel.
Men kon er niet onderuit: het was niet mogelijk om een werkend object-netwerk te maken volledig geabstraheerd van het netwerk. Dus werd het begrip "component" (opnieuw) ingevoerd. Componenten waren entiteiten die op het netwerk draaiden, en als zodanig bekend waren, en via een functioneel interface aangeroepen konden worden.
Maar hoe verhielden de componenten zich tot de objecten?
Een eerste schot was: laat elk object, althans elk zelfstandig domeinobject, een component zijn. Maar er zijn verschrikkelijk veel domeinobjecten. Die allemaal een echte zelfstandige component maken zou veel te veel resources vergen. Immers, de functionaliteit die nodig is om iets een zelfstandige, vindbare, persistente eintiteit op een netwerk (een component dus) te maken, is fors.Dus moest er een oplossing worden bedacht waarin de object-componenten weliswaar algemeen bekend en bereikbaar waren, maar voor de standaard-component functionaliteit gebruik maakten van een soort component voedingsbodem.
De J2EE-EntityBeans waren een poging in deze richting, maar al ras bleek dat zelfs in deze aanpak veel te veel componenten ontstonden om een acceptabele performance te halen. Bovendien konden J2EE-componenten alleen goed met J2EE-componenten praten, dus van een universele ruimte was sowieso geen sprake. En vergelijkbare nadelen golden voor andere pogingen in deze richting zoals COM/DCOM.
Goed, objecten konden dus niet allemaal componenten worden. Dan maar een hybride benadering: we hebben componenten, en daarbinnen leven objecten. En we gaan een standaard ontwikkelen volgens welke componenten met elkaar, in via die route gedistribueerde objecten met elkaar, kunnen praten. En dat niet gebonden aan één talomgeving (zoals bij RMI). Dat was Corba.
Ingewikkeld? Ja, en ook nog eens slechts een standaard, nog geen implementatie. En je had er meestal dure en in ieder geval moeilijk te begrijpen tools voor nodig.
Een andere variant was: laten we het niet te ingewikkeld maken. We zien de componenten gewoon als objecten (ze hebben tenslotte al een unieke lokatie, en een interface met mooie functies, en we proberen zo'n beetje de OO-ontwerp principes voor het ontwerp van die componenten te gebruiken. Daar is weinig op tegen, en als er goede standaarden zijn of komen voor de communicatie tussen de componenten, dan heeft dit een goede kans van slagen. O ja, en heel belangrijk: we noemen het anders, dan lijkt het nieuw.
Ziedaar SOA, en dankzij XML, SOAP en de WS-* standaarden is het inderdaad een behoorlijk succes. En dankzij het Web en HTTP is de ruimte van componenten nu ook universeel.
Maar het lost het oorspronkelijke probleem niet op. Want SOA-services of -componenten zijn geen domeinobjecten, al lijken ze er een beetje op. Eigenlijk zijn we weer terug bij af: we hebben componenten (services) die elkaar kunnen vinden en met elkaar kunnen praten. Objecten bestaan wel, maar zitten binnenin de componenten. En als ee object een boodschap wil sturen aan een object in een andere component, moet eerst worden uitgezocht waar het doelobject zich eigenlijk bevindt, moet de boodschap vervolgens worden vertaald naar een serviceaanroep, moet daarbij worden aangegeven voor welk object de boodschap eigenlijk is bedoeld, en kan daarna de service-aanroep worden gedaan. En aan de andere kant moet de booschap dan weer worden uitgepakt en ontcijferd, en worden doorgestuurd naar het doelobject. Het kan wel, maar het is erg omslachtig. (Al is dat bij gebruik van MDD-technieken midner bezwaarlijk.)
Stand van zaken: we hebben eindelijk een universele ruimte, maar alleen voor componenten. Die gebruiken om echte objecten direct aan elkaar te hangen is niet gelukt, vanwege gebrek aan eenvoud, gebrek aan standaardisatie, en gebrek aan persistentie.
En toen kwam REST.
De resources van REST vormen een universele ruimte, ze zijn (uiteraard) persistent, ze zijn vindbaar en uniek dankzij de URI, het is een bestaande en zeer wijdverbreide standaard (HTTP in feite), en hij is bewezen makkelijk te gebruiken: het hele Web is erop gebaseerd.
Zouden objecten dan te mappen zijn op HTTP-resources?
Op het eerste gezicht is de mapping lastiger dan op RPC-style componenten. Objecten hebben een unieke identificatie ne locatie nodig, en dat biedt de resource inderdaad dankzij de URI. Maar niet elke via een URI te identificeren resource is een echt object, sommige zijn een "representation" van een object, in OO-termen een returnwaarde van een method.
En de REST-methods passen ook niet zonder meer op de methods in een objectmodel. Immers, REST kent slechts een beperkt aantal methods (GET, PUT, POST, DELETE zijn relevant in dit verband). De eerste drie hebben een heel strikte betekenis, en de consequentie is dat extra informatie (parameters in een method van een object) in de URI wordt gestopt. En methods die niet kunnen worden gezien als een GET, PUT of DELETE moeten via POST worden "getruct".
Vanuit OO ziet het er dus op het eerste gezicht niet zo heel goed uit. Maar als je wat beter kijkt, lijkt dat erg mee te vallen. De object-methods uit een goed ontworpen OO-domeinmodel blijken vrijwel alle zonder veel problemen te kunnen worden vertaald naar HTTP-methods.
Maar dan nog steeds: het wringt. HTTP-resources zijn brokken informatie die aan elkaar zij gerelateerd, met verscheidene representaties. Het zijn geen objecten die potentieel een zeer specifiek hebben. Resources hebben juist zoveel mogelijk een standaard-interface.
De claim van REST-voorstanders is dat dat standaard-interface juist een voordeel is. Doordat bijvoorbeeld de betekenis van GET is gedefineerd als: een GET mag een resource niet wijzigen, kunnen HTTP-servers GET-resultaten cachen. En door de simpele method + URI structuur zouden hergerbuikers makkelijker in staat zijn te snappen wat er gebeurt dan als ze bv een WSDL-file moeten lezen voor een SOA-service. Bij REST is de structuur van de resources en de informatie binnen de resources (te verkrijgen als representatie) primair.
In OO is dat van oudsher anders: daar is het functionele interface primair, en de informatie is juist geëncapsuleerd. Althans: volgens de OO-puristen. Als je kijkt naar een goed domeinmodel, dan blijkt dat veel meer een "semantic web" achtig ding te zijn, waarbij het interface helemaal niet zo'n leidende rol speelt.
(Voor de duidelijkheid: voor OO-toepassingen op een ander nivo dan de implementatie van domeinmodellen ligt dat anders, maar die worden ook niet geraakt door deze problematiek.)
En dus is het verschil met de REST/resource-oriented denkwijze helemaal niet zo groot als het op het eerste gezicht lijkt. En het voordeel van REST, namelijk dat je een universele ruimte met dingen (resources, objecten) krijgt, met unieke locaties, met de mogelijkheid daar via een standaard protocol boodschappen aan te sturen, en dat zonder dat je last hebt van het begrip component, dat voordeel is immens.
Is REST dus de toekomst? Ja, ik denk het wel. Maar we moeten nog wel uitzoeken hoe goed die mapping van OO op REST nou echt werkt, en ik denk dat er toch soort REST-standaard bovenop HTTP (bij via een nadere uitwerking van POST) nodig blijkt. Ook al is dat tegen het zere been van de REST-puristen.
Betekent dit dat "gewone SOA" ten dode is opgeschreven? Dat weet ik niet zo zeker. Voor "semantic web" achtige webservices is REST de eerste keus, maar er zijn ook webservices die andere eisen stellen. In de beruchte WS-* stack zitten een aantal zaken (bijvoorbeeld op het gebied van reliability en security) die wat lastig zijn vorm te geven in een REST-context. Het zou kunnen dat we die veel minder vaak nodig hebben dat we nu denken, maar of dat echt waar is moet nog maar blijken.
Maar er zijn zeker een hoop SOA/SOAP-etc interfaces die makkelijk via REST zouden kunnen werken, en ik denk dat we REST-facades bovenop SOA-interfaces gaan zien. Dat zal de migratie ook makkelijker maken.
Dat zijn allemaal interessante en ook relevante vragen, maar ik denk dat het toch vooral om iets anders gaat, namelijk de manier waarop je objecten (en daarmee semantische modellen) kunt gebruiken op het Web.
Toen zo'n 20 jaar geleden OO doorbrak, werd hoog opgegeven van de voordelen: je maakte een model in objecten van het relevante domein, je implementeerde dat in een daartoe geëigende omgeving, en het werkte. Schaalbaarheid, onderhoudbaarheid, en wat niet al waren je deel.
En dat kon dankzij het feit dat goed ontworpen objecten een unieke identiteit hadden en vindbaar waren op een unieke lokatie, ze stelden functionaliteit beschikbaar via een interface, en de interne implementatie en gegevens waren afgeschermd van de buitenwereld. Objecten waren eigenlijk zelfstandige entiteiten die elkaar kennen en met elkaar samenwerken.
Natuurlijk bleek de werkelijkheid wat prozaïscher, en kon er erg veel misgaan. Maar desondanks: als eea goed werd aangepakt, konden de beloften worden ingelost. Althans: binnen de run-time omgeving van een OO-omgeving, bijvoorbeeld een SmallTalk-image. En dus: eigenlijk slechts binnen het geheugen van een applicatie en zolangs als die applicatie loopt.
Persistentie en distributie verstoorden dus de OO-droom, en maakten het nodig om ingewikkelde oplosssinngen te bedenken, waarmee verzekerd werd dat objecten bewaard en geditribueerd konden worden, en wel op een "transparante" wijze. En dus werd er heel wat afgemapt.
Het persistentie-probleem is min of meer opgelost. Er kwamen OO-databases die het applicatiegeheugen en de "echte" database naadloos ("transparant", jazeker) in elkaar over lieten lopen. Erg mooi, en vrijwel niemand gebruikte het. Maar ook de wat meer aardse oplossing via een ORM (object relational mapping) bleek na wat vijven en zessen goed werkend te krijgen.
Het distributie-probleem bleek persistenter. :) Hoe moest de "ruimte" van objecten in één applicatie op één machine worden uitgebreid naar andere ruimtes van andere applicaties op andere machines? Met andere woorden: hoe maken we van al die ruimtes één grote ruimte?
De meest voor de hand liggende oplossingsrichting was: maak bovenop het netwerk een protocol wat ervoor zorgt dat objecten war dan ook elkaar kunnen kennen en direct boodschappen sturen. Java RMI is van deze route een voorbeeld.
Dat werkte, althans tot op zekere hoogte. Binnen een closely-knitted LAN was het netwerk stabiel genoeg om van het netwerk te kunnen abstraheren. Maar daarbuiten bleek dat een fictie: het netwerk was niet stabiel genoeg, en dan kun je het ook niet transparant maken. Bovendien waren de RMI-objecten niet echt persistent, omdat ze in feite afhankelijk waren van de applicatie waarbinnen ze bestonden. En tenslotte was de bovenop het netwerk vereiste laag dusdanig ingewikkeld dat het nooit een algemene standaard kon worden. En dat is ook niet gebeurd: RMI kun je alleen binnen de Java-architectuur gebruiken, en die is niet universeel.
Men kon er niet onderuit: het was niet mogelijk om een werkend object-netwerk te maken volledig geabstraheerd van het netwerk. Dus werd het begrip "component" (opnieuw) ingevoerd. Componenten waren entiteiten die op het netwerk draaiden, en als zodanig bekend waren, en via een functioneel interface aangeroepen konden worden.
Maar hoe verhielden de componenten zich tot de objecten?
Een eerste schot was: laat elk object, althans elk zelfstandig domeinobject, een component zijn. Maar er zijn verschrikkelijk veel domeinobjecten. Die allemaal een echte zelfstandige component maken zou veel te veel resources vergen. Immers, de functionaliteit die nodig is om iets een zelfstandige, vindbare, persistente eintiteit op een netwerk (een component dus) te maken, is fors.Dus moest er een oplossing worden bedacht waarin de object-componenten weliswaar algemeen bekend en bereikbaar waren, maar voor de standaard-component functionaliteit gebruik maakten van een soort component voedingsbodem.
De J2EE-EntityBeans waren een poging in deze richting, maar al ras bleek dat zelfs in deze aanpak veel te veel componenten ontstonden om een acceptabele performance te halen. Bovendien konden J2EE-componenten alleen goed met J2EE-componenten praten, dus van een universele ruimte was sowieso geen sprake. En vergelijkbare nadelen golden voor andere pogingen in deze richting zoals COM/DCOM.
Goed, objecten konden dus niet allemaal componenten worden. Dan maar een hybride benadering: we hebben componenten, en daarbinnen leven objecten. En we gaan een standaard ontwikkelen volgens welke componenten met elkaar, in via die route gedistribueerde objecten met elkaar, kunnen praten. En dat niet gebonden aan één talomgeving (zoals bij RMI). Dat was Corba.
Ingewikkeld? Ja, en ook nog eens slechts een standaard, nog geen implementatie. En je had er meestal dure en in ieder geval moeilijk te begrijpen tools voor nodig.
Een andere variant was: laten we het niet te ingewikkeld maken. We zien de componenten gewoon als objecten (ze hebben tenslotte al een unieke lokatie, en een interface met mooie functies, en we proberen zo'n beetje de OO-ontwerp principes voor het ontwerp van die componenten te gebruiken. Daar is weinig op tegen, en als er goede standaarden zijn of komen voor de communicatie tussen de componenten, dan heeft dit een goede kans van slagen. O ja, en heel belangrijk: we noemen het anders, dan lijkt het nieuw.
Ziedaar SOA, en dankzij XML, SOAP en de WS-* standaarden is het inderdaad een behoorlijk succes. En dankzij het Web en HTTP is de ruimte van componenten nu ook universeel.
Maar het lost het oorspronkelijke probleem niet op. Want SOA-services of -componenten zijn geen domeinobjecten, al lijken ze er een beetje op. Eigenlijk zijn we weer terug bij af: we hebben componenten (services) die elkaar kunnen vinden en met elkaar kunnen praten. Objecten bestaan wel, maar zitten binnenin de componenten. En als ee object een boodschap wil sturen aan een object in een andere component, moet eerst worden uitgezocht waar het doelobject zich eigenlijk bevindt, moet de boodschap vervolgens worden vertaald naar een serviceaanroep, moet daarbij worden aangegeven voor welk object de boodschap eigenlijk is bedoeld, en kan daarna de service-aanroep worden gedaan. En aan de andere kant moet de booschap dan weer worden uitgepakt en ontcijferd, en worden doorgestuurd naar het doelobject. Het kan wel, maar het is erg omslachtig. (Al is dat bij gebruik van MDD-technieken midner bezwaarlijk.)
Stand van zaken: we hebben eindelijk een universele ruimte, maar alleen voor componenten. Die gebruiken om echte objecten direct aan elkaar te hangen is niet gelukt, vanwege gebrek aan eenvoud, gebrek aan standaardisatie, en gebrek aan persistentie.
En toen kwam REST.
De resources van REST vormen een universele ruimte, ze zijn (uiteraard) persistent, ze zijn vindbaar en uniek dankzij de URI, het is een bestaande en zeer wijdverbreide standaard (HTTP in feite), en hij is bewezen makkelijk te gebruiken: het hele Web is erop gebaseerd.
Zouden objecten dan te mappen zijn op HTTP-resources?
Op het eerste gezicht is de mapping lastiger dan op RPC-style componenten. Objecten hebben een unieke identificatie ne locatie nodig, en dat biedt de resource inderdaad dankzij de URI. Maar niet elke via een URI te identificeren resource is een echt object, sommige zijn een "representation" van een object, in OO-termen een returnwaarde van een method.
En de REST-methods passen ook niet zonder meer op de methods in een objectmodel. Immers, REST kent slechts een beperkt aantal methods (GET, PUT, POST, DELETE zijn relevant in dit verband). De eerste drie hebben een heel strikte betekenis, en de consequentie is dat extra informatie (parameters in een method van een object) in de URI wordt gestopt. En methods die niet kunnen worden gezien als een GET, PUT of DELETE moeten via POST worden "getruct".
Vanuit OO ziet het er dus op het eerste gezicht niet zo heel goed uit. Maar als je wat beter kijkt, lijkt dat erg mee te vallen. De object-methods uit een goed ontworpen OO-domeinmodel blijken vrijwel alle zonder veel problemen te kunnen worden vertaald naar HTTP-methods.
Maar dan nog steeds: het wringt. HTTP-resources zijn brokken informatie die aan elkaar zij gerelateerd, met verscheidene representaties. Het zijn geen objecten die potentieel een zeer specifiek hebben. Resources hebben juist zoveel mogelijk een standaard-interface.
De claim van REST-voorstanders is dat dat standaard-interface juist een voordeel is. Doordat bijvoorbeeld de betekenis van GET is gedefineerd als: een GET mag een resource niet wijzigen, kunnen HTTP-servers GET-resultaten cachen. En door de simpele method + URI structuur zouden hergerbuikers makkelijker in staat zijn te snappen wat er gebeurt dan als ze bv een WSDL-file moeten lezen voor een SOA-service. Bij REST is de structuur van de resources en de informatie binnen de resources (te verkrijgen als representatie) primair.
In OO is dat van oudsher anders: daar is het functionele interface primair, en de informatie is juist geëncapsuleerd. Althans: volgens de OO-puristen. Als je kijkt naar een goed domeinmodel, dan blijkt dat veel meer een "semantic web" achtig ding te zijn, waarbij het interface helemaal niet zo'n leidende rol speelt.
(Voor de duidelijkheid: voor OO-toepassingen op een ander nivo dan de implementatie van domeinmodellen ligt dat anders, maar die worden ook niet geraakt door deze problematiek.)
En dus is het verschil met de REST/resource-oriented denkwijze helemaal niet zo groot als het op het eerste gezicht lijkt. En het voordeel van REST, namelijk dat je een universele ruimte met dingen (resources, objecten) krijgt, met unieke locaties, met de mogelijkheid daar via een standaard protocol boodschappen aan te sturen, en dat zonder dat je last hebt van het begrip component, dat voordeel is immens.
Is REST dus de toekomst? Ja, ik denk het wel. Maar we moeten nog wel uitzoeken hoe goed die mapping van OO op REST nou echt werkt, en ik denk dat er toch soort REST-standaard bovenop HTTP (bij via een nadere uitwerking van POST) nodig blijkt. Ook al is dat tegen het zere been van de REST-puristen.
Betekent dit dat "gewone SOA" ten dode is opgeschreven? Dat weet ik niet zo zeker. Voor "semantic web" achtige webservices is REST de eerste keus, maar er zijn ook webservices die andere eisen stellen. In de beruchte WS-* stack zitten een aantal zaken (bijvoorbeeld op het gebied van reliability en security) die wat lastig zijn vorm te geven in een REST-context. Het zou kunnen dat we die veel minder vaak nodig hebben dat we nu denken, maar of dat echt waar is moet nog maar blijken.
Maar er zijn zeker een hoop SOA/SOAP-etc interfaces die makkelijk via REST zouden kunnen werken, en ik denk dat we REST-facades bovenop SOA-interfaces gaan zien. Dat zal de migratie ook makkelijker maken.
maandag 30 juli 2007
Wat is software-ontwikkeling?
Een collega vroeg me laatst eens te kijken naar een leerboek over "software-ontwikkeling". Het was een aardig boek, ongeveer langs de lijnen zoals die boeken tegenwoordig worden geschreven; vrij veel OO en UML, maar verder het nodige over architecturen (J2EE, Corba, etc), wat over UIs, wat over projectaanpak (RUPachtig), etc. Ik vind dat toch wel raar. Want Sw-ontwikkeling is een "proces" met heel veel totaal verschillende
activeiten en deelgebieden erin.
Van oudsher werd het grootste deel overzien door de 'analist-programmeur'. Die deed een soort halfwas IA, hij ontwierp het systeem in techische zin, en programmeerde ook vrijwel alle aspecten; het "echte" programma, detransactiehandling, de JCL, de files, het scherm als daarvan sprake was. En hij organiseerde ook zijn eigen "project".
Ik ben nog zo opgeleid, maar dat begon toen al een beetje onzin te worden. Iig dreven informatie-analyse en min of functioneel ontwerp weg van het meer technische deel. En dat wegdrijven is alleen maar verder gegaan. "Business modeling" is een aparte tak van sport geworden, "architectuur" ook. DBA is al lang apart. GUI-design wordt door specialisten gedaan, en het resultaat wordt weer door andere specialisten
gebouwd. Etc, etc.
Bovendien: als die activiteiten nog in 1 hand vallen, is dat een probleem, want het resultaat zal suboptimaal zijn. De Programmero Universalis is dood.
En dan hebben we het nog niet over allerhande projectaanpakken, met bijbehorende pseudo-specialismen (agile, RUP, spiral, etc, etc).De nieuwe ontwikkelingen (SOA, SaaS, MDA/E, offshoring/outsourcing, enz) versterken dat alleen maar.
Dat zo zijnde: wat heeft heeft het dan voor zin om een "allesomvattend" verhaal te schrijven over software-ontwikkeling? Of het als 1 onderwerp te doceren, for that matter?
Die leerboeken leggen dan ook sterk de nadruk op OO en UML, maar ze durven zich er niet toe te beperken. Maar wat doen al die verhalen over Corba, RMI, J2EE, er dan toe? Waarom geen Flex, of C#, of VB, of voor mijn part Cobol en CICS? En waarom een of andere RUP-variant, en niet AD? Waarom geen verhaal over SaaS en de consequenties
daarvan?
En door al die aandacht voor die zaken er omheen, zal het OO-design verhaal ook de kern missen, denk ik. Want de grap is natuurlijk dat je OO moet gebruiken als een platform- en aanpak-onafhankelijke "taal" geschikt voor analyse en design, meer niet.
Ik denk dat het niet veel zin heeft om software-ontwikkeling, met alle aspecten die daarbij horen (van requirements gathering tot versiebeheer, en van testen tot design patterns) als 1 discipline te beschouwen. Dat is het niet meer, en dat is maar goed ook. Nu de leerboeken nog.
Abonneren op:
Posts (Atom)