GraphQL SPQR (GraphQL Schema Publisher & Query Resolver, prononcé comme le haut-parleur ) est une bibliothèque simple à utiliser pour le développement rapide des API GraphQL en Java.
GraphQL SPQR vise à rendre Dead Simple d'ajouter une API GraphQL à n'importe quel projet Java. Il fonctionne en générant dynamiquement un schéma GraphQL à partir du code Java.
Lors du développement d'applications compatibles GraphQL, il est courant de définir d'abord le schéma et de brancher la logique métier plus tard. Ceci est connu comme le style de schéma. Bien qu'il ait ses avantages, dans des langues fortement et statiques, comme Java, il conduit à beaucoup de duplication.
Par exemple, une définition de schéma d'un type GraphQL simple pourrait aimer ceci:
type Link {
id : ID !
url : String !
description : String
}
et, généralement, un type Java correspondant existerait dans le système, similaire à ce qui suit:
public class Link {
private final String id ;
private final String url ;
private final String description ;
//constructors, getters and setters
//...
}
Ces deux blocs contiennent exactement les mêmes informations. Pire encore, le changement un nécessite un changement immédiat vers l'autre. Cela rend le refactoring risqué et lourd, et le compilateur ne peut pas aider. D'un autre côté, si vous essayez d'introduire une API GraphQL dans un projet existant, écrire le schéma signifie pratiquement redécrire l'ensemble du modèle existant. Ceci est à la fois coûteux et sujet aux erreurs, et souffre toujours de duplication et de manque d'outillage.
Au lieu de cela, GraphQL SPQR adopte l'approche First Code, en générant le schéma à partir du modèle existant. Cela maintient le schéma et le modèle en synchronisation, ce qui assouplit la refactorisation. Il fonctionne également bien dans les projets où GraphQL est introduit en plus d'une base de code existante.
Notez que le développement dans le style de code d'abord est toujours en tant que schéma, la différence est que vous développez votre schéma non pas dans une autre langue, mais en Java, avec votre IDE, le compilateur et tous vos outils qui vous aident. Les modifications de rupture du schéma signifient que la compilation échouera. Pas besoin de liners ou d'autres hacks fragiles.
GraphQL SPQR est déployé sur Maven Central.
Maven
< dependency >
< groupId >io.leangen.graphql</ groupId >
< artifactId >spqr</ artifactId >
< version >0.12.3</ version >
</ dependency >
Grade
compile ' io.leangen.graphql:spqr:0.12.3 '
L'exemple utilisera les annotations fournies par GraphQL SPQR elle-même, mais celles-ci sont facultatives et le mappage est complètement configurable, permettant aux services existants d'être exposés via GraphQL sans modification.
Classe de service:
class UserService {
@ GraphQLQuery ( name = "user" )
public User getById ( @ GraphQLArgument ( name = "id" ) Integer id ) {
...
}
}
Si vous souhaitez ignorer l'ajout @GraphQLArgument
, compilez avec l'option -parameters
ou les noms seront perdus.
Classe de domaine:
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 ;
}
}
Pour attacher des champs supplémentaires au type GraphQL User
, sans modifier la classe User
, vous ajoutez simplement une requête qui a User
comme contexte . La manière la plus simple consiste à utiliser l'annotation @GraphQLContext
:
class UserService {
... //regular queries, as above
// Attach a new field called twitterProfile to the User GraphQL type
@ GraphQLQuery
public TwitterProfile twitterProfile ( @ GraphQLContext User user ) {
...
}
}
Exposer le service avec 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
}
}}" );
Nous travaillons sur un démarreur Spring Boot propulsé par SPQR. Le projet est encore très jeune, mais déjà fonctionnel.
Voir des exemples plus complets en utilisant Spring Boot sur https://github.com/leangen/graphql-spqr
À venir
Pour une meilleure compatibilité, Kotlin 1.3.70 ou ultérieure est nécessaire avec l'argument du compilateur -Xemit-jvm-type-annotations
. Cela demande au compilateur Kotlin de produire correctement les annotations d'utilisation de type (introduites dans JDK8). Voir KT-35843 et KT-13228 pour plus de détails.
Il y a un bogue dans l'annotation de l'annotation d'OpenJDK avant la version 16 B17 qui provoque duplication des annotations sur les paramètres de type générique. Vous pouvez en faire l'expérience sous une forme de mystérieuse
AnnotationFormatError: Duplicate annotation for class: interface io.leangen.graphql.annotations.GraphQLNonNull
Être lancé lors de l'utilisation @GraphQLNonNull
à la fois sur un type et sur ses paramètres génériques, par exemple @GraphQLNonNull List<@GraphQLNonNull Item>
.
Heureusement, très peu d'utilisateurs semblent rencontrer ce problème, même sur les JDK affectés. Notez qu'il est pertinent que Java compile les sources, pas ce que Java exécute le code. Notez également que Intellij Idea est livré avec un JDK à part, donc construire le projet dans l'idée peut conduire à cette erreur. Vous devez configurer votre IDE pour utiliser le système Java s'il est différent.