americanexpress / nodes

A GraphQL JVM Client - Java, Kotlin, Scala, etc.
Apache License 2.0
307 stars 70 forks source link

Null Pointer When Adding Arguments #32

Closed seanjrng closed 6 years ago

seanjrng commented 6 years ago

Context:

I'm trying to create a small demo project using this project to see if this fits our needs. It is nothing fancy just a bare bones app. The app just assembles the request object and prints it to the console.

Issue:

When trying to assemble add the arguments to the builder using the "GraphQLRequestEntity.Builder.arguments()" method I get a null pointer exception. The stack trace looks like this:

 java.lang.NullPointerException
        at io.aexp.nodes.graphql.GraphQLRequestEntity.setArguments(GraphQLRequestEntity.java:119)
        at io.aexp.nodes.graphql.GraphQLRequestEntity.<init>(GraphQLRequestEntity.java:62)
        at io.aexp.nodes.graphql.GraphQLRequestEntity$RequestBuilder.build(GraphQLRequestEntity.java:379)
        at App.main(App.java:36) 

I have included what I think are the correct annotations on the class I'm trying to query for. Below is the main method for my "app" and the first few lines of the model I'm using. Is there something I'm doing wrong? Thanks in advance.

Code

Main class

`public class App { public String getGreeting() { return "Hello world."; }

public static void main(String[] args) {
    try{
    System.out.println(new App().getGreeting());
    GraphQLTemplate template = new GraphQLTemplate();
    Argument<Fudge> ag= new Argument("thing", "d070633a9f9"); //<---- this throws a warning aobut argumant being a generic an i need to do a checked cast but it gets mad when I do that
    Arguments arguments= new Arguments("thing1.thing2.Fudge",ag);
    GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder()
    .url("http://graphql.example.com/graphql")
    .arguments(arguments)//<---- this seems to be what fails. If i comment it out It works but I have no arguments
    .request(Fudge.class)
    .build();
System.out.println(requestEntity.getRequest());
System.out.println("no errors, this time");
}
    catch(Exception ex){ex.printStackTrace();
    }
}

}`

Model

@GraphQLProperty(name="fudge" 
    , arguments={
        @GraphQLArgument(name="id", type="String")
        ,@GraphQLArgument(name="thing", type="String")
        ,@GraphQLArgument(name="bar", type="String") 
        }
    )
public class Fudge {

    String id;
    String subjectLine;
    String body;
}
// everything below here is just getters and setters
chemdrew commented 6 years ago

Hi @seanjrng,

I think you'll be able to fix your request to match the behavior you expect with this in your main class:

Argument<String> idArg = new Argument("id", "whatever");
Argument<String> thingArg= new Argument("thing", "d070633a9f9");
Argument<Integer> barArg = new Argument("bar", "whatever");

Arguments arguments = new Arguments("fudge", idArg, thingArg, barArg);

GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder()
    ...
    .arguments(arguments)
    ...

let me know if this solves the issue you are facing!

seanjrng commented 6 years ago

I'm afraid it does not. I did as suggested but to no avail. I've also tried messing around with the dotPath, changing how I create the individual arguments, and passing the arguments as a list rather than an array but I cannot get .arguments() to work. It still throws a null pointer exception at GraphQLRequestEntity Ln 119. Which looks like: ``` Property argProp = property; // ln 116 String[] path = dotPath.split("\."); for (String key: path) { argProp = argProp.getChildren().get(key); // stack trace says it fails here }

chemdrew commented 6 years ago

Fudge.java

import io.aexp.nodes.graphql.annotations.GraphQLArgument;
import io.aexp.nodes.graphql.annotations.GraphQLProperty;

@GraphQLProperty(name="fudge", arguments={
        @GraphQLArgument(name="id", type="String"),
        @GraphQLArgument(name="thing", type="String"),
        @GraphQLArgument(name="bar", type="String")
    }
)
public class Fudge {

    String id;
    String subjectLine;
    String body;

    ... getters + setters ...
}

test file

    @Test
    public void testIssue32() throws MalformedURLException {
        Argument<String> idArg = new Argument("id", "whatever");
        Argument<String> thingArg= new Argument("thing", "d070633a9f9");
        Argument<String> barArg = new Argument("bar", "whatever");

        Arguments arguments = new Arguments("fudge", idArg, thingArg, barArg);

        GraphQLRequestEntity requestEntity = GraphQLRequestEntity.Builder()
                .url("http://graphql.example.com/graphql")
                .arguments(arguments)//<---- this seems to be what fails. If i comment it out It works but I have no arguments
                .request(Fudge.class)
                .build();
        System.out.println(requestEntity.getRequest());
        System.out.println("no errors, this time");
    }

output

query { fudge (id:"whatever",thing:"d070633a9f9",bar:"whatever") { subjectLine id body } } 
no errors, this time
seanjrng commented 6 years ago

I figured it out. Thanks