GraphQL:这两种模式中哪一种更好/更差?

时间:2017-08-08 17:15:56

标签: graphql

我对GraphQL比较陌生,我注意到你可以用两种不同的方式选择相关的字段。假设我们有一个droids表和一个humans表,droids有一个owner,它是humans表中的记录。 (至少)有两种表达方式:

query DroidsQuery {
  id
  name
  owner {
    id
  }
}

或:

query DroidsQuery {
  id
  name
  ownerId # this resolves to owner.id
}

乍一看,前者似乎更具惯用性,显然,如果您选择多个字段,它具有优势(owner { id name }与必须创建新ownerName,因此您可以执行ownerId ownerName })。但是,对ownerId风格有一定的明确性,因为你在表达“这是我特别希望你选择的东西”。

此外,从实施的角度来看,似乎owner { id }会使解决方案产生不必要的JOIN,因为它会将owner { id }翻译为idhumans表的对象(与ownerId字段的对应,它有自己的解析器,知道它不需要JOIN来获取owner_id表的droids列)。

正如我所说,我是GraphQL的新手,所以我确信这个问题有很多细微差别,如果我长时间使用它,我会很感激。因此,我希望从使用GraphQL的人那里获得任何方法的好处或缺点。只是为了清楚(并避免让这个答案关闭)我正在寻找明确的“这是一个方法对另一个方法的客观坏/好”,而不是主观的“我更喜欢一种方法”的答案。

1 个答案:

答案 0 :(得分:1)

您应该了解GraphQL只是一种查询语言+执行语义。您提供数据的方式以及解决数据的方式没有限制。

没有什么可以阻止你做你描述的事情,并返回所有者对象和ownerId。

type Droid {
  id: ID!
  name: String!
  owner: Human! # use it when you want to expand owner detail
  ownerId: ID! # use it when you just want to get id of owner
}

你已经指出了主要问题:前一个实现似乎更惯用。不,你不做一个惯用的代码,你制作实用的代码。

在GraphQL中设计字段分页时的真实示例:

type Droid {
  id: ID!
  name: String!
  friends(first: Int, after: String): [Human]
}

第一次,您查询机器人+朋友,这很好。

{
  query DroidsQuery {
    id
    name
    friends(first: 2) {
      name      
    }
  }
}

然后,点击“更多”以加载更多朋友;在解析下一个朋友之前,它会再次点击DroidsQuery来查询前一个droid对象:

{
  query DroidsQuery {
    id
    friends(first: 2, after: "dfasdf") {
      name      
    }
  }
}

因此,让另一个DroidFriendsQuery查询直接解析来自droid id的朋友是可行的。