Uvod u GraphQL

1. Pregled

GraphQL je jezik upita, koji je Facebook stvorio u svrhu izrade klijentskih aplikacija zasnovanih na intuitivnoj i fleksibilnoj sintaksi, za opis njihovih zahtjeva za podacima i interakcija.

Jedan od primarnih izazova s ​​tradicionalnim REST pozivima je nemogućnost klijenta da zatraži prilagođeni (ograničeni ili prošireni) skup podataka. U većini slučajeva, nakon što klijent zatraži podatke od poslužitelja, ili dobiva sva ili nijedno polje.

Druga je poteškoća rad i održavanje više krajnjih točaka. Kako platforma raste, time će se i broj povećavati. Stoga klijenti često trebaju tražiti podatke s različitih krajnjih točaka.

Prilikom izrade GraphQL poslužitelja, potreban je samo jedan URL za sve dohvaćanje i mutiranje podataka. Dakle, klijent može zatražiti skup podataka slanjem niza upita, opisujući ono što želi, poslužitelju.

2. Osnovna nomenklatura GraphQL

Pogledajmo osnovnu terminologiju GraphQL-a.

  • Upit: je operacija samo za čitanje zatražena za GraphQL poslužitelj
  • Mutacija: je operacija čitanja i pisanja koja se traži na GraphQL poslužitelju
  • Razrješivač: U GraphQL-u, Razrješivač odgovoran je za mapiranje operacije i koda koji se izvodi na pozadini koji je odgovoran za obradu zahtjeva. Analogno je MVC pozadini u aplikaciji RESTFul
  • Tip: A Tip definira oblik podataka odgovora koji se mogu vratiti s GraphQL poslužitelja, uključujući polja koja su rubovi drugih Vrste
  • Ulazni: kao Tip, ali definira oblik ulaznih podataka koji se šalju na GraphQL poslužitelj
  • Skalar: je primitivac Tip, kao što je a Niz, Int, Booleova, Plutatiitd
  • Sučelje: Sučelje će pohraniti imena polja i njihove argumente, tako da GraphQL objekti mogu nasljeđivati ​​od njega, osiguravajući upotrebu određenih polja
  • Shema: U GraphQL-u Shema upravlja upitima i mutacijama, definirajući što se smije izvršiti na GraphQL poslužitelju

2.1. Učitavanje sheme

Postoje dva načina učitavanja sheme na GraphQL poslužitelj:

  1. korištenjem GraphQL-ovog jezika za definiranje sučelja (IDL)
  2. korištenjem jednog od podržanih programskih jezika

Pokažimo primjer pomoću IDL-a:

upišite Korisnik {firstName: String}

Sada, primjer definicije sheme pomoću Java koda:

GraphQLObjectType userType = newObject () .name ("User") .field (newFieldDefinition () .name ("firstName") .type (GraphQLString)) .build ();

3. Jezik definicije sučelja

Definicijski jezik sučelja (IDL) ili Jezik definicije sheme (SDL) najsažetiji je način određivanja GraphQL sheme. Sintaksa je dobro definirana i bit će usvojena u službenoj GraphQL specifikaciji.

Na primjer, stvorimo GraphQL shemu za korisnika / e-adrese koje se mogu odrediti ovako:

schema {query: QueryType} enum Spol {MALE FEMALE} upišite User {id: String! firstName: Niz! lastName: Niz! createdAt: DateTime! dob: Int! @default (value: 0) gender: [Gender]! e-mailovi: [Email!]! @relation (name: "E-mail")} upišite Email {id: String! e-mail: String! zadano: Int! @default (value: 0) user: User @relation (name: "E-mail")}

4. GraphQL-java

GraphQL-java je implementacija koja se temelji na specifikaciji i implementaciji JavaScript reference. Imajte na umu da za rad pravilno treba barem Java 8.

4.1. Bilješke GraphQL-jave

GraphQL također omogućuje upotrebu Java napomena za generiranje definicije sheme bez cjelokupnog koda stvorenog korištenjem tradicionalnog IDL pristupa.

4.2. Ovisnosti

Da bismo kreirali naš primjer, krenimo prvo s uvozom potrebne ovisnosti koja se oslanja na modul Graphql-java-annotations:

 com.graphql-java graphql-java-anotacije 3.0.3 

Također implementiramo HTTP knjižnicu kako bismo olakšali postavljanje u našoj aplikaciji. Koristit ćemo Ratpack (iako bi se mogao implementirati i s Vert.x, Spark, Dropwizard, Spring Boot itd.).

Uvezimo i ovisnost Ratpack:

 io.ratpack ratpack-core 1.4.6 

4.3. Provedba

Stvorimo naš primjer: jednostavni API koji korisnicima nudi "CRUDL" (Stvori, preuzmi, ažuriraj, izbriši i popis). Prvo, kreirajmo svoje Korisnik POJO:

@GraphQLName ("user") javna klasa Korisnik {@GraphQLField private Long id; @GraphQLField ime privatnog niza; @GraphQLField privatni niz e-pošte; // izostavljeni getteri, postavljači, konstruktori i pomoćne metode}

U ovom POJO možemo vidjeti @GraphQLName ("korisnik") anotacija, kao pokazatelj da GraphQL mapira ovu klasu zajedno sa svakim poljem označenim s @GraphQLField.

Dalje ćemo stvoriti UserHandler razred. Ova klasa nasljeđuje od odabrane knjižnice HTTP konektora (u našem slučaju, Ratpack) metodu rukovatelja, koja će upravljati i pozivati ​​GraphQL-ove Razrješivač značajka. Dakle, preusmjeravanje zahtjeva (JSON nosivosti) na odgovarajući upit ili operaciju mutacije:

@Override public void handle (Context context) baca izuzetak {context.parse (Map.class). Then (payload -> {Map parameters = (Map) payload.get ("parameters"); ExecutionResult execuResult = graphql .execute (payload) .get (SchemaUtils.QUERY) .toString (), null, this, parametri); Map result = new LinkedHashMap (); if (ExecuResult.getErrors (). isEmpty ()) {result.put (SchemaUtils.DATA, ExecuResult. getData ());} else {result.put (SchemaUtils.ERRORS, ExecuResult.getErrors ()); LOGGER.warning ("Pogreške:" + Execution Result.getErrors ());} context.render (json (rezultat)); }); }

Sada će klasa koja će podržavati operacije upita, tj. UserQuery. Kao što je spomenuto, svim metodama koje dohvaćaju podatke sa poslužitelja do klijenta upravlja ova klasa:

@GraphQLName ("query") javna klasa UserQuery {@GraphQLField javni statični korisnik retrieveUser (DataFetchingEnvironment env, @NotNull @GraphQLName ("id") String id) {// return user} @GraphQLField javni statički popis popisaUser (DataFetchingEnvironment en // povratak popisa korisnika}}

Slično kao UserQuery, sada stvaramo UserMutation, koji će upravljati svim operacijama koje namjeravaju promijeniti neke zadane podatke pohranjene na strani poslužitelja:

@GraphQLName ("mutacija") javna klasa UserMutation {@GraphQLField javni statički korisnik createUser (DataFetchingEnvironment env, @NotNull @GraphQLName ("name") Ime niza, @NotNull @GraphQLName ("email") String e-pošta) {// stvoriti korisnika informacije}}

Vrijedno je primijetiti napomene u obje UserQuery i UserMutation klase: @GraphQLName ("upit") i @GraphQLName („mutacija“). Te se bilješke koriste za definiranje operacija upita i mutacije.

Pomoću GraphQL-java poslužitelja koji može izvoditi operacije upita i mutacije, možemo koristiti sljedeća JSON opterećenja za testiranje zahtjeva klijenta prema poslužitelju:

  • Za operaciju CREATE:
{"query": "mutacija ($ name: String! $ email: String!) {createUser (name: $ name email: $ email) {id name email age}}", "parametri": {"name": " John "," email ":" [e-mail zaštićen] "}} 

Kao odgovor poslužitelja za ovu operaciju:

{"data": {"createUser": {"id": 1, "name": "John", "email": "[email zaštićen]"}}}
  • Za operaciju RETRIEVE:
{"query": "query ($ id: String!) {retrieveUser (id: $ id) {name email}}", "parametri": {"id": 1}}

Kao odgovor poslužitelja za ovu operaciju:

{"data": {"retrieveUser": {"name": "John", "email": "[email protected]"}}}

GraphQL pruža značajke koje klijent može prilagoditi odgovoru. Dakle, u posljednjoj operaciji RETRIEVE koja je korištena kao primjer, umjesto vraćanja imena i e-pošte, možemo, na primjer, vratiti samo e-poštu:

{"query": "query ($ id: String!) {retrieveUser (id: $ id) {email}}", "parametri": {"id": 1}}

Dakle, povratne informacije s GraphQL poslužitelja vratit će samo tražene podatke:

{"data": {"retrieveUser": {"email": "[email protected]"}}}

5. Zaključak

GraphQL je jednostavan i prilično atraktivan način za smanjivanje složenosti između klijenta / poslužitelja kao alternativni pristup REST API-ima.

Kao i uvijek, primjer je dostupan u našem GitHub spremištu.


$config[zx-auto] not found$config[zx-overlay] not found