如何根据选择集阻止运行解析器?

时间:2018-02-03 21:32:12

标签: graphql apollo-server

示例:

user.starredPosts

服务器如何注意到只请求了id,并使用已经提取的Posts.findOne(id)(一组id),而不是为每个id调用class PostController extends Controller { /** * Display a listing of the resource. * * @return \Illuminate\Http\Response */ public function index() { $posts=Post::with('users')->paginate(5); return view('\home2',compact('posts')); }

2 个答案:

答案 0 :(得分:1)

我们遇到了同样的问题,并且正在开源我们在过去一年半内建立的工具,以解决这些问题:https://github.com/4Catalyzer/graphql-node-resource/pull/1

对于像这样的对象解析器,我们使用的解决方案是将它们解析为仅包含ID的“存根”对象,如:

const childField = {
  type: ChildType,
  resolve: obj => ({ id: obj.childId }),
};

然后我们使用DataLoader通过使用我们自己的默认解析器来获取子对象上的其他字段。

我们连接到我们的内部REST API,它支持对这些请求进行批处理,因此可以有效地分派和解析需要其他字段的查询。

但是,这确实会在编写自定义解析器时引入错误,因为无法保证obj实际上具有相关字段。我们已通过设置静态类型来解决此问题,以防止对obj属性进行未经检查的访问。

答案 1 :(得分:0)

您可以检查info.fieldNodes[0].selectionSet.selections或使用graphql-fields包:

const postsIds = user.starredPosts

const selectionSet = Object.keys(graphqlFields(info))

const onlySelectingId = isEqual(['__typename', 'id'], selectionSet.sort())
if (onlySelectingId) {
  return postIds.map(id => ({ id, __typename: 'Post' }))
} else {
  return favs.map(id => Post.findOneById(id))
}