6

我一直在研究 GraphQL 作为我的一些 REST API 的替代品,虽然我认为我已经把自己的头脑围绕在基础知识上,并且就像我目前看到的大部分内容一样,但似乎缺少一个重要的特性。

假设我有一个这样的项目集合:

{
    "id": "aaa",
    "name": "Item 1",
    ...
}

应用程序需要所有这些对象的映射,由 ID 索引,如下所示:

{
    "allItems": {
        "aaa": {
            "name": "Item 1",
            ...
        },
        "aab": {
            "name": "Item 2",
            ...
        }
    }
}

我曾经编写过的每个 API 都能够以这样的格式返回结果,但我正在努力寻找一种使用 GraphQL 的方法。我一直在运行issue 101,但这更多地涉及未知模式。就我而言,我确切地知道所有字段是什么;这纯粹是关于输出格式。我知道我可以简单地返回一个数组中的所有项目并在客户端重新格式化它,但这似乎有点过头了,因为过去从未需要它,并且会让 GraphQL 感觉像是倒退了一步。我不确定我想要做的事情是否不可能,或者我只是使用了所有错误的术语。我应该继续挖掘,还是 GraphQL 不适合我的需求?如果这是可能的,那么检索这样的数据的查询会是什么样子?

我目前正在服务器上使用graphql-php,但我对更高级别的概念响应持开放态度。

4

1 回答 1

12

不幸的是,像这样返回具有任意和动态键的对象并不是 GraphQL 中的一等公民。这并不是说您无法实现相同的目标,但这样做您将失去 GraphQL 的许多好处。

如果您设置返回带有 id 键的对象,而不是返回包含 id 的对象的集合/列表,然后在客户端上进行转换,那么您可以创建一个特殊的 GraphQLScalarType。

const GraphQLAnyObject = new GraphQLScalarType({
  name: 'AnyObject',
  description: 'Any JSON object. This type bypasses type checking.',
  serialize: value => {
    return value;
  },
  parseValue: value => {
    return value;
  },
  parseLiteral: ast => {
    if (ast.kind !== Kind.OBJECT) {
      throw new GraphQLError("Query error: Can only parse object but got a: " + ast.kind, [ast]);
    }
    return ast.value;
  }
});

这种方法的问题在于,由于它是标量类型,因此您无法提供选择集来查询它。EG 如果你有一个类型

type MyType implements Node {
  id: ID!
  myKeyedCollection: AnyObject
}

那么你只能像这样查询它

query {
  getMyType(id: abc) {
    myKeyedCollection  # note there is no { ... }
  }
}

正如其他人所说,我不推荐这样做,因为你失去了 GraphQL 的很多好处,但它表明 GraphQL 仍然可以做 REST 可以做的任何事情。

希望这可以帮助!

于 2017-01-10T00:06:20.683 回答