GraphQL Spqr (GraphQL Schema Publisher & Query Resolucion, pronunciado como altavoz ) es una biblioteca de uso fácil para el desarrollo rápido de las API GraphQL en Java.
Graphql Spqr tiene como objetivo hacer que sea simple agregar una API GraphQL a cualquier proyecto Java. Funciona generando dinámicamente un esquema GraphQL a partir del código Java.
Al desarrollar aplicaciones habilitadas para GraphQL, es común definir primero el esquema y conectar la lógica comercial más adelante. Esto se conoce como el estilo de esquema primero. Si bien tiene sus ventajas, en idiomas de escrito fuertemente y estáticamente, como Java, conduce a mucha duplicación.
Por ejemplo, una definición de esquema de un tipo de GraphQL simple podría gustarle esto:
type Link {
id : ID !
url : String !
description : String
}
y, comúnmente, existiría un tipo Java correspondiente en el sistema, similar al siguiente:
public class Link {
private final String id ;
private final String url ;
private final String description ;
//constructors, getters and setters
//...
}
Ambos bloques contienen exactamente la misma información. Peor aún, cambiar uno requiere un cambio inmediato al otro. Esto hace que la refactorización sea arriesgada y engorrosa, y el compilador no puede ayudar. Por otro lado, si está tratando de introducir una API GraphQL en un proyecto existente, escribir el esquema prácticamente significa redescribir todo el modelo existente. Esto es costoso y propenso a errores, y todavía sufre de duplicación y falta de herramientas.
En su lugar, GraphQL SPQR adopta el enfoque de código primero, generando el esquema del modelo existente. Esto mantiene el esquema y el modelo sincronizado, aliviando la refactorización. También funciona bien en proyectos donde GraphQL se introduce además de una base de código existente.
Tenga en cuenta que desarrollar en el estilo de código primero sigue siendo efectivamente el esquema primero, la diferencia es que desarrolla su esquema no en otro idioma más, sino en Java, con su IDE, el compilador y todas sus herramientas lo ayudan. Los cambios de ruptura en el esquema significan que la compilación fallará. No hay necesidad de linters u otros hacks frágiles.
GraphQL SPQR se implementa en Maven Central.
Aturdir
< dependency >
< groupId >io.leangen.graphql</ groupId >
< artifactId >spqr</ artifactId >
< version >0.12.3</ version >
</ dependency >
Graduarse
compile ' io.leangen.graphql:spqr:0.12.3 '
El ejemplo utilizará anotaciones proporcionadas por GraphQL Spqr, pero estas son opcionales y la asignación es completamente configurable, lo que permite que los servicios existentes se expusen a través de GraphQL sin modificación.
Clase de servicio:
class UserService {
@ GraphQLQuery ( name = "user" )
public User getById ( @ GraphQLArgument ( name = "id" ) Integer id ) {
...
}
}
Si desea omitir agregar @GraphQLArgument
, compile con la opción -parameters
o los nombres se perderán.
Clase de dominio:
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 ;
}
}
Para adjuntar campos adicionales al tipo User
GraphQL, sin modificar la clase User
, simplemente agregue una consulta que tenga User
como contexto . La forma más simple es usar la anotación @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 ) {
...
}
}
Exponer el servicio con 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
}
}}" );
Estamos trabajando en un iniciador de arranque de primavera con SPQR. El proyecto sigue siendo muy joven, pero ya funcional.
Vea más ejemplos completos usando el arranque de primavera en https://github.com/leangen/graphql-spqr-samples
Muy pronto
Para la mejor compatibilidad, se necesita Kotlin 1.3.70 o posterior con el argumento del compilador -Xemit-jvm-type-annotations
. Esto instruye al compilador Kotlin que produzca anotaciones de uso de tipo (introducido en JDK8) correctamente. Ver KT-35843 y KT-13228 para más detalles.
Hay un error en el analizador de anotaciones de OpenJDK antes de la versión 16 B17 que hace que las anotaciones en los parámetros de tipo genérico se dupliquen. Puedes experimentar esto en forma de misterioso
AnnotationFormatError: Duplicate annotation for class: interface io.leangen.graphql.annotations.GraphQLNonNull
siendo arrojado cuando se usa @GraphQLNonNull
tanto en un tipo como en sus parámetros genéricos, por ejemplo, @GraphQLNonNull List<@GraphQLNonNull Item>
.
Afortunadamente, muy pocos usuarios parecen experimentar este problema, incluso en los JDK afectados. Tenga en cuenta que solo es relevante qué Java compila las fuentes, no qué Java ejecuta el código. También tenga en cuenta que la idea de IntelliJ viene incluida con un JDK propio, por lo que construir el proyecto en idea puede conducir a este error. Debe configurar su IDE para usar el sistema Java si es diferente.