Graphql没有为接口/联合定义解析器 - Java

6

我在使用这种方法向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 文件内容:

type Query {
    getClaimSubType: [DictionaryItemWithParentDto]
}

type DictionaryItemWithParentDto {
    code: String!
    name: String
    parents: [DictionaryItemDto]
}

type DictionaryItemDto {
    code: String!
    name: String
    description: String
}

在Java中,我有一个Vehicle接口和两个实现它的类:AirplaneCar。当我添加这行到模式中:

union SearchResult = Airplane | Car

我遇到了以下错误:

There is no type resolver defined for interface / union 'Vehicle' type, There is no type resolver defined for interface / union 'SearchResult' type]}

我不确定如何处理它。

如果我添加以下内容:

interface Vehicle {
    maxSpeed: Int
}

type Airplane implements Vehicle {
    maxSpeed: Int
    wingspan: Int
}

type Car implements Vehicle {
    maxSpeed: Int
    licensePlate: String
}

我收到以下错误信息:

我收到以下错误信息:

errors=[There is no type resolver defined for interface / union 'Vehicle' type]

我该如何使用我的方法处理这些错误?还有其他方法可以处理吗?

编辑

添加这些代码行部分地解决了问题:

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");
        }
    }
};

并且在 RuntimeWiring 构建器中添加以下内容:

            .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);
    }

当需要请求:

query {
    getVehicle(maxSpeed: 30) {
        maxSpeed

    }
}

我可以获取maxSpeed,但是当我添加wingspan时,会出现错误。

Field 'wingspan' in type 'Vehicle' is undefined @ 'getVehicle/wingspan'",

我添加了。
getVehicle(maxSpeed: Int): Vehicle

针对graphqls文件,我认为这里可以使用多态。

1个回答

11

添加以下代码行可解决此问题:

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");
        }
    }
};

同时在 RuntimeWiring 构建器中添加以下内容:

            .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);
    }

当要求时:

query {
    getVehicle(maxSpeed: 30) {
        maxSpeed

    }
}

我可以获取 maxSpeed,但当我添加 wingspan 时出现错误。

Field 'wingspan' in type 'Vehicle' is undefined @ 'getVehicle/wingspan'",

我已经添加了。
getVehicle(maxSpeed: Int): Vehicle

针对graphqls文件,我认为这里可以使用多态性。

如果我想要子类的字段,可以像这样请求它们:

query {
    getVehicle(maxSpeed: 10) {
        maxSpeed
        ... on Airplane {
        wingspan
      }
        ... on Car {
        licensePlate
      }
    }
}

1
你是如何编译这行代码的? if (javaObject instanceof Car) {CAR类是如何生成的? - c.sankhala
这是一个普通的Java类 - 手工制作 - tryingHard
有没有一种通用的方法可以在不创建Car类的情况下完成它? - stark
1
@stark,我已经检查了javaObject instanceof Map && ((Map)javaObject).get("__typename"),并将类型名称直接放入映射值中。你可以根据自己的需要确定GraphQL类型名称,只要给定一个值,它不必基于具体类(虽然这是一种非常符合Java习惯的选项)。 - Ben Mosher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接