Početak rada s GraphQL-om i Spring Boot-om

1. Uvod

GraphQL je relativno novi koncept s Facebooka koji se naplaćuje kao alternativa REST-u za web API-je.

Ovaj će članak dati uvod u postavljanje GraphQL poslužitelja pomoću Spring Boota kako bi se mogao dodati postojećim aplikacijama ili koristiti u novim.

2. Što je GraphQL?

Tradicionalni REST API-ji rade s konceptom resursa kojima poslužitelj upravlja. Ovim se resursima može manipulirati na neke standardne načine, slijedeći različite HTTP glagole. To funkcionira vrlo dobro dok god naš API odgovara konceptu resursa, ali se brzo raspada kad od njega moramo odstupiti.

To također pati kad klijentu istodobno trebaju podaci iz više izvora. Na primjer, traženje objave na blogu i komentara. To se obično rješava tako što klijent uputi više zahtjeva ili tako što poslužitelj isporuči dodatne podatke koji možda nisu uvijek potrebni, što dovodi do većih veličina odgovora.

GraphQL nudi rješenje za oba ova problema. Omogućuje klijentu da precizno navede koji su podaci željeni, uključujući navigaciju podređenim resursima u jednom zahtjevu, a omogućuje više upita u jednom zahtjevu.

Također radi na mnogo RPC način, koristeći imenovane upite i mutacije umjesto standardnog obveznog skupa radnji. To djeluje na postavljanje kontrole tamo gdje joj pripada, s tim da programer API-ja određuje što je moguće, a potrošač API-ja što želi.

Na primjer, blog može dopustiti sljedeći upit:

upit {recentPosts (count: 10, offset: 0) {id title title author {id name thumbnail}}}

Ovaj upit će:

  • zatraži deset najnovijih postova
  • za svaki post zatražite ID, naslov i kategoriju
  • za svaki post traži autor, vraćajući ID, ime i sličicu

U tradicionalnom REST API-u za ovo je potrebno 11 zahtjeva - 1 za postove i 10 za autore - ili mora uključiti detalje o autoru u pojedinosti posta.

2.1. GraphQL sheme

GraphQL poslužitelj izlaže shemu koja opisuje API. Ova se shema sastoji od definicija tipa. Svaka vrsta ima jedno ili više polja, koja uzimaju nula ili više argumenata i vraćaju određeni tip.

Grafikon je napravljen prema načinu na koji su ta polja međusobno ugniježđena. Imajte na umu da nema potrebe da graf bude acikličan - ciklusi su sasvim prihvatljivi - ali je usmjeren. Odnosno, klijent može doći iz jednog polja do svoje djece, ali se ne može automatski vratiti roditelju ako shema to izričito ne definira.

Primjer GraphQL sheme za blog može sadržavati sljedeće definicije, opisujući post, autora posta i root zahtjev za dobivanje najnovijih postova na blogu.

upišite Post {id: ID! naslov: String! tekst: Niz! kategorija: Autor niza: Autor! } upišite Autor {id: ID! ime: Niz! minijatura: String postovi: [Objavi]! } # Korijenski upit za vrstu aplikacije Query {recentPosts (count: Int, offset: Int): [Objavi]! } # Korijenska mutacija za vrstu aplikacije Mutation {writePost (naslov: String !, tekst: String !, kategorija: String): Objavi! }

"!" na kraju nekih imena označava da je ovo tip koji se ne može poništiti. Bilo koja vrsta koja to nema može biti ništavna u odgovoru poslužitelja. Usluga GraphQL to ispravno rješava, omogućujući nam da sigurno tražimo podređena polja nullirnih tipova.

Usluga GraphQL također izlaže samu shemu pomoću standardnog skupa polja, omogućavajući bilo kojem klijentu da unaprijed zatraži definiciju sheme.

To može omogućiti klijentu da automatski otkrije promjene sheme i klijentima koji se dinamički prilagođavaju načinu rada sheme. Jedan nevjerojatno koristan primjer toga je alat GraphiQL - o kojem ćemo kasnije raspravljati - koji nam omogućuje interakciju s bilo kojim API-jem GraphQL.

3. Predstavljamo GraphQL Spring Boot Starter

Spring Boot GraphQL Starter nudi fantastičan način za pokretanje GraphQL poslužitelja u vrlo kratkom vremenu. U kombinaciji s knjižnicom GraphQL Java Tools, trebamo samo napisati kod potreban za našu uslugu.

3.1. Postavljanje usluge

Sve što nam treba da bi funkcioniralo su ispravne ovisnosti:

 com.graphql-java graphql-spring-boot-starter 5.0.2 com.graphql-java graphql-java-tools 5.2.4 

Spring Boot će ih automatski pokupiti i postaviti odgovarajuće rukovatelje za automatski rad.

Prema zadanim postavkama ovo će izložiti uslugu GraphQL na / graphql krajnja točka naše aplikacije i prihvatit će POST zahtjeve koji sadrže GraphQL korisni teret. Ta se krajnja točka može prilagoditi u našem primjena.svojstva dosje ako je potrebno.

3.2. Pisanje sheme

Biblioteka GraphQL Tools radi tako da obrađuje datoteke GraphQL Schema kako bi izgradila ispravnu strukturu, a zatim na nju poveže posebne grahove. Starter Spring Boot GraphQL automatski pronalazi ove datoteke sheme.

Te datoteke treba spremiti s nastavkom “.graphqls"I može biti prisutan bilo gdje na stazi. Također možemo imati onoliko datoteka koliko želimo, tako da shemu možemo podijeliti na module po želji.

Jedan je uvjet da mora postojati točno jedan upit za korijen i do jedne mutacije korijena. To se ne može podijeliti na datoteke, za razliku od ostatka sheme. Ovo je ograničenje same definicije GraphQL sheme, a ne implementacije Jave.

3.3. Rješivač korijenskih upita

Korijenski upit mora imati posebne grahove definirane u kontekstu Spring da bi obrađivao različita polja u ovom root zahtjevu. Za razliku od definicije sheme, ne postoji ograničenje da postoji samo jedan grah Spring za korijenska polja upita.

Jedini su zahtjevi da grah provodi GraphQLQueryResolver i da svako polje u korijenskom upitu iz sheme ima metodu u jednoj od ovih klasa s istim imenom.

javni razred Query implementira GraphQLQueryResolver {private PostDao postDao; javni popis getRecentPosts (int count, int offset) {return postsDao.getRecentPosts (count, offset); }}

Imena metode moraju biti jedno od sljedećeg, ovim redoslijedom:

  1. je - samo ako je polje tipa Booleova
  2. dobiti

Metoda mora imati parametre koji odgovaraju bilo kojim parametrima u GraphQL shemi, a po želji može uzeti i konačni parametar tipa DataFetchingEnvironment.

Metoda također mora vratiti ispravan tip povrata za tip u shemi GraphQL, kao što ćemo vidjeti. Bilo koji jednostavan tip - String, Int, List, itd. - mogu se koristiti s ekvivalentnim vrstama Java, a sustav ih samo automatski mapira.

Gore navedeno definira metodu getRecentPosts koji će se koristiti za obradu bilo kojih GraphQL upita za Najnoviji postovi polje u ranije definiranoj shemi.

3.4. Korištenje graha za predstavljanje vrsta

Svaki složeni tip na GraphQL poslužitelju predstavljen je Java grahom - bilo da je učitan iz korijenskog upita ili bilo gdje drugdje u strukturi. Ista Java klasa mora uvijek predstavljati isti GraphQL tip, ali naziv klase nije potreban.

Polja unutar Java zrna bit će izravno mapirana na polja u odgovoru GraphQL na temelju imena polja.

javna klasa Post {private String id; privatni naslov niza; kategorija privatni niz; private String authorId; }

Sva polja ili metode na Java grahu koja se ne preslikaju na shemu GraphQL bit će zanemarene, ali neće uzrokovati probleme. Ovo je važno za rad terenskih razrješivača.

Na primjer, polje autorId ovdje ne odgovara ničemu u našoj shemi koju smo prethodno definirali, ali bit će dostupna za korištenje za sljedeći korak.

3.5. Terenski rješavači za složene vrijednosti

Ponekad vrijednost polja nije trivijalno za učitavanje. To može uključivati ​​pretraživanja baze podataka, složene izračune ili bilo što drugo. GraphQL Tools ima koncept razlučivača polja koji se koristi u tu svrhu. To su proljetni grah koji može pružiti vrijednosti umjesto zrna podataka.

Razrješivač polja je bilo koji grah u proljetnom kontekstu koji ima isto ime kao grah podataka, sa sufiksom Razrješivač, a koja implementira GraphQLResolver sučelje. Metode na zrnu razrješivača polja slijede sva ista pravila kao i na zrnu podataka, ali također se pružaju i sami zrno podataka kao prvi parametar.

Ako razlučivač polja i grah podataka imaju metode za isto polje GraphQL, tada će razlučivač polja imati prednost.

javna klasa PostResolver implementira GraphQLResolver {private AuthorDao authorDao; javni autor getAuthor (Post post) {return authorDao.getAuthorById (post.getAuthorId ()); }}

Važna je činjenica da su ovi razlučivači polja učitani iz konteksta Spring. To im omogućuje rad s bilo kojim drugim grahom kojim se upravlja proljećem - npr. DAO.

Važno je ako klijent ne zatraži polje, tada GraphQL Server nikada neće obaviti posao za njegovo preuzimanje. To znači da ako klijent dohvati post i ne zatraži autora, tada getAuthor () gornja metoda nikada neće biti izvršena, a DAO poziv nikada neće biti izvršen.

3.6. Vrijednosti koje se mogu poništiti

Shema GraphQL ima koncept da su neke vrste zabranjene, a druge nisu.

To se može riješiti u Java kodu izravnom uporabom null vrijednosti, ali jednako tako i nove Neobvezno type iz Java 8 ovdje se može koristiti izravno za poništene tipove, a sustav će ispravno postupiti s vrijednostima.

Ovo je vrlo korisno jer znači da je naš Java kôd očiglednije isti kao shema GraphQL iz definicija metode.

3.7. Mutacije

Do sada se sve što smo radili odnosilo na dohvaćanje podataka s poslužitelja. GraphQL također ima mogućnost ažuriranja podataka pohranjenih na poslužitelju, pomoću mutacija.

S gledišta koda, nema razloga da Upit ne može promijeniti podatke na poslužitelju. Lako bismo mogli napisati rješavače upita koji prihvaćaju argumente, spremaju nove podatke i vraćaju te promjene. To će uzrokovati iznenađujuće nuspojave za API klijente i smatra se lošom praksom.

Umjesto toga, Mutacije treba upotrijebiti za obavještavanje klijenta da će to dovesti do promjene podataka koji se pohranjuju.

Mutacije su definirane u Java kodu pomoću klasa koje implementiraju GraphQLMutationResolver umjesto GraphQLQueryResolver.

Inače se primjenjuju sva ista pravila kao i za upite. Povratna vrijednost iz polja Mutacija tada se tretira potpuno isto kao i iz polja Query, omogućavajući i dohvaćanje ugniježđenih vrijednosti.

javna klasa Mutation implementira GraphQLMutationResolver {private PostDao postDao; javni post writePost (naslov niza, tekst niza, kategorija niza) {return postDao.savePost (naslov, tekst, kategorija); }}

4. Predstavljamo vam GraphiQL

GraphQL također ima i prateći alat zvan GraphiQL. Ovo je korisničko sučelje koje je u mogućnosti komunicirati s bilo kojim GraphQL poslužiteljem i izvršavati upite i mutacije protiv njega. Njegova verzija za preuzimanje postoji kao aplikacija Electron i može se preuzeti odavde.

Također je moguće automatski uključiti web verziju GraphiQL-a u našu aplikaciju dodavanjem ovisnosti GraphiQL Spring Boot Starter:

 com.graphql-java graphiql-spring-boot-starter 5.0.2 

To će raditi samo ako svoj GraphQL API hostiramo na zadanoj krajnjoj točki / graphql ipak, zato će biti potrebna samostalna aplikacija ako to nije slučaj.

5. Sažetak

GraphQL je vrlo uzbudljiva nova tehnologija koja potencijalno može revolucionirati način na koji se razvijaju web API-ji.

Kombinacija Spring Boot GraphQL Startera i GraphQL Java Tools biblioteka čine nevjerojatno jednostavnim dodavanje ove tehnologije u bilo koji novi ili postojeći Spring Boot program.

Isječke koda možete pronaći na GitHubu.