Het Ontwerpen van Schaalbare Java API’s met GraphQL

Heb je je ooit afgevraagd of er een betere manier is om gegevens op te halen voor je applicaties dan via REST API’s? In back-endontwikkeling is GraphQL naar voren gekomen als een krachtig alternatief, met een meer flexibele en efficiënte benadering voor het ophalen van gegevens. Voor ontwikkelaars die bekend zijn met Java opent het integreren van GraphQL in een moderne backend de deur naar schaalbare en hoogwaardige API’s die zijn afgestemd op een breed scala aan toepassingen.

In deze blog zullen we de belangrijkste verschillen tussen GraphQL en REST verkennen, de unieke voordelen van het gebruik van GraphQL voor gegevensophalen benadrukken, en je begeleiden bij het implementeren van een GraphQL API in Java met een voorbeeld uit de praktijk.

Wat Is GraphQL?

GraphQL is een querytaal voor API’s en een runtime voor het uitvoeren van die vragen. In tegenstelling tot REST, waar vaste eindpunten vooraf gedefinieerde gegevens teruggeven, stelt GraphQL clients in staat precies de gegevens op te vragen die ze nodig hebben. Deze granulariteit maakt GraphQL zeer efficiënt, vooral voor complexe of gegevensintensieve toepassingen.

Voordelen van de GraphQL-benadering:

  • Grondig Gegevens ophalen: De client kan bijvoorbeeld alleen naam en functie opvragen zonder onnodige velden zoals afdeling op te halen.
  • Gekoppelde Vragen: Haal de details van de manager op samen met de informatie van de werknemer in één query.
  • Schema-Gedreven Ontwikkeling: Het schema fungeert als een contract, waardoor API-evolutie gemakkelijker wordt.

Wat Is REST API?

Representational State Transfer (REST) is een architectuurstijl voor het bouwen van API’s. Het maakt gebruik van standaard HTTP-methoden zoals GET, POST, PUT en DELETE om CRUD-operaties uit te voeren. REST staat bekend om zijn eenvoud en brede adoptie.

Beperkingen van REST:

  • Over- of onder-ophalen van gegevens.
  • Vereist meerdere eindpunten en versiebeheer om wijzigingen te accommoderen.
  • Geen ingebouwde real-time mogelijkheden.

GraphQL vs. REST API: Wat is het verschil?

GraphQL en REST zijn twee populaire benaderingen voor het bouwen van API’s, elk met zijn sterke punten. Terwijl REST jarenlang de standaard is geweest, biedt GraphQL meer flexibiliteit en efficiëntie, met name op het gebied van gegevensopvraging en samenwerking tussen front-end en back-end teams.

Belangrijkste verschillen

  • In tegenstelling tot REST, dat meerdere eindpunten gebruikt en versiebeheer vereist voor wijzigingen, consolideert GraphQL gegevensopvraging in één enkele query en vermindert de behoefte aan versiebeheer doordat cliënten gegevensvereisten specificeren.
  • Terwijl REST HTTP-statuscodes gebruikt om succes of fouten aan te geven, retourneert GraphQL altijd een 200 OK-status en communiceert fouten in het responslichaam.
  • GraphQL ondersteunt ook real-time updates via abonnementen, in tegenstelling tot REST, dat geen ingebouwde ondersteuning voor real-time heeft.
  • Hoewel REST wijdverspreid is met vele tools, is de omgeving van GraphQL snel gegroeid en biedt krachtige tools zoals GraphiQL voor eenvoudigere ontwikkeling.
  • Ten slotte, terwijl REST headers gebruikt voor caching, vereist GraphQL meer geavanceerde technieken vanwege dynamische queries, maar biedt opties zoals persistente queries voor efficiënte caching.

Kernconcepten van GraphQL

1. Schema Definitietaal (SDL)

GraphQL heeft zijn eigen type systeem dat wordt gebruikt om het schema van een API te definiëren. De syntaxis voor het schrijven van schema’s wordt Schema Definitietaal (SDL) genoemd.

2. Queries vs. Mutaties vs. Abonnementen

  • Queries worden gebruikt om gegevens van de server op te halen. In tegenstelling tot REST, dat meerdere vaste eindpunten gebruikt, gebruikt GraphQL een enkel eindpunt, en de client specificeert de benodigde gegevens in de query, wat flexibiliteit biedt.
  • Mutaties worden gebruikt om gegevens op de server te wijzigen, zoals het creëren, bijwerken of verwijderen van gegevens. Ze stellen clients in staat om wijzigingen naar de backend te sturen en zijn essentieel voor toepassingen die gegevens moeten schrijven.
  • Abonnementen stellen realtime updates mogelijk door een constante verbinding tussen de client en de server te onderhouden. Wanneer een geabonneerd evenement plaatsvindt, duwt de server updates naar de client, wat continue gegevensstromen biedt, in tegenstelling tot queries en mutaties, die een aanvraag-responscyclus volgen.

3. GraphQL-schema

Het definieert de gegevensstructuur die kan worden bevraagd of gewijzigd, en fungeert als een contract tussen de server en de client. Het specificeert de types, velden en relaties die beschikbaar zijn voor cliënten om toegang tot te krijgen. Het schema omvat typisch speciale hoofdtypes: Query voor gegevensopvraging, Mutation voor het wijzigen van gegevens, en Subscription voor realtime updates. Deze types definiëren gezamenlijk de mogelijkheden van de API en hoe cliënten ermee kunnen communiceren.

4. Resolvers: Het koppelen van GraphQL Queries aan Gegevens

Resolvers zijn functies die de logica afhandelen voor het ophalen van gegevens in een GraphQL-server. Elk veld in een schema is gekoppeld aan een resolver, die bepaalt hoe de gegevens voor dat veld moeten worden opgehaald of berekend. Wanneer een query wordt uitgevoerd, roept de server de juiste resolvers aan voor de gevraagde velden. Resolvers kunnen scalars of objecten retourneren, waarbij de uitvoering doorgaat voor kindvelden als er een object wordt geretourneerd en eindigt als er een scalar wordt geretourneerd. Als er null wordt geretourneerd, stopt de uitvoering. Resolvers zijn essentieel voor het koppelen van GraphQL queries aan de werkelijke gegevensbronnen.

Voordelen van het Gebruik van GraphQL in Java

  1. Nauwkeurig Gegevens Ophalen: Vraag alleen de benodigde gegevens op, niets meer, waardoor voorspelbare en efficiënte resultaten worden gegarandeerd.
  2. Eén Verzoek voor Meerdere Bronnen: Haal gerelateerde gegevens op in één query, waardoor meerdere API-aanroepen worden verminderd.
  3. Type-systeem: Organiseert API’s op basis van types en velden, waardoor queries geldig zijn en fouten duidelijk zijn.
  4. Ontwikkelaarstools: Verhoog de productiviteit met tools zoals GraphiQL, waarbij type-definities worden gebruikt voor betere queryconstructie en debugging.
  5. Versieloze evolutie: Voeg velden toe of deprecieer ze zonder bestaande query’s te verbreken, waardoor API’s onderhoudbaar blijven.
  6. Flexibele gegevensintegratie: Creëer een eenduidige API over bestaande gegevens en code die compatibel is met verschillende opslagengines en talen.

Opzetten van een GraphQL API in Java

Realistisch voorbeeld: Gebruikers en bestellingen

Stel je voor dat je een API voor een medewerkersdirectory bouwt voor een grote organisatie. Het doel is om klanten in staat te stellen details op te vragen zoals de naam van de werknemer, functie, afdeling en zelfs hun rapportagehiërarchie.

1. Project instellen

Maak een nieuw Spring Boot-project met behulp van Spring Tool Suite of ga naar Spring Initialiser. Voeg vervolgens deze afhankelijkheden toe aan het pom.xml-bestand:

XML

 

2. Maak uw entiteiten

Maak Java-entiteiten (bijv. Gebruiker en Bestelling) om de gegevens te vertegenwoordigen die via GraphQL zullen worden bevraagd of gewijzigd. Bijvoorbeeld:

Java

 

3. Maak Repositories

Maak repositories om te communiceren met de database:

Java

 

4. Maak serviceklassen

Maak serviceklassen aan om bedrijfslogica af te handelen:

Java

 

5. Maak GraphQL-controllers

Definieer GraphQL-controllers om queries en mutaties af te handelen:

Java

 

6. Definieer je GraphQL-schema

Maak een schema.graphqls-bestand aan in de src/main/resources-map:

Plain Text

 

7. Configureer GraphQL in application.properties

Optioneel, configureer GraphQL-instellingen in scr/main/resources/application.properties:

Properties files

 

8. Start je applicatie

Start de SpringBoot-applicatie met mvn spring-boot:run of vanuit je IDE. Als het draait, kun je toegang krijgen tot het GraphAL-eindpunt op /graphiql.

9. Test met GraphQL-queries

Test de GraphQL-API met een tool zoals GraphiQL of Postman.

Voor Mutatie: 

Plain Text

 

Output:

Plain Text

 

Voor Query:

Plain Text

 

Output:

JSON

 

Geavanceerde GraphQL-functies

1. Verbeter de herbruikbaarheid met fragmenten

Een fragment is in feite een herbruikbare set velden gedefinieerd voor een specifiek type. Het is een functie die de structuur en herbruikbaarheid van je GraphQL-code verbetert.

2. Velden parameteriseren met argumenten

In GraphQL kunnen velden argumenten accepteren om queries dynamischer en flexibeler te maken. Deze argumenten stellen je in staat om de data die door de API wordt geretourneerd te filteren of aan te passen.

3. Pagineren en Sorteren met GraphQL

Paginering

Paginering is een lastig onderwerp in API-ontwerp. Op een hoog niveau zijn er twee belangrijke benaderingen met betrekking tot hoe dit kan worden aangepakt.

  • Limiet-offset: Vraag een specifiek deel van de lijst op door de indices van de items die moeten worden opgehaald te verstrekken (in feite verstrek je voornamelijk het startindex (offset) evenals een telling van items die moeten worden opgehaald (limiet)).
  • Cursor-gebaseerd: Dit paginatiemodel is iets geavanceerder. Elk element in de lijst is geassocieerd met een unieke ID (de cursor). Clients die door de lijst pagineren verstrekken dan de cursor van het startelement evenals een telling van items die moeten worden opgehaald.

Sorteren

Met Graphql API-ontwerp is het mogelijk om lijsten van elementen terug te geven die zijn gesorteerd (geordend) volgens specifieke criteria.

Uitdagingen en Overwegingen bij het Gebruik van GraphQL

  • Complexiteit: Het beheren van GraphQL-schema’s en queries kan uitdagend zijn voor eenvoudige datamodellen of onervaren teams.
  • Prestatieproblemen: Diep geneste queries kunnen backend-resources belasten als ze niet zijn geoptimaliseerd.
  • Caching-uitdagingen: Standaard op REST gebaseerde cachingstrategieën zijn niet van toepassing en vereisen aangepaste oplossingen.
  • Beveiligingszorgen: Over-fetching en kwaadaardige query’s vereisen querylimieten en andere beveiligingsmaatregelen.
  • Hybride gebruik: Werkt het beste voor complexe gegevensbehoeften, vaak gecombineerd met REST voor eenvoudigere bewerkingen.

Conclusie

GraphQL biedt een flexibele en efficiënte benadering voor het bouwen van moderne API’s in Java, waardoor het een ideale keuze is voor dynamische en data-intensieve toepassingen. De architectuur met één eindpunt en sterke typen vereenvoudigen API-ontwerp en zorgen voor robuuste prestaties. Of je nu een eenvoudige werknemersgids of een complex analytics platform creëert, GraphQL stelt ontwikkelaars in staat om schaalbare oplossingen met gemak te leveren. Begin vandaag met het verkennen van GraphQL met tools zoals Spring Boot en graphql-java om het volledige potentieel ervan te ontsluiten in je volgende project.

Broncode

Je kunt de volledige broncode voor deze zelfstudie vinden op Github.

Source:
https://dzone.com/articles/design-scalable-java-apis-with-graphql