为什么选择graphQL解析器

时间:2018-06-21 13:01:16

标签: graphql graphql-js

为什么GraphQL不调用嵌套类型为 Starring 的解析器?

我可以将文件和文件夹加为我的收藏夹。所以我的架构很简单:

type File {
  id: ID!,
  name: String,
  starring: Starring
}

type Folder {
  id: ID!,
  name: String,
  starring: Starring
}

type Starring {
  isStarred: Boolean!
}

我为Starring找出了两种避免代码重复的方法。但是,我想知道为什么GraphQL不够巧,无法首先调用Starring解析器(没有从包装的File解析器中引用)。

到达星标解析器的第一种可能方法:

// File.js
export default {
  id: obj => { obj.id.replace('/file/', '') }
  name: obj => { obj.name.toUpperCase() }
  // why do I need to pass the obj so that the Starring resolver is called?
  starring: obj => obj
}

// Starring.js
export default {
   isStarred: obj => obj.isStarred
}

避免重复的第二种可能方法:

// File.js
import starring from './starring'

export default {
  // feels like wrong approach when I just spread the starring object
  ...starring
  id: obj => { obj.id.replace('/file/', '') }
  name: obj => { obj.name.toUpperCase() }
}

1 个答案:

答案 0 :(得分:0)

GraphQL不够“聪明”,无法调用Starring解析器,因为父对象的结构与您的架构不匹配。根据您的模式,这是GraphQL返回的File对象的样子:

{
  id: 'string',
  name: 'string',
  starring: {
    isStarred: false
  }
}

在您的代码中,传递给File解析器的父对象看起来像这样:

{
  id: 'string'
  name: 'string'
  isStarred: false
}

因此,您可以任一展平您的架构:

type Folder {
  id: ID!,
  name: String,
  isStarred: Boolean!
}

在这种情况下,您用于Folder的解析器将如下所示:

export default {
  id: obj => obj.id.replace('/file/', '')
  name: obj => obj.name.toUpperCase()
  // no need to add resolver for isStarred -- default resolver will handle it for you
}

另一个选择是操纵作为父对象传递给File类型的解析器的对象。例如,如果您有一个查询在其解析程序中返回文件数组,则可以遍历每个查询并将isStarred属性嵌套在starring内,然后再返回数组。

后一种选择与将父对象传递到Starring解析器一样难看。归根结底,您最好将架构展平以匹配正在使用的数据的形状。