GraphQL SPQR (editor de esquema GraphQL e resolvedor de consultas, pronunciado como o alto-falante ) é uma biblioteca simples de usar para o desenvolvimento rápido de APIs grafql em Java.
O GraphQL SPQR visa simplificar a adição de uma API do GraphQL a qualquer projeto Java. Funciona gerando dinamicamente um esquema GraphQL a partir do código Java.
Ao desenvolver aplicativos habilitados para GraphQL, é comum definir o esquema primeiro e conectar a lógica de negócios posteriormente. Isso é conhecido como o estilo esquema. Embora tenha suas vantagens, em idiomas digitados fortes e estaticamente, como o Java, leva a muita duplicação.
Por exemplo, uma definição de esquema de um tipo de grafql simples pode ser assim:
type Link {
id : ID !
url : String !
description : String
}
E, geralmente, um tipo Java correspondente existiria no sistema, semelhante ao seguinte:
public class Link {
private final String id ;
private final String url ;
private final String description ;
//constructors, getters and setters
//...
}
Ambos os blocos contêm exatamente as mesmas informações. Pior ainda, mudar um requer uma mudança imediata para a outra. Isso torna a refatoração arriscada e pesada, e o compilador não pode ajudar. Por outro lado, se você está tentando introduzir uma API do GraphQL em um projeto existente, escrever o esquema significa praticamente re-descrever todo o modelo existente. Isso é caro e propenso a erros, e ainda sofre de duplicação e falta de ferramentas.
Em vez disso, o GraphQL SPQR adota a abordagem de código-primeiro, gerando o esquema a partir do modelo existente. Isso mantém o esquema e o modelo em sincronia, facilitando a refatoração. Ele também funciona bem em projetos em que o GraphQL é introduzido no topo de uma base de código existente.
Observe que o desenvolvimento do estilo Code-primeiro ainda é efetivamente o esquema, a diferença é que você desenvolve seu esquema ainda em outro idioma, mas em Java, com o seu IDE, o compilador e todas as suas ferramentas ajudando você. Breaking mudanças no esquema significa que a compilação falhará. Não há necessidade de linters ou outros hacks frágeis.
GraphQL SPQR é implantado no Maven Central.
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 '
O exemplo usará as anotações fornecidas pelo próprio GraphQL SPQR, mas elas são opcionais e o mapeamento é completamente configurável, permitindo que os serviços existentes sejam expostos através do GraphQL sem modificação.
Classe de serviço:
class UserService {
@ GraphQLQuery ( name = "user" )
public User getById ( @ GraphQLArgument ( name = "id" ) Integer id ) {
...
}
}
Se você deseja pular a adição de @GraphQLArgument
, compilar com a opção -parameters
ou os nomes serão perdidos.
Classe de domínio:
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 anexar campos adicionais ao tipo de grafql User
, sem modificar a classe User
, basta adicionar uma consulta que tenha User
como contexto . A maneira mais simples é usar a anotação @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 ) {
...
}
}
Expondo o serviço com grafql-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 trabalhando em um acionador de inicialização do SPQR SPQR. O projeto ainda é muito jovem, mas já funcional.
Veja exemplos mais completos usando a inicialização da primavera em https://github.com/leangen/graphql spqr-samples
Em breve
Para melhor compatibilidade, é necessário o Kotlin 1.3.70 ou posterior com o argumento do compilador -Xemit-jvm-type-annotations
. Isso instrui o compilador Kotlin a produzir anotações de uso do tipo (introduzido no JDK8) corretamente. Consulte KT-35843 e KT-13228 para obter detalhes.
Há um bug no analisador de anotação do OpenJDK antes da versão 16 B17 que faz com que as anotações nos parâmetros do tipo genérico sejam duplicados. Você pode experimentar isso na forma de um misterioso
AnnotationFormatError: Duplicate annotation for class: interface io.leangen.graphql.annotations.GraphQLNonNull
sendo jogado ao usar @GraphQLNonNull
tanto em um tipo quanto em seus parâmetros genéricos, por exemplo, @GraphQLNonNull List<@GraphQLNonNull Item>
.
Felizmente, muito poucos usuários parecem ter esse problema, mesmo nos JDKs afetados. Observe que é relevante que o Java compila as fontes, não o que Java executa o código. Observe também que o Intellij Idea vem com um JDK próprio, portanto, construir o projeto em Idea pode levar a esse erro. Você deve configurar seu IDE para usar o sistema Java se for diferente.