我正在尝试获取模型列表。
首先,我创建了一个模型查询API。现在,我想通过提供ids
来获得列表。
我知道我可以在Promise.all
上使用getModelById
,并对再次得到的每个结果进行一些处理。
但是有一种方法可以重用各个模型查询API吗?谢谢
const ModelType = new GraphQLObjectType({
name: 'Model',
fields: {
id: { type: GraphQLString },
// ...
}
});
const RootQuery = new GraphQLObjectType({
name: 'RootQueryType',
fields: () => ({
model: {
type: ModelType,
args: {
id: { type: GraphQLString }
},
resolve(parentValue, args) {
const { id } = args;
return getModelById(id).then(model => doSomeProcessing(model));
}
},
models: {
type: new GraphQLList(ModelType),
args: {
ids: { type: new GraphQLList(GraphQLString) }
},
resolve(parentValue, args) {
const { ids } = args;
// here I know I can use Promise.all on getModelById and do my doSomeProcessing again for each result I got,
// but is there a way to reuse the model query above? Thanks
}
}
})
});
答案 0 :(得分:1)
您不能引用另一个解析器中的现有解析器。重用逻辑的唯一方法是将其抽象为一个单独的函数,两个解析器都将调用该函数。例如:
const getProcessedModelById = (id) => {
return getModelById(id).then(model => doSomeProcessing(model))
}
// model
resolve(parentValue, args) {
return getProcessedModelById(args.id)
}
// models
resolve(parentValue, args) {
return Promise.all(args.ids.map(id => getProcessedModelById(args.id)))
}
取决于您对模型进行的处理的种类,可能可以通过Model
类型的字段解析器来完成。假设您的Model
类型具有两个字段-firstName
和lastName
,但是您的模型返回一个名为name
的字段。您的doSomeProcessing
只是拿这个名字并将其分为firstName
和lastName
:
function doSomeProcessing (model) {
const names = model.name.split(' ')
return { firstName: names[0], lastName: names[1] }
}
您的解析器可能会返回getModelById
所返回的内容,而不是这样做。然后,您可以将“处理”逻辑封装在每个字段的解析器中:
// firstName field
resolve (parentValue) {
return parentValue.name.split(' ')[0]
}
// lastName field
resolve (parentValue) {
return parentValue.name.split(' ')[1]
}
这种方法的优点是,除非客户端请求该字段,否则“处理”实际上不会发生。在这个非常简单的示例中,解决lastName
字段并不昂贵,但是并非总是如此。它还非常巧妙地封装了从基础数据层派生的字段的逻辑。但是,它也可能最终变得更昂贵(例如,假设split
调用本身就很昂贵...现在,我们要两次而不是一次调用该方法)。