Inhoudsopgave

Voordelen van het gebruik van GraphQL boven REST API's

Een van de meest voorkomende problemen met REST is het over- en onderhalen van gegevens. Dit gebeurt omdat de enige manier voor een cliënt om gegevens te downloaden is door eindpunten aan te spreken die vaste gegevensstructuren teruggeven. Het is moeilijk om de API zo te ontwerpen dat hij klanten precies kan voorzien in hun gegevensbehoeften.

  • GraphQL vermindert netwerkverzoeken door ons in staat te stellen alle gegevens die we nodig hebben in een enkele query op te halen.
  • Met GraphQL is er geen behoefte aan versiebeheer, omdat we gemakkelijk nieuwe velden en types aan onze GraphQL API kunnen toevoegen zonder de bestaande queries te beïnvloeden. Ook kunnen we gemakkelijk velden markeren als afgeschreven, en de velden zullen worden uitgesloten van het antwoord dat van de server wordt ontvangen.
  • Met GraphQL kunt u ook prestatiebewaking op laag niveau uitvoeren op de verzoeken die door uw server worden verwerkt. GraphQL gebruikt het concept van resolverfuncties om de gegevens te verzamelen die een klant opvraagt. Het instrumenteren en meten van de prestaties van deze resolvers levert cruciale inzichten op over knelpunten in uw systeem.

Korte uitleg over hoe GraphQL werkt

GraphQL implementatie bevat voornamelijk drie onderdelen

  • Schema - Beschrijft de gegevens.
  • Resolvers - Logica voor het ophalen van gegevens uit verschillende bronnen (microservices).
  • Query - Opdrachtgever vraagt welke gegevens moeten worden opgehaald.

Schema(meer over schema's en types)

➡️
type Query{getUsers:[User]getUser(user_id:Int!):User}type Mutation{addUser(first_name:String!,last_name:String,pic:String):Boolean deleteUser(user_id:Int!):Boolean}type User{first_name:Stringlast_name:Stringpic:Stringfull_name:Stringuser_id:Int!designation:String}

De bovenstaande code beschrijft wat kan worden opgevraagd en de responsgegevens (datatype) die van de bronnen worden verwacht.

P.S: "!" betekent dat het veld niet nul of ongedefinieerd kan zijn.

Resolvers (Onderstaande code is geschreven in NodeJs)

➡️
{Query:{getUsers:(obj,args,context,info) => { return users},getUser:(obj,{user_id},context,info) => { return users.find(user => user.user_id == user_id) } },Mutation:{ addUser:(obj,{first_name,last_name,pic},context,info) => { users.push({ first_name:first_name, last_name:last_name, pic:pic }) return true },deleteUser:(obj,{user_id},context,info) => { for (var i = 0; i < users.length; i++) { if(users[i].user_id == user_id){ users.splice(i,1) return true }}return false } }, User:{ full_name:(prev_obj,args,context,info) => { return `${prev_obj.first_name} ${prev_obj.last_name}`}}}

De bovenstaande code beschrijft de logica die wordt uitgevoerd wanneer de cliënt een verzoek indient.

P.S. Ik heb de full_name resolver functie voor User type gebruikt voor het schrijven van mijn eigen logica.

Query(Meer over query)

➡️
{getUsers{full_name pic}}

Declient doet een query met bovenstaande code die alleen full_name en pic teruggeeft zoals hieronder.

P.S. Client kan alleen zoeken naar velden die in het Schema zijn gedefinieerd.

➡️
{"data":{"getUsers":{"full_name":"Srinivasa Sainath", "pic":"https://vpms.xoxoday.com/images/xoxoday.png"}}}

Het clientverzoek kan bestaan uit Query en Mutation ( en Subscription. Dit zal worden besproken in toekomstige blogs van de GraphQL-serie).

Beide verzoeken doen hetzelfde. Behalve dat Mutation synchroon wordt uitgevoerd. De conventie die wordt gevolgd is dat Mutation wordt gebruikt voor elke operatie die leidt tot schrijven in de server (profiel bijwerken, bestelling aanmaken, enz.) en een query wordt gebruikt voor het ophalen van gegevens (menu ophalen, lijst met vouchers ophalen, enz.). ( Vergelijkbaar met GET en POST ). Technisch gezien kunnen beide soorten verzoeken worden gebruikt om eender welke logica uit te voeren. Maar het is beter om de conventie te volgen, omdat het uw team helpt.

Belangrijke punten voor een goed begrip van de relatie tussen resolverfuncties en query's

  • U kunt elk veld in een GraphQL query zien als een functie of methode van het vorige type die het volgende type retourneert. Dit is precies hoe GraphQL werkt. Elk veld van elk type wordt ondersteund door een functie genaamd de resolver, geleverd door de GraphQL-serverontwikkelaar. De bijbehorende resolver wordt aangeroepen om de volgende waarde te produceren wanneer een veld wordt uitgevoerd.
  • De uitvoering is voltooid als een veld een scalaire waarde oplevert, zoals een string of een getal. Heeft een veld echter een objectwaarde, dan bevat de query nog een selectie van velden die op dat object van toepassing zijn. Dit gaat door totdat scalaire waarden zijn bereikt. GraphQL query's eindigen altijd bij scalaire waarden.

Een resolver-functie ontvangt vier argumenten

Syntax :

➡️
{getUsers:(obj,args,context,info) =>{ return users }}
  • obj Het vorige object, dat voor een veld op de root Query type vaak niet wordt gebruikt.
    Om meer over dit argument te begrijpen, zie GraphQL Server With Node.js.
  • args De argumenten die in de GraphQL query aan het veld worden gegeven. In de bovenstaande resolver-functie is {user_input} de args
  • context Een waarde die aan elke resolver wordt verstrekt en die belangrijke contextuele informatie bevat, zoals de momenteel ingelogde gebruiker of de toegang tot een database. In de bovenstaande resolver wordt functie context gebruikt voor het doorgeven van token_info
  • info Een waarde die veldspecifieke informatie bevat die relevant is voor de huidige query, evenals de details van het schema. Wordt vaak niet gebruikt
➡️
Clone the demo GraphQL project from here.P.S. In the next part of the GraphQL series, I will discuss how to implement GraphQL as an API Gateway.
Srinivasa Sainath

Srinivasa Sainath