Comments (8)
This is a fairly involved setup, so I'll have to analyze this in more depth, but at the first glance it seems auto discovery would work for you.
Just add implementationAutoDiscovery = true
to your @GraphQLInterface
, i.e. make it @GraphQLInterface(name = "IAnimal", implementationAutoDiscovery = true)
. This is enough if the implementations are within the base package (test.graphql.model
). If they're not, you can also specify the packages to scan via scanPackages
property of @GraphQLInterface
.
Does this satisfy your needs or did I misunderstand you?
from graphql-spqr.
Ah. I've just tested your scenario. With implementationAutoDiscovery
it still fails but for a different reason: both BatImpl
and IBat
are discovered and it still doesn't know which one to choose. As a temporary work-around, you can explicitly set the scanPackages
and keep the interfaces and the impls in separate packages, because the GraphQLIgnore
annotation is not considered in this case.
I'll implement the support for GraphQLIgnore
in this context in 0.9.2
Another option is to enable implementationAutoDiscovery
but then implement your own TypeResolver
and provide it via @GraphQLTypeResolver(CustomTypeResolver.class)
on either IAnimal
or the impl classes.
from graphql-spqr.
Yet a third option would be to implement your own TypeMapper
(extending InterfaceMapper
) that will take care of the custom logic of detecting and mapping the correct implementations. This is where I'll add the code to skip the implementations annotated with @GraphQLIgnore
.
It was an important design goal to keep graphql-spqr insanely extensible and customizable, so if there's a feature you're missing, the chances are you can easily add it yourself.
from graphql-spqr.
Thanks for your effort! I tried out your second solution and it works. I kept Java-Implementations and Java-Interfaces in separate packages, enabled implementationAutoDiscovery
on the IAnimal
-GraphQL-Interface and additionally annotated it with @GraphQLTypeResolver(DummyTypeResolver.class)
(where DummyTypeResolver.resolveType
always returns null
) and created the schema as I did before.
Now the only thing that raises a question mark, is that the automatically created _type_
-field in the domain objects contains the actual Java-Type (e.g. BatImpl
instead of IBat
) and not the type defined in the GraphQL domain.
from graphql-spqr.
If you're keeping the interfaces and implementations in separate packages, you don't need the @GraphQLTypeResolver
.
And as for the _type_
property, it should always be the concrete type that can be instantiated.
It is only needed in case an interface or an abstract class is used as an input type, because it would be impossible to deserialize it from JSON without the knowledge of the concrete type. So it is basically a hint to the deserializer. The only reason _type_
exists in output types is to help the client know the possible value.
It is safe to use, as the possible values of _type_
are whitelisted at startup, so the client can't attempt to inject an arbitrary class name.
In short, if you're not using interfaces/abstract types as input types, you don't care about the _type_
field.
from graphql-spqr.
I have a problem similar to the one reported in this topic but I could not find a solution.
I have got Java types with SPQR-Annotations the following manner:
@GraphQLInterface(name = "IdentificationIf", implementationAutoDiscovery=true)
public interface IdentificationIf{
@GraphQLQuery(name = "identification")
public String getIdentification();
}
@GraphQLType(name = "IdentificationCPF")
public class IdentificationCPF implements IdentificationIf{
private String identification;
public IdentificationCPF(String identification){
this.identification = identification;
}
@GraphQLQuery(name = "identification")
public String getIdentification(){
return this.identification;
}
@GraphQLQuery(name = "type")
public String getType() {
return "CPF";
}
}
@GraphQLType(name = "IdentificationCNPJ")
public class IdentificationCNPJ implements IdentificationIf{
private String identification;
public IdentificationCNPJ(String identification){
this.identification = identification;
}
@GraphQLQuery(name = "identification")
public String getIdentification(){
return this.identification;
}
@GraphQLQuery(name = "branch")
public String getBranch() {
String branch = "";
if(identification != null) {
branch = identification.substring(7, 12);
}
return branch;
}
}
@Service
public class ServiceIdentification {
@GraphQLQuery(name = "person")
public Person getSolicitante() {
Person solic = new Person();
solic.setName("José");
solic.setIdentification(new IdentificationCPF("88888888888"));
return solic;
}
@GraphQLQuery(name = "identificacaoCPF")
public IdentificationIf getIdentificacaoCPF() {
return new IdentificationCPF("12345678912");
}
@GraphQLQuery(name = "identificacaoCNPJ")
public IdentificationIf getIdentificacaoCNPJ() {
return new IdentificationCNPJ("12345678912345");
}
}
When executing the query the error occurs:
{"query":"{person{name, ... on IdentificationCPF {identification, type}, ... on IdentificationCNPJ {identification, branch}}}"}
{errors=[{message=Validation error of type UnknownType: Unknown type IdentificationCPF, locations=[]}, {message=Validation error of type UnknownType: Unknown type IdentificationCNPJ, locations=[]}]}
I'd like to know how I should proceed to work with complex object queries that have interface type attribute.
Thanks in advance.
from graphql-spqr.
@pmbdias I don't see anything obviously wrong in your code... I'd suggest you place a breakpoint in e.g. GraphQLController
and analyze the generated schema. It seems as if the implementation types are not automatically discovered for whatever reason. Maybe even place a breakpoint in InterfaceTypeMapper
and what happens when it tries to scan for implementations.
from graphql-spqr.
The difference is that the IdentificationCPF object is a concrete class and in the initial example of the post the ICat object is an interface.
The example has two interface levels, but in my case I only have one interface.
I put the breakpoint in GraphQLController and in the generated schema for the example of "zoo" the GraphQLObjectType is generated for ICat, but in my example the GraphQLObjectType does not generate only the InterfaceType.
e.g schemes:
catteste=GraphQLFieldDefinition{name='catteste', type=GraphQLObjectType{name='ICat', description='', fieldDefinitionsByName=[_type_, name, smart], interfaces=[GraphQLInterfaceType{name='IAnimal', description='', fieldDefinitionsByName=[_type_, name], typeResolver=io.leangen.graphql.generator.DelegatingTypeResolver@3f594bf}]}, arguments=[], dataFetcherFactory=graphql.schema.DataFetcherFactories$$Lambda$19748/431014167@1758940c, description='', deprecationReason='null', definition=null}
identificationCPF=GraphQLFieldDefinition{name='identificationCPF', type=GraphQLInterfaceType{name='IdentificationIf', description='', fieldDefinitionsByName=[_type_, formattedID, identification], typeResolver=io.leangen.graphql.generator.DelegatingTypeResolver@3f594bf}, arguments=[], dataFetcherFactory=graphql.schema.DataFetcherFactories$$Lambda$19748/431014167@33f28f68, description='', deprecationReason='null', definition=null}
from graphql-spqr.
Related Issues (20)
- How to use executionResult data HOT 2
- Failing tests - ComplexityTest class
- Explicitly register Java classes to the GraphQL schema. HOT 4
- How to map a java class to GraphQL interface without using @GraphQLInterface annotation? HOT 5
- Best way to error handling HOT 1
- Help in Handling Exceptions with SPQR HOT 1
- Question: Extending an InputObject type and handle it in SPQR HOT 3
- SDL Printing Fails on Schema Directives with Arguments HOT 4
- Spring 3.2: Cannot resolve parameter names for constructor public io.leangen.graphql.spqr.spring.web.dto.GraphQLRequest(java.lang.String,java.lang.String,java.lang.String,java.util.Map) HOT 2
- Compile parameters to support Spring Boot 3.2.1 (Spring Framework 6.1) HOT 1
- null values sent in response json HOT 1
- Schema Generation Regression in 0.12.4 HOT 1
- Polymorphism type on input
- Scalars containing an Instant cannot be serialized over subscription
- Schema generation at compile time?
- BUG: The DelegatingTypeResolver breaks when updating the GraphQLSchema using a Visitor HOT 1
- Feature Request: Add support for GraphQLOutputType to the SchemaTransformer HOT 39
- Make a public OperationMapper#createResolver overload to help with creating custom field resolvers
- Mark the gson-java8-datatype dependency as optional HOT 3
- Kotlin boolean property setters are skipped if isX prefixed HOT 11
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from graphql-spqr.