Bir*_*sky 1 graphql graphql-js apollo-server
使用facebook的参考库,我发现了一种破解通用类型的方法,如下所示:
type PagedResource<Query, Item> = (pagedQuery: PagedQuery<Query>) => PagedResponse<Item>
?
interface PagedQuery<Query> {
query: Query;
take: number;
skip: number;
}
?
interface PagedResponse<Item> {
items: Array<Item>;
total: number;
}
Run Code Online (Sandbox Code Playgroud)
function pagedResource({type, resolve, args}) {
return {
type: pagedType(type),
args: Object.assign(args, {
page: { type: new GraphQLNonNull(pageQueryType()) }
}),
resolve
};
function pageQueryType() {
return new GraphQLInputObjectType({
name: 'PageQuery',
fields: {
skip: { type: new GraphQLNonNull(GraphQLInt) },
take: { type: new GraphQLNonNull(GraphQLInt) }
}
});
}
function pagedType(type) {
return new GraphQLObjectType({
name: 'Paged' + type.toString(),
fields: {
items: { type: new GraphQLNonNull(new GraphQLList(type)) },
total: { type: new GraphQLNonNull(GraphQLInt) }
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
但是我喜欢使用Apollo Server如何以声明方式创建架构。所以问题是,你们如何使用模式语言创建类似泛型的类型?
您可以创建接口或联合以实现类似的结果。我认为本文在解释如何正确实现接口和联合方面做得很好。您的架构如下所示:
type Query {
pagedQuery(page: PageInput!): PagedResult
}
input PageInput {
skip: Int!
take: Int!
}
type PagedResult {
items: [Pageable!]!
total: Int
}
# Regular type definitions for Bar, Foo, Baz types...
union Pageable = Bar | Foo | Baz
Run Code Online (Sandbox Code Playgroud)
您还需要为联合定义一个resolveType方法。使用graphql-tools,这是通过解析器完成的:
const resolvers = {
Query: { ... },
Pageable {
__resolveType: (obj) => {
// resolve logic here, needs to return a string specifying type
// i.e. if (obj.__typename == 'Foo') return 'Foo'
}
}
}
Run Code Online (Sandbox Code Playgroud)
__resolveType将要解析的业务对象作为其第一个参数(通常是您提供GraphQL解析的原始数据库结果)。您需要在这里应用一些逻辑来找出所有不同的Pageable类型,我们正在处理这种类型。对于大多数ORM,您只需将某种typename字段添加到正在使用的模型实例中,然后将其resolveType返回即可。
编辑:正如您所指出的那样,此方法的缺点是项中返回的类型对客户端不再透明-客户端将必须知道返回的类型,并为itemsinline片段中的字段指定字段... on Foo。当然,您的客户仍然必须对返回的类型有所了解,否则他们将不知道要请求哪些字段。
我想以声明的方式生成架构时,按照您想要的方式创建泛型是不可能的。为了使您的模式能够以与当前相同的方式工作,您必须忍耐一下,定义PagedFoo何时定义Foo,定义PagedBar何时定义Bar,依此类推。
我能想到的唯一其他选择是将两种方法结合起来。以编程方式创建“基础”架构。您只需要使用pagedResource函数在“根查询”下定义分页查询。然后,您可以使用printSchemafrom graphql/utilities将其转换为可以与其余类型定义串联的String。在类型定义中,可以使用extend关键字在基础模式中已经声明的任何类型上进行构建,如下所示:
extend Query {
nonPaginatedQuery: Result
}
Run Code Online (Sandbox Code Playgroud)
如果走这条路线,您可以跳过将resolve函数传递给pagedResource或在以编程方式定义的类型上定义任何解析器的方式,而只需利用通常传递给的解析器对象即可buildExecutableSchema。
| 归档时间: |
|
| 查看次数: |
3765 次 |
| 最近记录: |