【问题标题】:Data normalization in GraphQL queryGraphQL 查询中的数据规范化
【发布时间】:2020-08-14 23:58:12
【问题描述】:

我正在使用 GraphQL 查询具有两种数据类型的数据库:UserGroup

组有一个字段users,它是该组中User 对象的数组。我在根目录有一个名为 groups 的字段,它返回我所有组的数组。

典型的查询可能如下所示:

{
    groups {
        id,
        name,
        users {
            id,
            name,
            address,
            email,
            phone,
            attitude,
            job,
            favoriteQuote,
            favoriteColor,
            birthday
        }
    }
}

问题是这些用户中的很多可以属于多个组,并且看到User 有很多字段,这会使响应变得非常大。

有没有办法为对象的第一个实例获取一组字段,并为响应中的每个其他实例获取不同的一组字段?

每个用户在响应中只需要namejobemail 等一次,之后只需要id(之后我可以自己进行标准化)。

或者

有没有办法只为组中的所有用户获取id 字段,并返回查询中引用的所有唯一User 对象的单独数组(不是全部 User 对象)?

【问题讨论】:

    标签: graphql database-normalization


    【解决方案1】:

    一般 - 通常

    ...标准化...当然... f.e.使用apollo,它是标准化缓存。

    从 API 返回的所有记录必须是相同的形状。

    您可以使用仅查询 id 和名称(完整/分页)来获取数据并呈现一些 <MembersList/> 组件。

    稍后您可以使用自己的查询(内部挂钩 useQuery)在某些 <UserProfile/> 组件中渲染细节,以从缓存/api(可控)中获取更多数据。

    您的具体要求 - 可能

    第一个选项:

    通常响应是一种常见的形式(根据要求),但您可以在解析器级别决定返回什么。这需要查询结构更改,以允许(API、后端)使某些属性无效。 F.e.

    group {
        id
        name
        users {
            id
            name
            profile {
              photo
              email
              address
    

    使用 profile 自定义 json 类型...您可以构建用户解析器以仅返回第一条记录的完整数据,并为所有后续用户返回 null

    第二个选项:

    您可以在一个请求中使用 2 个略有不同的查询。简而言之,使用别名(参见文档):

    groupWithFullMember: group ( groupId:xxx, limitUsers:1 ) {
        id
        name
        users {
            id
            name
            address
            email
            ...
        }
    }
    
    groupMembers: group ( groupId:xxx ) {
        id
        name // not required
        users {
            id
            name
        }
    }
    

    组解析器可以返回它的子 users ... 或 users 解析器可以访问 limitUsers 参数来限制响应/修改数据库查询。

    【讨论】:

    • 我希望在一个查询中做到这一点
    • 有趣 - 我必须由拥有实现的后端人员运行它
    【解决方案2】:

    有没有办法为对象的第一个实例获取一组字段,并为响应中的每个其他实例获取不同的一组字段?

    没有。除非单个项目的类型不同,否则将为列表中的每个项目返回相同的字段集,因为可以为运行时返回的每个类型指定单独的选择集。

    有没有办法只获取组中所有用户的 id 字段,并返回查询中引用的所有唯一用户对象(不是所有用户对象)的单独数组?

    您可以设计您的架构来适应这种情况。类似的东西

    {
      groups {
        nodes {
          id
          name
          users {
            id
          }
        }
        uniqueUsers {
          id
          # other fields
        }
      }
    }
    

    您的groups 解析器需要处理所有规范化并以适当的形状返回数据。但是,更简单的解决方案可能是颠倒您的关系:

    {
      users {
        id
        name
        address
        email
        phone
        attitude
        job
        favoriteQuote
        favoriteColor
        birthday
        groups {
          id
          name
        }
      }
    }
    

    【讨论】:

    • 酷 - 我不拥有这个的实现,但我相信我可以让那些在船上做的人
    猜你喜欢
    • 2014-10-21
    • 2011-09-19
    • 2011-10-07
    • 2012-12-25
    • 2014-04-19
    • 2011-11-15
    • 1970-01-01
    • 2017-05-09
    • 2015-01-04
    相关资源
    最近更新 更多