2

I have problem searching with using Input data in graphql:

@RestController
@RequestMapping("/api/dictionary/")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class DictionaryController {
    @Value("classpath:items.graphqls")
    private Resource schemaResource;
    private GraphQL graphQL;
    private final DictionaryService dictionaryService;

    @PostConstruct
    public void loadSchema() throws IOException {
        File schemaFile = schemaResource.getFile();
        TypeDefinitionRegistry registry = new SchemaParser().parse(schemaFile);
        RuntimeWiring wiring = buildWiring();
        GraphQLSchema schema = new SchemaGenerator().makeExecutableSchema(registry, wiring);
        graphQL = GraphQL.newGraphQL(schema).build();
    }

private RuntimeWiring buildWiring() {

            DataFetcher<String> fetcher9 = dataFetchingEnvironment ->
            getByInput((dataFetchingEnvironment.getArgument("example")));

        return RuntimeWiring.newRuntimeWiring()
                .type("Query", typeWriting ->
                   typeWriting
                    .dataFetcher("getByInput", fetcher9)
                    )
                .build();
    }


public String getByInput(Character character) {
    return "testCharacter";
}
  }

items.graphqls file content:

type Query {
   getByInput(example: Character): String
}

input Character {
    name: String
}

When asking for resource like that:

query {
    getByInput (example: {name: "aa"} )
}

Character DTO:

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Character {
    protected String name;
}

I've got an error:

"Exception while fetching data (/getByInput) : java.util.LinkedHashMap cannot be cast to pl.graphql.Character",

How should the query look like?

Edit

If i change to:

public String getByInput(Object character) 

The codes runs fine - but i want convert to work.

tryingHard
  • 1,794
  • 4
  • 35
  • 74

1 Answers1

4

For the input argument which the type is the input type , graphql-java will convert it to a Map.

In your case the query is getByInput (example: {name: "aa"} ) which the example argument is the input type . So ,

dataFetchingEnvironment.get("example");

will return a Map with the structure (key="name" , value="aa") .Then you try to cast the map to Character which definitely gives you an error since they are totally different types.

To convert a Map to a Character , graphql-java will not help you for such conversion. You have to implement the conversion codes by yourselves or use other libraries such as Jackson , Gson , Dozer or whatever libraries you like for converting a map to your domain object (i.e. Character).

Ken Chan
  • 84,777
  • 26
  • 143
  • 172
  • Then what for are `input` types in `grapql` good for? Maybe i don't understand it correctly. But dealing with custom transaltion from `object` / `map` is to much work in my opinion. Usually do you use it in some other way ? I reallt can not understand - why i am making `Character` type and `grapql` won't search for this `class` in my code to make it match and cast etc. It's kinda working silly right now. – tryingHard Jan 19 '19 at 20:15
  • 1
    here is why input type good for: https://stackoverflow.com/questions/41743253/whats-the-point-of-input-type-in-graphql . If you think it is too much work to do for translating a map to your domain object , that 's why you need to a library to help you. I personally use Jackson for such conversion. – Ken Chan Jan 19 '19 at 20:20
  • 1
    Yes . that 's why someone come up the another framework on top of `graphql-java` such as this https://github.com/leangen/graphql-spqr to reduce the boilerplate codes that you are concerned with, but I personally did not tried it yet. – Ken Chan Jan 19 '19 at 20:26
  • github issue that talks about this https://github.com/graphql-java/graphql-java/issues/777 – googleman2200 Apr 10 '19 at 02:18