Πώς να ενεργοποιήσετε τον διακομιστή GraphQL Java σε λειτουργία σε χρόνο μηδέν

Το GraphQL είναι μια γλώσσα ερωτήματος για τη λήψη δεδομένων μέσω του Διαδικτύου. Από τη δημόσια ανακοίνωσή του από το Facebook το 2015, έχει προκαλέσει ενδιαφέρον σε πολλά μυαλά. Το GraphQL έχει χρησιμοποιηθεί κυρίως σε JavaScript. Στην πραγματικότητα, το Facebook κυκλοφόρησε την εφαρμογή αναφοράς για αυτό σε JavaScript (graphql-js).

Αλλά αυτή η ανάρτηση ιστολογίου θα επικεντρωθεί στην ανάπτυξη του διακομιστή GraphQL στην Java. Το GraphQL-Java είναι η αντίστοιχη υλοποίηση GraphQL στην Java και λαμβάνει ενημερώσεις και βελτιώσεις έκδοσης σχεδόν κάθε μήνα. Λειτουργίες όπως ενοργάνωση, ασύγχρονες κλήσεις προς το backend, το dataloader, οδηγίες και πολλά άλλα το καθιστούν ένα πολύ ενδιαφέρον και ισχυρό αποθετήριο στην Java.

Πώς να δημιουργήσετε έναν διακομιστή GraphQL Java στο springboot

Ας πάρουμε το παράδειγμα μιας μαγικής σχολής από το Σύμπαν του Χάρι Πότερ . Τα δεδομένα της μαγικής σχολής έχουν ως εξής:

Εδώ τα DataStores μπορούν να είναι διακομιστές backend ή ακόμα και βάσεις δεδομένων. Μια επαναληπτική λήψη θα μοιάζει παρακάτω.

GET: /student?{parameters}GET: /House?{parameters}

Βασικά εκθέστε μια διεπαφή για μια υπηρεσία. Έτσι, εάν προστεθούν καθηγητές στο παραπάνω μοντέλο, τότε πρέπει να ανοίξει ένα νέο τελικό σημείο και ο πελάτης πρέπει να κάνει πολλαπλά δρομολόγια μετ 'επιστροφής. Επίσης, εάν ο πελάτης θέλει ένθετα δεδομένα όπως το ραβδί του ΧάριπροέλευσηήΤο χρώμα του σπιτιού του Ρον,τότε ο διακομιστής API πρέπει να καλέσει το backend δύο φορές. Θα οδηγήσει επίσης σε ορισμένες ανεπιθύμητες πληροφορίες για το σπίτι και το ραβδί.

Enter GraphQL : Το GraphQL είναι μια προσέγγιση που βασίζεται σε σχήμα για τη λήψη δεδομένων. Μοντελοποιεί τα δεδομένα ως γραφήματα και θα πρέπει να εκδώσετε ένα ερώτημα για τη λήψη των δεδομένων. Λειτουργεί όπως SQL, αλλά για αντικείμενα ιστού. Έτσι, ένα ερώτημα graphQL για τον Χάρι μοιάζει με:

query{Magic School{Student{namewand{origin}}}}

Πριν πάμε στο GraphQL, πρέπει να εγκαταστήσουμε ένα ελατήριο MVC. Ο ευκολότερος τρόπος για να γίνει αυτό είναι το SpringBootStarter. Μπορείτε να επιλέξετε το επιθυμητό εργαλείο αυτοματισμού κατασκευής. Αυτό δίνει ένα πακέτο ενσωματωμένο ελατήριο Tomcat έτοιμο για λειτουργία στη θύρα 8080. Για να δοκιμάσετε το Tomcat, εκτελέστε:

$gradle clean build$java -jar ./build/libs/graphql-demo-0.0.1-SNAPSHOT.jar

Από προεπιλογή, το Gradle ονομάζει το JAR "project_name-version-SNAPSHOT.jar". Ελέγξτε http: localhost: 8080για να δείτε το Tomcat να τρέχει στη θύρα 8080.

Ας προσθέσουμε τώρα μια εξάρτηση GraphQL-Java στο build.gradle μας .

dependencies {compile('com.graphql-java:graphql-java:{version}')compile group: 'org.json', name: 'json', version: '20170516'}

Προσθέστε την τρέχουσα έκδοση όπως βρίσκεται στο αποθετήριο mavenCentral. Επί του παρόντος, η τελευταία έκδοση είναι 8.0. Προσθέστε επίσης το org.json, το οποίο είναι μια εύχρηστη βιβλιοθήκη καθώς το GraphQL χειρίζεται την απόκριση αιτήματος στο JSON

Όπως ανέφερα νωρίτερα, η GraphQL είναι μια γλώσσα που βασίζεται σε σχήμα. Ζητά από τους χρήστες να επιλέξουν αντικείμενα στο ερώτημα έναντι του σχήματος.

Ας βουτήξουμε κατευθείαν:

Έχουμε ανοίξει ένα / graphqlδιεπαφή για αιτήματα GraphQL POST . Πρέπει να δημιουργήσουμε ένα σχήμα για την αναπαράσταση δεδομένων.

  • Το SchemaGenerator αναλύει το σχήμα και δημιουργεί ένα Abstract Syntax Tree με ονόματα πεδίων ως θυγατρικούς κόμβους.
  • Στη συνέχεια, στα πεδία αντιστοιχίζονται τύποι από TypeDefinitionRegistry,για παράδειγμα Int, String και ούτω καθεξής. Το GraphQL έχει ένα ωραίο σύστημα τύπου όπου μπορούμε να έχουμε προσαρμοσμένους τύπους στο σχήμα, όπως enum, διεπαφές, συνδικάτα, λίστες και άλλα.
  • Ρίξτε μια ματιά στο βήμα RuntimeWiring () όπου το πεδίο "MagicSchool" χαρτογραφείται στο "Hogwarts" από ένα StaticDataFetcher .
  • Κάθε πεδίο υποστηρίζεται από έναν φάκελο δεδομένων και είναι έργο του υπεύθυνου επεξεργασίας δεδομένων να επιλύσει τα δεδομένα και να επιστρέψει στη GraphQL.
  • Στη συνέχεια, το GraphQL το συνδέει με τα καθορισμένα ονόματα σχήματος, είτε πρόκειται για ένθετο χάρτη λιστών είτε για γενικό χάρτη. Το GraphQL το κάνει εφ 'όσον ορίζετε το κατάλληλο σχήμα.
  • Μετά την αποστολή αυτών των δεδομένων στο ExecutionInput , η μηχανή GraphQL αναλύει-> επικυρώνει-> fetches-> εκτελεί το ερώτημα και σας επιστρέφει μια έξοδο JSON της απόκρισης χρησιμοποιώντας .toSpeci fiation ()

Ας εκδώσουμε ένα ερώτημα χρησιμοποιώντας το GraphiQL. Προσθέστε αυτήν την επέκταση στο πρόγραμμα περιήγησής σας και ορίστε το τελικό σημείο.

Δείτε πώς το σχήμα του ερωτήματός σας καθορίζει το σχήμα της απόκρισης. Το σχήμα μπορεί να γίνει ορατό λόγω της ενδοσκοπικής φύσης της GraphQL. Αυτό επιτρέπει τον έλεγχο επικύρωσης και σύνταξης του σχήματος αυτόματα λόγω του Abstract Syntax Tree που δημιουργήθηκε κατά την ανάλυση του σχήματος.

Ας προσθέσουμε μερικά περισσότερα πεδία στο σχήμα. Θα δημιουργήσουμε μια γλώσσα ορισμού σχήματος. Δημιουργήστε ένα αρχείο με το όνομα magicSchool.graphql.

type Query{magicSchool:MagicSchool}type MagicSchool{name: StringHeadMaster:Stringstudent:Student}type Student{name:Stringwand:Wandhouse:House}type House{name:Stringcolor:Stringpoints:Int}type Wand{name:Stringorigin:String}

Τροποποιήστε την πηγή σχήματος στον κώδικα και ελέγξτε το νέο σχήμα στο GraphiQL

File schemaFile = loadSchema("magicSchool.graphql");TypeDefinitionRegistry typeRegistry=schemaParser.parse(schemaFile);

Το runtimeWiring για το σχήμα και τις λήψεις αλλάζει σημαντικά για να συμπεριλάβει τους άλλους τύπους. Κάθε τύπος έχει το ανεξάρτητο DataFetcher.

Εδώ έχουμε @Autowired όλους τους ανακτήτες για να λάβουμε τα δεδομένα. Κάθε τύπος GraphQL υποστηρίζεται από ένα πρόγραμμα ανάλυσης τύπων (data fetcher). Αυτά τα προγράμματα επίλυσης είναι ανεξάρτητα το ένα από το άλλο και μπορούν να έχουν διαφορετικές πηγές. Κάθε DataFetcher εδώ έχει ένα DatafetchingEnvironment, το οποίο είναι μια διεπαφή στην εκτέλεση του ερωτήματος GraphQL. Περιέχει το ερώτημα-ορίσματα , το περιβάλλον , την εκτέλεσηId , συγκεκριμένες παραμέτρους πεδίου και ούτω καθεξής .

Ρίξτε μια ματιά στο StudentFetcher και το αποτέλεσμα του ερωτήματός μας (αγνοήστε τις επεκτάσεις):

public DataFetcher getData() { return environment -> { Map student = new HashMap(); if ("1".equalsIgnoreCase(environment.getArgument("id"))) { student.put("name", "Harry Potter"); } return student; };}

Σας θυμίζει SQL, έτσι δεν είναι; Δείτε επίσης πώς εξαλείφεται το Underfetching και το Overfetching και ο έλεγχος των δεδομένων είναι στα χέρια του πελάτη. Τώρα μπορούμε να λάβουμε τις πληροφορίες του Χάρι και του Ρον τακτοποιημένα και με μία κλήση στον διακομιστή!

Στρατηγική και οργάνωση εκτέλεσης GraphQL

Κάθε εκτέλεση ερωτήματος είναι ασύγχρονη στο graphql-java. Όταν καλείτε build.execute (εκτέλεσηInput) , επιστρέφει ένα αντικείμενο CompletableFuture που ολοκληρώνεται όταν το ερώτημα ολοκληρώνει τη ροή εκτέλεσης.

Also, as the fields are resolved separately, in the above example the Wand and House information are fetched and executed in parallel. The default ExecutionStrategy uses Java’s fork-join pool, but you can add your custom threadpool using the Executor Class.

ExecutorService executorService = new ThreadPoolExecutor( 128, /* core pool size 128 threads */ 256, /* max pool size 256 threads */ 10, TimeUnit.SECONDS, new LinkedBlockingQueue(), new ThreadPoolExecutor.CallerRunsPolicy()); return GraphQL.newGraphQL() .instrumentation(new TracingInstrumentation ()) .queryExecutionStrategy(new ExecutorServiceExecutionStrategy(executorService)) .build();}

graphql-java allows you to instrument the query execution at every point: beforeExecution, beforeParsing, andbeforeFetching. You can extend the Instrumentation class and provide your own action at each step — for example, logging the queries and returning the time of each step.

The instrumentation output provides an extensions map in Apollo Tracing format by default. This can later be used by a certain client to visualize the execution data (for example, using elastic-search and Grafana). Now you know what the extensions in the above picture mean!

The complete code of the above example can be accessed from here.

Wrapping up

There are many more features in graphql-java, like Dataloader (which solves the N+1 fetching problem), directives (which make schema writing easier), and so on. GraphQL is an emerging technology that makes the client’s life easier and can change how we do things on the Internet. That is why many companies like Facebook, Twitter, GitHub, and Coursera have already adopted it.

Θα ήθελα πολύ να ακούσω τα σχόλιά σας σχετικά με το GraphQL. Παρακαλώ μοιραστείτε τις απόψεις σας. Επίσης, αν σας αρέσει η ανάρτηση ιστολογίου, μην ξεχάσετε να χειροκροτήσετε.