Apollo/Hasura 使用 Typescript 的 GraphQL 查询的扁平化结果

Flattening Result from Apollo/Hasura GraphQL Query using Typescript

使用 Apollo 客户端挂钩,我在组件中检索了以下查询:

import {
  gql
} from '@apollo/client';

interface User {
  id: number;
  email: string;
  role: string;
}

interface QueryData {
  organization_users: OrgUser[];
}

export const GET_USERS = gql `
  query GetUsers {
    organization_users {
      user {
        id
        email
      }
      role
    }
  }
`;

如何使从 Hasura 映射返回到我的 User 界面的结果正确,有效地压平上面的 organization_users.user

几个建议...

  1. 创建一些转换逻辑来扁平化内存中的数据,即在应用程序的 Typescript 中,使用 as 类型断言。 https://www.typescriptlang.org/docs/handbook/interfaces.html

  2. 在 Hasura 中创建一个包含 user 列和 organization_users 列的视图。所以organization_users_view可以定义为

select user.id as id, users.email as email, organization_users.role as role
  from organization_users 
  join users 
  on organization_users.user_id = users.id;

所以查询看起来像...

export const GET_USERS = gql `
  query GetUsers {
    organization_users_view {
      id
      email
      role
    }
  }
`;

用更少的代码更接近,但请仔细检查您是否保留了 Apollo 缓存在水化应用程序其他部分方面的优势,这在很大程度上取决于 ID 和资源 "type"。它还需要一些开销来定义 and/or 每次需要更多列时修改视图(可以根据需要使用 users.* 和 organization_users.*)。然而,一个好处是这将很好地处理类型和组件生成......因此您不必手动定义接口。

在 avimoondra 的回答中添加另一个建议:

计算字段

使用 Hasura 计算字段,您实际上可以避免创建一个全新的视图来创建它。实际上,您可以通过在 returns 角色的用户对象上定义一个函数,使 role 成为用户模式的虚拟 属性。

在此处查看更多信息:https://hasura.io/docs/1.0/graphql/manual/schema/computed-fields.html