Toen de eerste webapplicaties gebouwd werden, was dat vaak met een webserver die een directe verbinding had met de database. Als daar later een app aan moest worden toegevoegd voor je smartphone moest daar een application programming interface, ofwel api, voor gemaakt worden. Hetzelfde was ook nodig voor integratie met andere systemen omdat je deze geen directe toegang wilt geven tot jouw database.
De api-laag werd vaak als een afterthought toegevoegd en was beperkt in functionaliteit. Dit tijdperk hebben we al een tijdje achter ons gelaten. Waarin een jaar of vijftien geleden nog soap xml werd gebruikt om zo’n api te bouwen, is deze met de komst van smartphones en moderne webapplicaties al snel vervangen met restful api’s. Rest als technologie is overigens ouder dan soap maar dat terzijde. Kort door de bocht bestaat een rest api uit een serie van links zoals deze website ook een link is. Ieder link wijst vaak een resource. Bijvoorbeeld mijnapp.nl/api/customer of mijnapp.nl/api/order. Met de juiste toegang krijg je dan een lijst met customers of orders te zien in json formaat. Json is net als xml maar prettiger om naar te kijken en tegenaan te praten als software ontwikkelaar. Vaak werkt het dan zo als je mijnapp.nl/api/customer/id/123 opvraagt je de customer met ID 123 krijgt. In json- formaat, bijvoorbeeld:
r “id”:123,
“name” : “klant x”,
“total_orders” : 24,
“last_order” : “2020-02-29”
}
Industriestandaard
Rest api’s zijn feitelijk de industriestandaard, soap wordt vooral in legacy en bij corporates gebruikt. Rest api’s kennen ook nadelen. Zoals in iedere architectuur krijg je vroeg laat frictie met de naamgeving en wordt de api doorontwikkeld met functies, maar moet de api natuurlijk wel backwards compatibel blijven. Je krijgt dan bijvoorbeeld nieuwe versie van de api’s met een volgnummer.
Dit zit dan ook weer de snelheid in de weg van doorontwikkeling, of je moet de versies van de applicaties gelijk releasen met de versies van de api’s. Ook zal een rest api altijd hele objecten terugsturen. Het is heel voorspelbaar en altijd compleet, maar vaak ook veel meer dan je nodig hebt, bijvoorbeeld als je alleen maar een zoekfunctie maakt om een klant te selecteren. Daarnaast geldt; als je een pagina vult met informatie moet je meerdere verzoeken naar de api sturen om een compleet beeld te krijgen… Je voelt het aankomen wat ik nu ga schrijven.
Sinds een paar jaar is er een nieuwe manier om api’s te bouwen die snel opgepikt wordt: GraphQL.
GraphQL is ontwikkeld door Facebook en voor het eerst gedeeld met de wereld in 2015. GraphQL is opensource, dat betekent dat het niet meer van Facebook zelf is en de code publiekelijk inzichtelijk. Het is het mooiste wat Facebook ooit heeft voortgebracht, al is ReactJS – een front-end framework – een goede tweede en je ziet ze vaak samen.
GraphQL lost veel problemen op die ik met rest heb. Je hebt nog maar één link waarop je alles kunt opvragen. Je vraagt ook alleen op wat je nodig hebt. Wil je alleen de top vijf grootste customers met hun laatste vijf orders dit jaar zien? Fluitje van een cent. Met één request naar de server haal je direct al je informatie op en je krijgt een voorspelbaar resultaat in json-formaat terug. In principe heb je weinig uitdagingen in backwards compatible en hoef je de release cycles niet meer strikt af te stellen met de front-end developers. Continuous deployment en integration worden hiermee een stuk eenvoudiger. Als developer haal je op wat je nodig hebt en niets meer.
Ook is het eenvoudig om meerdere soorten databronnen op een uniforme manier te ontsluiten. Je kunt relationeel, nosql en zelfs een tekst bestand via één query combineren en opvragen. GraphQL is middleware, je kunt het op allerlei manier aansluiten op Python, NodeJS, .NET, et cetera. Het is in feite een querytaal waarmee je op declaratieve wijze een resultaat op kunt vragen. Met declaratief bedoel ik dat je het gewenste resultaat beschrijft en GraphQL uit laten zoeken hoe deze aan het resultaat komt. Het past hiermee heel goed in het plaatje van microservices en serverless. De standaard tools zoals Graphiql (met een i dus) heb je direct een omgeving waarin je query’s kunt schrijven die je één op één kunt kopiëren en plakken naar je code. Het is net als de rest-technologie taal-onafhankelijk, dus iedereen kan er direct mee aan de slag
Hoe begin je met GraphQL?
Mijn filosofie is altijd al api centrisch geweest. Ons leerplatform was eerst gebaseerd op een rest-architectuur. Dat heeft ons altijd een beetje dwars gezeten. Het remde de doorontwikkeling en voelde meer als een last dan een verlichting. GraphQL klonk erg aantrekkelijk, maar het was ook nieuw en onzeker. Bijna niemand gebruikte het in productie en tegenwoordig is het best risicovol om een lock-in met een framework te krijgen. Je weet nooit of het ineens in de steek gelaten wordt. Wij zijn begonnen om nieuwe aanvullingen via GraphQL te bouwen en zodoende ervaring op te doen. De klik was er bijna direct en vorig jaar hebben we nagenoeg ons hele platform omgeschreven naar GraphQL. Ook omdat GraphQL veel real-time mogelijkheden biedt via websockets en pubsub constructies.
Maar GraphQL kent ook nadelen. Je moet opnieuw nadenken over cache. Er is weinig kennis van GraphQL in de markt. Als externe partijen ook de api willen consumeren betekent dit ook een leercurve of afkeer. Waar rest-api’s extreem schaalbaar gemaakt kunnen worden zul je dit met GraphQL zelf uit moeten vogelen. GraphQL is meer een query language dan een architectuur. Je kunt GraphQL zelfs over een rest-api heenleggen. Ik zou dus GraphQL geen vervanger van rest willen noemen, maar gewoon een alternatieve manier om de tussenlaag te bouwen tussen front-end en back-end. Daarnaast is het zeer developer vriendelijk als je query’s schrijft dat er intellisense in zit. Je ziet direct of de query klopt en kunt hem ook direct testen. Het helpt enorm om sneller te ontwikkelen en of je de front-end nu in een native app doet of de browser maakt niets meer uit. It just works.
Wij zijn in ieder geval volledig over en kijken nooit meer achterom. Ben je cto of werk je met ontwikkelaars? Geef het een keer kans en bedank me later.
Louis Kossen,
De ICT is vooral cyclisch, mijn vraag aangaande GraphQL in de conceptuele architectuur van een ESB heeft Henri beantwoord. De CTO van Thingks heeft nieuwe rietjes gevonden waarbij hij – zoals toegegeven in laatste reactie – wat aanpassingen in autorisaties moest doen. In een Enterprise Architectuur is de schaal waarop dit gedaan moet worden over het algemeen wat groter en complexer. Technologische mogelijkheid om met een bundel rietjes informatie op te vragen uit verschillende (ongekoppelde) bronnen wil nog niet zeggen (privacy-by-design) dat je organisatorisch hiertoe ook geautoriseerd bent. Facebook als voorbeeld spreekt hierin niet tot de verbeelding en maatschappelijke/politieke discussies over transparantie in algoritmen gaat om vertrouwen.
In de discussies heeft de CTO van Thingks zich altijd opportuun getoond met zijn ‘developer mind’ welke geen rekening hield met de goverance aspecten. Er is daarom altijd een spanningsveld tussen beheer en ontwikkeling want laatste trekt vaak al snel weer verder naar nieuwe groene weiden en laat beheer van eerdere weidegronden aan anderen over, technologische schuld komt vaakt voort uit organisatorische veranderingen.
Interessant artikel, ik kende het nog niet.
Na lezing, vooral van je reacties, krijg ik een beetje het idee dat we terug gaan naar de tijd van de fat clients (het oude client server model).
Ik vond juist het mooie van middleware dat je een abstractielaag kunt plaatsen naar de data en die via een API kunt ontsluiten. De client ontwikkelaar hoeft geen weet te hebben van het datamodel van de database (of databases, want volgens mij gaan we steeds meer naar een hybride oplossing toe). De client ontwikkelaar heeft alleen te maken met de API.
Ik ga komende tijd eens wat van je links lezen, maar naar mijn mening gaan we een stap terug doen als clients kennis moeten hebben van de achterliggende database en het bijbehorende model.
Benno,
Ik heb het misschien niet goed beschreven, maar er is geen sprake van fat clients. GraphQL is een abstractielaag tussen de client (de applicatie c.q. de webpagina) en de database. De client ontwikkelaar heeft alleen maar te maken met de GraphQL API.
Met “Geen weet hebben” weet ik niet precies wat je bedoeld. Het is niet zo dat de ontwikkelaar hoef te weten hoe het onderliggende relationele model (tabellen en de sleutels tussen tabellen) in elkaar steekt. Als je bouwt vanuit een Order ontdek je vanzelf wel dat er aan een order ook een Klant zit en welke eigenschappen deze heeft. Als je bouwt vanuit de Klant zie je vanzelf dat een klant orders heeft, maar bijvoorbeeld ook Betalingen of Retouren. Je kunt juist heel mooi een “Domein” beschrijven.
Om dit even tastbaar te maken. In de database heb je een tabel Orders en Customers. In de tabel Orders is bijvoorbeeld een kolom die status heet. In die status staat “besteld”, “geleverd”,”factureert” of “geannuleerd”. In SQL zou je dan doen:
select o.* from orders o where o.customer_id = 123 and status = ‘geannuleerd’
In GraphQL zou je dan bijvoorbeeld doen:
{ Orders(Customer: 123) { annuleringen }}
en dan krijg je een lijst met orders van die klant die geannuleerd zijn. In de annuleringen je andere eigenschappen staan dan in bestellingen terwijl ze onder de motorkap allebei uit de tabel Orders komen. Dus heel logisch en intuitief voor de ontwikkelaar.
Maar platgeslagen doet je met GraphQL hetzelfde als wat je ook met SOAP of REST zou willen doen.
Hoop dat deze toelichting wat verduidelijkt.
Henri,
Benno wijst op de reacties, ik ben mogelijk debet aan het idee dat we met GraphQL terug gaan in de tijd wat ik graag wil ontkrachten omdat naar mijn mening de architectuur niet gebaseerd is op een client-server model maar het concept van REST, een software-architectuur voor gedistribueerde systemen zoals het wereldwijde web. Mijn zorgen over de autorisaties hierin heb ik al kenbaar gemaakt, je voorbeeld van een query over de geannuleerde orders is voor de concurrentie namelijk heel interessant. Het delen van kennis kan ook tegen je werken als we kijken naar bedrijfspionage middels arbeidsmobiliteit.
Ik heb er ook even naar gekeken en een korte cursus gedaan. De volgende zaken lijken me interessant:
1) De client bepaald welke data ze ophaalt en hoeveel dus ook
2) Filters worden bepaald en worden ook door client bepaald
Ad 1. Je bent nog wel afhankelijk van het graph model dat je opstelt en hoe makkelijk de verschillende nodes (data entiteiten) zijn te koppelen met de backend systemen. Hiermee kun je mooi voor de client in 1 call data bij elkaar harken waar dit vaak met REST met meerdere resource calls moet. Dus je kunt performance winnen.
Ad 2. Aangezien je met REST custom moet afspreken welke query parameters je allemaal mag gebruiken is er veel afstemming nodig en implementatie wanneer dit verandert. Met GraphQL is een standaard gedefinieerd en krijg je veel out-of-the-box (zoals filtering en pagination).
Ik ben zeer geïnteresseerd naar de ervaringen van mensen hier.
RJH,
Mooie toevoeging en goede observatie.
Mijn ervaring weet je al en wil best een keer een demo geven van productie.
Henri,
bedankt voor je aanvulling. Mijn veronderstelling was inderdaad dat je een soort sql achtige taal had waarbij je direct op de achterliggende DB queries gaat afvuren.
Met “geen weet hebben van de database structuur” bedoel ik dat je dat naar mijn mening los moet trekken in je middleware. Hoe data opgeslagen worden is voor de client helemaal niet relevant, die moet gewoon functionele data krijgen in objecten. Daardoor kun je de verantwoordelijkheid voor bv de database(s) ook los trekken en neerleggen bij de juiste personen. Voor de clients blijft alles gelijk als er bv aan de DB kant wijzigingen zijn.
Ik zal er de komende tijd eens wat meer over gaan lezen. Voorlopig blijft Rest voldoende ;).
Wat mij zeer aanspreekt is de aansluitbaarheid op Python, en daarmee ook de mogelijke koppeling met een 5GL zoals ik deze voorsta: https://www.dt5gl.com/
Net als SQL is GraphQL een declaratieve taal en dus 4GL. Maar binnen 4GL is hier sprake van een evolutie, getuige deze op internet gevonden quote (die mij zeer aanspreekt): GraphQL is SQL for Knowledge, not Data.
In één oplossing heb ik de koppeling met SQL laten zien (Organs-part2.txt), maar dat zou dus net zo goed (en nog veel krachtiger) met GraphQL kunnen!
Ondertussen zou ik nog wel eens een oplossing voor deze challenge met een lowcode of nocode tool willen zien, maar dat nu geheel terzijde.
In ieder geval een leuk geschreven, informatief opiniestuk!
Hi Jack,
Bedankt voor je compliment! Ik weet nog niet of ik klaar ben voor 5GL en zou nog wel een keer een voorbeeld van GraphQL met beslissingstabellen willen zien.
en wij gebruiken o.a. Python icm GraphQL.
Henri, het aardige is dat jij dat voorbeeld veel sneller kan geven dan ik.
Want dat voorbeeld krijg je als je de SQL-query’s in de eerder genoemde oplossing Organs-part2.txt omzet naar GraphQL.
Is een voordeel van GraphQL boven SQL niet ook dat je een hele batterij aan joins uit de meer ingewikkelde SQL-query’s wegwerkt?
Ik heb nog even gezocht naar een SQL to GraphQL converter, maar kon niet snel een handzame vinden.
Het idee van Oudlid om GraphQL in te zetten als een soort van ESB vind ik zo gek nog niet 🙂