GraphQL响应中的自定义映射键 [英] Custom map keys in GraphQL response

查看:303
本文介绍了GraphQL响应中的自定义映射键的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究GraphQL来替代我的一些REST API,尽管我认为我已经将自己的知识包扎在基础知识上,并且像到目前为止所见的大多数内容一样,但似乎有一个重要功能丢失.

I've been looking into GraphQL as a replacement for some REST APIs of mine, and while I think I've wrapped my head around the basics and like most of what I see so far, there's one important feature that seems to be missing.

比方说,我有一些这样的物品:

Let's say I've got a collection of items like this:

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

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

An application needs a map of all those objects, indexed by ID as such:

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

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

Every API I've ever written has been able to give results back in a format like this, but I'm struggling to find a way to do it with GraphQL. I keep running across issue 101, but that deals more with unknown schemas. In my case, I know exactly what all the fields are; this is purely about output format. I know I could simply return all the items in an array and reformat it client-side, but that seems like overkill given that it's never been needed in the past, and would make GraphQL feel like a step backwards. I'm not sure if what I'm trying to do is impossible, or I'm just using all the wrong terminology. Should I keep digging, or is GraphQL just not suited to my needs? If this is possible, what might a query look like to retrieve data like this?

我目前正在服务器上使用 graphql-php ,但是我正在可以接受更高层次的概念性回应.

I'm currently working with graphql-php on the server, but I'm open to higher-level conceptual responses.

推荐答案

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

Unfortunately returning objects with arbitrary and dynamic keys like this is not really a first-class citizen in GraphQL. That is not to say you can't achieve the same thing, but in doing so you will lose many of the benefits of GraphQL.

如果您设置返回具有ID键的对象,而不是返回包含ID的对象的集合/列表,然后在客户端上进行转换,则可以创建特殊的GraphQLScalarType.

If you are set on returning an object with id keys instead of returning a collection/list of objects containing the ids and then doing the transformation on the client then you can create a special 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;
  }
});

此方法的问题在于,由于它是标量类型,因此您无法提供选择集来查询它.例如.如果你有类型

The problem with this approach is that since it is a scalar type you cannot supply a selection set to query it. E.G. if you had a type

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

那么您将只能像这样查询它

Then you would only be able to query it like so

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

正如其他人所说,我不推荐这样做,因为您正在失去GraphQL的很多好处,但是这表明GraphQL仍然可以执行REST可以做的几乎所有事情.如果您只想尝试一下,我们可以在 scaphold.io 上提供AnyObject类型.

As others have said, I wouldn't recommend this because you are losing a lot of the benefits of GraphQL but it goes to show that GraphQL can still do pretty much anything REST can. If you just want to try it out we provide AnyObject types on scaphold.io that you can play around with.

希望这会有所帮助!

这篇关于GraphQL响应中的自定义映射键的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆