I have problem adding resolver using this approach 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<List<DictionaryItemWithParentDto>> fetcher6 = dataFetchingEnvironment -> dictionaryService.getClaimSubType();
return RuntimeWiring.newRuntimeWiring()
.type("Query", typeWriting ->
typeWriting
.dataFetcher("getClaimSubType", fetcher6)
)
.build();
}
public List<DictionaryItemWithParentDto> getClaimSubType() {
return dictionaryService.getClaimSubType();
}
}
items.graphqls
file content:
type Query {
getClaimSubType: [DictionaryItemWithParentDto]
}
type DictionaryItemWithParentDto {
code: String!
name: String
parents: [DictionaryItemDto]
}
type DictionaryItemDto {
code: String!
name: String
description: String
}
In java I have Vehicle
interface and two classes that implement it: Airplane
and Car
. When i add to schema this line:
union SearchResult = Airplane | Car
I get following error:
There is no type resolver defined for interface / union 'Vehicle' type, There is no type resolver defined for interface / union 'SearchResult' type]}
I am not sure how to handle it.
If instead i add:
interface Vehicle {
maxSpeed: Int
}
type Airplane implements Vehicle {
maxSpeed: Int
wingspan: Int
}
type Car implements Vehicle {
maxSpeed: Int
licensePlate: String
}
I get following error:
errors=[There is no type resolver defined for interface / union 'Vehicle' type]
How can i handle these errors using my approach ? Is there another approach to handle it?
Edit
Adding these lines of code fix the issue partway i guess:
TypeResolver t = new TypeResolver() {
@Override
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
Object javaObject = env.getObject();
if (javaObject instanceof Car) {
return env.getSchema().getObjectType("Car");
} else if (javaObject instanceof Airplane) {
return env.getSchema().getObjectType("Airplane");
} else {
return env.getSchema().getObjectType("Car");
}
}
};
And adding to RuntimeWiring
builder this:
.type("Vehicle", typeWriting ->
typeWriting
.typeResolver(t)
)
@PostMapping("getVehicle")
public ResponseEntity<Object> getVehicleMaxSpeed(@RequestBody String query)
{
ExecutionResult result = graphQL.execute(query);
return new ResponseEntity<Object>(result, HttpStatus.OK);
}
When asking for:
query {
getVehicle(maxSpeed: 30) {
maxSpeed
}
}
I get the maxSpeed
but when i add wingspan
i get an error
Field 'wingspan' in type 'Vehicle' is undefined @ 'getVehicle/wingspan'",
I added
getVehicle(maxSpeed: Int): Vehicle
To the graphqls
file. I thought that polymorphism would work here.
Only types can implement an interface. An interface cannot implement another interface. You can see the syntax for interfaces defined here, which distinctly lacks the ImplementsInterfaces definition shown here.
A resolver is a function that's responsible for populating the data for a single field in your schema. It can populate that data in any way you define, such as by fetching data from a back-end database or a third-party API.
The __typename field returns the object type's name as a String (e.g., Book or Author ). GraphQL clients use an object's __typename for many purposes, such as to determine which type was returned by a field that can return multiple types (i.e., a union or interface).
Adding these lines of code fix the issue:
TypeResolver t = new TypeResolver() {
@Override
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
Object javaObject = env.getObject();
if (javaObject instanceof Car) {
return env.getSchema().getObjectType("Car");
} else if (javaObject instanceof Airplane) {
return env.getSchema().getObjectType("Airplane");
} else {
return env.getSchema().getObjectType("Car");
}
}
};
And adding to RuntimeWiring
builder this:
.type("Vehicle", typeWriting ->
typeWriting
.typeResolver(t)
)
@PostMapping("getVehicle")
public ResponseEntity<Object> getVehicleMaxSpeed(@RequestBody String query)
{
ExecutionResult result = graphQL.execute(query);
return new ResponseEntity<Object>(result, HttpStatus.OK);
}
When asking for:
query {
getVehicle(maxSpeed: 30) {
maxSpeed
}
}
I get the maxSpeed
but when i add wingspan
i get an error
Field 'wingspan' in type 'Vehicle' is undefined @ 'getVehicle/wingspan'",
I added
getVehicle(maxSpeed: Int): Vehicle
To the graphqls
file. I thought that polymorphism would work here.
If i want fields from subclasses i can ask for them like that:
query {
getVehicle(maxSpeed: 10) {
maxSpeed
... on Airplane {
wingspan
}
... on Car {
licensePlate
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With