Interface
跟许多类型系统一样,GraphQL 支持接口。一个接口是一个抽象类型,它包含某些字段,而对象类型必须包含这些字段,才能算实现了这个接口。
SDL方式
定义SDL
schema {
query: Query
}
type Query{
# 查询所有动物
animals:[IAnimal]
}
interface IAnimal{
#动物名字
name:String!
}
type Dog4Interface implements IAnimal{
name:String!
#有几条腿
legs:Int
}
type Fish4Interface implements IAnimal{
name:String!
# 尾巴的颜色
tailColor:String
}
服务端Schema&DataFetcher
package com.tangbaobao.graphql.service;
import com.google.common.base.Charsets;
import com.google.common.io.Resources;
import com.tangbaobao.graphql.domain.Dog4Interface;
import com.tangbaobao.graphql.domain.Fish4Interface;
import com.tangbaobao.graphql.domain.IAnimal;
import graphql.GraphQL;
import graphql.schema.DataFetcher;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.List;
/**
* @author tangxuejun
* @version 2020/4/3 12:24 上午
*/
@Service
public class GraphQLInterfaceTestWithSDL {
private GraphQL graphQL;
@PostConstruct
public void init() throws IOException {
URL url = Resources.getResource("interface.graphqls");
String sdl = Resources.toString(url, Charsets.UTF_8);
GraphQLSchema graphQLSchema = buildSchema(sdl);
this.graphQL = GraphQL.newGraphQL(graphQLSchema).build();
}
private GraphQLSchema buildSchema(String sdl) {
TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(sdl);
RuntimeWiring runtimeWiring = buildWiring();
SchemaGenerator schemaGenerator = new SchemaGenerator();
return schemaGenerator.makeExecutableSchema(typeRegistry, runtimeWiring);
}
@Bean
public GraphQL graphQL() {
return graphQL;
}
private RuntimeWiring buildWiring() {
return RuntimeWiring.newRuntimeWiring()
.type("Query",
builder -> builder
.dataFetcher("animals", this.getAnimalDataFetcher()))
.type(TypeRuntimeWiring.newTypeWiring("IAnimal")
.typeResolver(env -> {
if (env.getObject() instanceof Dog4Interface) {
return env.getSchema().getObjectType("Dog4Interface");
}
if (env.getObject() instanceof Fish4Interface) {
return env.getSchema().getObjectType("Fish4Interface");
}
return null;
}).build())
.build();
}
private DataFetcher<List<IAnimal>> getAnimalDataFetcher() {
Dog4Interface dog = new Dog4Interface();
dog.setName("dog");
dog.setLegs(4);
Fish4Interface fish = new Fish4Interface();
fish.setName("fish");
fish.setTailColor("red");
IAnimal[] animals = {dog, fish};
return environment -> Arrays.asList(animals);
}
}
JavaType方式
package com.tangbaobao.graphql.service;
import com.tangbaobao.graphql.domain.Dog4Interface;
import com.tangbaobao.graphql.domain.Fish4Interface;
import com.tangbaobao.graphql.domain.IAnimal;
import graphql.GraphQL;
import graphql.TypeResolutionEnvironment;
import graphql.schema.*;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.HashSet;
import java.util.Set;
import static graphql.Scalars.GraphQLInt;
import static graphql.Scalars.GraphQLString;
import static graphql.schema.GraphQLFieldDefinition.newFieldDefinition;
import static graphql.schema.GraphQLInterfaceType.newInterface;
import static graphql.schema.GraphQLObjectType.newObject;
/**
* @author tangxuejun
* @version 2020/4/3 12:24 上午
*/
@Service
public class GraphQLInterfaceTest {
private GraphQL graphQL;
private static GraphQLInterfaceType animalInterface = newInterface()
.name("IAnimal")
.description("动物接口")
.field(newFieldDefinition()
.name("name").type(GraphQLString))
.typeResolver(new TypeResolver() {
@Override
public GraphQLObjectType getType(TypeResolutionEnvironment env) {
if (env.getObject() instanceof Dog4Interface) {
return dogType;
}
if (env.getObject() instanceof Fish4Interface) {
return fishType;
}
return null;
}
})
.build();
private static GraphQLObjectType dogType = newObject()//定义Dog类型
.name("Dog4Interface")
.field(newFieldDefinition().name("name").type(GraphQLString))
.field(newFieldDefinition().name("legs").type(GraphQLInt))
.withInterface(animalInterface)
.build();
private static GraphQLObjectType fishType = newObject()//定义Fish类型
.name("Fish4Interface")
.field(newFieldDefinition().name("name").type(GraphQLString))
.field(newFieldDefinition().name("tailColor").type(GraphQLString))
.withInterface(animalInterface)
.build();
@PostConstruct
public void init() {
//服务端实例数据
Dog4Interface dog = new Dog4Interface();
dog.setName("dog");
dog.setLegs(4);
Fish4Interface fish = new Fish4Interface();
fish.setName("fish");
fish.setTailColor("red");
IAnimal[] animals = {dog, fish};
//定义暴露给客户端的查询API
GraphQLObjectType queryType = newObject().name("Query")
.field(newFieldDefinition()
.type(GraphQLList.list(animalInterface))
.name("animals")
.dataFetcher(environment -> animals)
).build();
//额外的GraphQL类型
Set<GraphQLType> types = new HashSet<>();
types.add(dogType);
types.add(fishType);
//创建Schema
GraphQLSchema schema = GraphQLSchema.newSchema()
.query(queryType)
.additionalTypes(types)
.build();
graphQL = GraphQL.newGraphQL(schema).build();
}
@Bean
public GraphQL graphQL() {
return graphQL;
}
}