AbubkarSiddiq
AbubkarSiddiq

Reputation: 1

Json to object deserialization issue in Graphql-spqr

Json to GraphQLArgumetn object conversion failing in graphql-spqr.

tried adding GraphQLInterface(with autodiscovery true and scanpackage) to above abstract classes and GraphQLtype type all concrete classes.

My graph query:

query contactsQuery($searchQuery : QueryInput) { contacts(searchQuery:$searchQuery){id}}
variables:{"searchQuery":{"bool":{"conditions":[{"must":{"matches":[{"singleFieldMatch":{"boost":null,"field":"firstname","value":"siddiq"}}],"bool":null}}]}})

Java code:

@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({@type(value = Must.class, name="must"),@type(value = MustNot.class, name="mustNot")})
public abstract class Condition
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME,include=JsonTypeInfo.As.WRAPPER_OBJECT)
@JsonSubTypes({@type(value = SingleFieldMatch.class, name="singleFieldMatch"),@type(value = MultiFieldMatch.class, name="multiFieldMatch")})
public abstract class Match
@GraphQLQuery(name = "contacts")
public List getContacts(@GraphQLArgument(name ="searchQuery") Query query)

Still it's throwing error unknown field error etc. Not sure which configuration is missing. Building GraphQLSchema with AnnotatedResolvedBuilder, base package configured JacksonValueMappperFactory and singleton services.

Upvotes: 0

Views: 1140

Answers (1)

John Duskin
John Duskin

Reputation: 357

Hi this may be a similar issue to what I ended up having.

Initially I had the following

@JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type")
@GraphQLInterface(name = "AbstractClass", implementationAutoDiscovery = true)
public abstract class AbstractClass{

with the following query called

addNewObject(object: {name: "soft2", id: "asdas"})

To get conversion functioning what I needed to do was the following change

@JsonTypeInfo(use = Id.NAME, include = As.EXISTING_PROPERTY, property = "type")
@GraphQLInterface(name = "AbstractClass", implementationAutoDiscovery = true)
public abstract class AbstractClass{
private String type = this.getClass().getSimpleName();

/**
     * @return the type
     */
    @GraphQLQuery(name = "type", description = "The concrete type of the node. This should match the initialised class. E.g. \"Concrete\", \"DecafCoffee\"")
    public String getType() {
        return type;
    }

with the query now being

addNewConcreteObject(concrete: {name: "soft2", id: "asdas", type: "Concrete"})

Why this worked (I think): When converting from JSON to objects in my code using the Jackson converter (ObjectMapper). I had previously noticed that the JSON required knowledge of what class to convert to. Thus the initial use of @JsonTypeInfo(use = Id.NAME, include = As.PROPERTY, property = "type") put a type property in the JSON when it was written to string.

The inclusion of the @JSON tag may be picked up by SPQR and it then seems to use a Jackson converter to try to convert your query to the required object. If I am right, here is the issue. As the query doesn't contain type the query can not be correctly converted. Moreover as the type property was not a member variable of the object but was instead only added by the ObjectMapper, SPQR didn't pick it up and so it wasn't part of the schema for the object. Thus to get around it, I added type as a member variable which is always equal to the actual class, then changed my JsonTypeInfo to look for an existing property.

I appreciate this isn't a direct answer to your question (and definitely isn't a pretty answer), but hopefully it will help you find your solution.

Upvotes: 1

Related Questions