GraphQL SPQR (GraphQL Schema Publisher & Query Resolver, ausgesprochen wie Sprecher ) ist eine einfach zu verwendende Bibliothek für die schnelle Entwicklung von GraphQL-APIs in Java.
GraphQL SPQR zielt darauf ab, jedem Java -Projekt eine GraphQL -API hinzuzufügen. Es wird dynamisch ein GraphQL -Schema aus Java -Code generiert.
Bei der Entwicklung von GraphQL-fähigen Anwendungen ist es üblich, zuerst das Schema zu definieren und die Geschäftslogik später anzuschließen. Dies ist als Schema-First-Stil bekannt. Während es seine Vorteile hat, führt es in stark und statisch typisierten Sprachen wie Java zu viel Vervielfältigung.
Beispielsweise könnte eine Schema -Definition eines einfachen GraphQL -Typs Folgendes mögen:
type Link {
id : ID !
url : String !
description : String
}
und üblicherweise würde im System ein entsprechender Java -Typ existieren, ähnlich wie folgt:
public class Link {
private final String id ;
private final String url ;
private final String description ;
//constructors, getters and setters
//...
}
Beide Blöcke enthalten genau die gleichen Informationen. Schlimmer noch, eine Änderung erfordert eine sofortige Veränderung zum anderen. Dies macht das Refactoring riskant und umständlich, und der Compiler kann nicht helfen. Wenn Sie hingegen versuchen, eine GraphQL-API in ein vorhandenes Projekt einzuführen, bedeutet das Schreiben des Schemas praktisch das Neuaufentwickeln des gesamten vorhandenen Modells. Dies ist sowohl teuer als auch fehleranfällig und leidet immer noch unter Duplizierung und mangelnder Werkzeuge.
Stattdessen verfolgt GraphQL SPQR den Code-ersten Ansatz, indem er das Schema aus dem vorhandenen Modell generiert. Dies hält das Schema und das Modell synchron und lockert das Refactoring. Es funktioniert auch gut in Projekten, bei denen GraphQL über eine vorhandene Codebasis eingeführt wird.
Beachten Sie, dass die Entwicklung im Code-ersten Stil immer noch effektiv schema-first ist, der Unterschied besteht darin, dass Sie Ihr Schema nicht in einer anderen Sprache, sondern in Java, mit Ihrer IDE, dem Compiler und all Ihren Tools, die Ihnen helfen, weiterentwickeln. Durch Brechen von Änderungen am Schema wird die Zusammenstellung fehlschlagen. Keine Notwendigkeit für Linter oder andere zerbrechliche Hacks.
GraphQL SPQR wird in Maven Central bereitgestellt.
Maven
< dependency >
< groupId >io.leangen.graphql</ groupId >
< artifactId >spqr</ artifactId >
< version >0.12.3</ version >
</ dependency >
Gradle
compile ' io.leangen.graphql:spqr:0.12.3 '
Das Beispiel verwendet Anmerkungen, die von GraphQL SPQR selbst bereitgestellt werden. Diese sind jedoch optional und die Zuordnung ist vollständig konfigurierbar, sodass vorhandene Dienste ohne Änderung über GraphQL freigelegt werden können.
Serviceklasse:
class UserService {
@ GraphQLQuery ( name = "user" )
public User getById ( @ GraphQLArgument ( name = "id" ) Integer id ) {
...
}
}
Wenn Sie das Hinzufügen von @GraphQLArgument
überspringen möchten, kompilieren Sie mit der Option -parameters
oder die Namen gehen verloren.
Domänenklasse:
public class User {
private String name ;
private Integer id ;
private Date registrationDate ;
@ GraphQLQuery ( name = "name" , description = "A person's name" )
public String getName () {
return name ;
}
@ GraphQLQuery
public Integer getId () {
return id ;
}
@ GraphQLQuery ( name = "regDate" , description = "Date of registration" )
public Date getRegistrationDate () {
return registrationDate ;
}
}
Um zusätzliche Felder an den User
-GraphQL -Typ anzuhängen, ohne die User
zu ändern, fügen Sie einfach eine Abfrage hinzu, die User
als Kontext hat. Der einfachste Weg ist die Verwendung der @GraphQLContext
-Annotation:
class UserService {
... //regular queries, as above
// Attach a new field called twitterProfile to the User GraphQL type
@ GraphQLQuery
public TwitterProfile twitterProfile ( @ GraphQLContext User user ) {
...
}
}
Aussetzen des Dienstes mit GraphQL-SPQR:
UserService userService = new UserService (); //instantiate the service (or inject by Spring or another framework)
GraphQLSchema schema = new GraphQLSchemaGenerator ()
. withBasePackages ( "io.leangen" ) //not mandatory but strongly recommended to set your "root" packages
. withOperationsFromSingleton ( userService ) //register the service
. generate (); //done ;)
GraphQL graphQL = new GraphQL . Builder ( schema )
. build ();
//keep the reference to GraphQL instance and execute queries against it.
//this operation selects a user by ID and requests name, regDate and twitterProfile fields only
ExecutionResult result = graphQL . execute (
"{ user (id: 123) {
name,
regDate,
twitterProfile {
handle
numberOfTweets
}
}}" );
Wir arbeiten an einem von SPQR betriebenen Spring-Boot-Starter. Das Projekt ist immer noch sehr jung, aber bereits funktional.
Weitere vollständige Beispiele finden Sie mit Spring Start unter https://github.com/leangen/graphql-Samples
Bald kommen
Für die beste Kompatibilität wird Kotlin 1.3.70 oder höher mit dem Compiler-Argument- -Xemit-jvm-type-annotations
benötigt. Dadurch wird der Kotlin-Compiler angewiesen, Anmerkungen zu Typenverwendungen (in JDK8 eingeführt) richtig zu erstellen. Weitere Informationen finden Sie unter KT-35843 und KT-13228.
In OpenJDKs Annotation -Parser vor Version 16 B17 gibt es einen Fehler, der Anmerkungen zu generischen Typparametern dupliziert. Sie können dies in einer Form eines mysteriösen erleben
AnnotationFormatError: Duplicate annotation for class: interface io.leangen.graphql.annotations.GraphQLNonNull
Wenn Sie @GraphQLNonNull
verwendet werden, sowohl auf einem Typ als auch auf den generischen Parametern EG @GraphQLNonNull List<@GraphQLNonNull Item>
.
Glücklicherweise scheinen nur sehr wenige Benutzer dieses Problem zu haben, selbst bei betroffenen JDKs. Beachten Sie, dass es nur relevant ist, welche Java die Quellen kompiliert , nicht welche Java den Code ausführt . Beachten Sie auch, dass die Intellij -Idee mit einem eigenen JDK gebündelt ist, sodass das Aufbau des Projekts in Idee zu diesem Fehler führen kann. Sie sollten Ihre IDE so konfigurieren, dass sie das System Java verwenden, wenn es anders ist.