Closed GaneshBChandgude closed 11 months ago
You're talking about input polymorphism, which has a few RFCs out, let alone implemented support. https://github.com/graphql/graphql-spec/issues/627
While @baohouse is correct in the sense that GraphQL spec itself does not (yet) allow polymorphic input types, SPQR does (for the most part). You can enable this with generator.withAbstractInputTypeResolution()
and SPQR will automatically add a discriminator input field called _type
(by default, classType
in your case) where needed. But. In your case, there is no field on type Schema
that could possibly be deserialized in any of its concrete subtypes. How would Schema
input value look like? There isn't a single valid value that could be provided.
If Schema
instead looked something like this, for example:
@GraphQLInterface(name = "Schema", implementationAutoDiscovery = true)
public interface Schema {
String getClassType();
Schema copy();
List<Attribute> getAttributes(); //This is deserializable in DatasetSchema, because there is a matching writable property called `attributes` (assuming Attribute is a valid input)
}
then with .withAbstractInputTypeResolution()
, SchemaInput
would get mapped as:
input SchemaInput {
attributes: [AttributeInput]
}
This is now a valid input type, and you could provide a value to a mutation as expected:
mutation CreateDataset {
createDataset(dataset: {schema: {attributes: [...]}}) {
schema {
attributes {
...
}
}
}
}
Notice how the _type
field wasn't even present. This is because only a single concrete subtype of Schema
exists, so no disambiguation was needed.
@kaqqao following upon this, I have a very similar issue. You mentioned that the discriminator _type
field is not required in case there is only a single implementation. But this is not working in my case below:
These are my classes, all in the same package:
Merge.java
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubType({
@Type(value = MergeImpl1.class, name = "impl1")
})
@GraphQLInterface(name = "Merge", implementationAutoDiscovery = true)
public abstract class Merge {
private String type;
// getter and setter for "type"
}
MergeImpl1.java
public class MergeImpl1 extends Merge {
private String request;
public MergeImpl1() {
setType("impl1");
}
// getter and setter for "request"
}
In the above classes, type
field exists only to distinguish between the implementations.
The schema is now the following:
input MergeInput {
type: String
}
Now I want to query on its implementation MergeImpl1:
query queries {
myQuery(merge: {type: "impl1", request: "..."}) {
id
__typename
}
}
On doing this, I get the following error:
The variables input contains a field name 'request' that is not defined for input object type 'MergeInput'
For this, why doesn't type: "impl1" work? Should I be using _type
instead of type
in the query variable? In any case, since there is only a single implementation, specifying type should not be required.
I might have misunderstood or might be missing something. Could you please help me in this?
I am not sure this is issue or not. Might be my understanding/expectation is wrong. Request you to please verify my use case and error that I am facing.
Error Message:
Java types with SPQR-Annotations the following manner:
I am getting above error on GraphQLSchemaGenerator.generate API
FYI...Above java types and SPQR annotations are working fine for output type. Working output type code snippet and query
Query: