【问题标题】:Build relay queries dynamically动态构建中继查询
【发布时间】:2018-04-18 23:20:36
【问题描述】:

我使用 Relay Modern 作为我的客户端 GraphQL 接口。我想知道是否可以在 Relay Modern 中动态构建我的查询语句,比如更改原来的:

const ComponentQuery = graphql`
    query ComponentQuery ($companyId: ID!) {
        viewer {
            company(id: $companyId) {
                id
                name
                enabled
                users {
                    id
                    username
                    email
                    firstName
                    lastName
                    jobTitle
                    phone
                }
            }
        }
    }
`;

致以下:

let queryFields = ['name', 'enabled'];
let userFields = ['username', 'email', 'firstName', 'lastName', 'jobTitle', 'phone' ];


const ComponentQuery = graphql`
    query ComponentQuery ($companyId: ID!) {
        viewer {
            company(id: $companyId) {
                id
                queryFields
                name
                enabled
                users {
                    id
                    userFields
                }
            }
        }
    }
`;

当然,由于 GraphQL Schema 是静态的,因此所有字段都必须存在于 GraphQL Schema 中。我想要的只是动态构建查询,而不是动态的 GraphQL 架构。

【问题讨论】:

    标签: javascript reactjs graphql relayjs


    【解决方案1】:

    虽然不可能像您在第二个示例中勾勒出的那样以无限的方式动态地制作查询,但您可以使用@include@skip 指令来做出固定数量的选择。

    在片段级别:

    query ComponentQuery(
      $companyId: ID!,
      $showUserDetails: Boolean!,
    ) {
      viewer {
        company(id: $companyId) {
          id
          name
          enabled
          users {
            id
            firstName
            lastName
            ... on User @include(if: $showUserDetails) {
              email
              jobTitle
              phone
              username
            }
          }
        }
      }
    }
    

    在字段级别:

    query ComponentQuery(
      $companyId: ID!,
      $showUserContactDetails: Boolean!,
      $showUserRealName: Boolean!,
      $showUserRole: Boolean!,
      $showUserUnixname: Boolean!,
    ) {
      viewer {
        company(id: $companyId) {
          id
          name
          enabled
          users {
            id
            firstName @include(if: $showUserRealName)
            lastName @include(if: $showUserRealName)
            username @include(if: $showUserUnixname)
            email @include(if: $showUserContactDetails)
            jobTitle @include(if: $showUserRole)
            phone @include(if: $showUserContactDetails)
          }
        }
      }
    }
    

    【讨论】:

      【解决方案2】:

      您在 Relay 中的所有查询和突变都需要静态可供编译器生成运行时工件。任何动态行为都需要由 graphql 变量和片段来控制。请务必仔细阅读 graphql 规范。

      对于您上面的情况,片段会很好地为您服务。片段甚至可以在不同的文件中定义。我将给出一个示例,您将定义一个名为 UserComponent 的子组件,该组件将负责显示用户信息和一个指定所需字段的片段。然后,您可以在父组件查询中使用该片段。假设您正在使用 react 并且您的用户类型称为 User。

      /UserComponent.js
      ...
      const UserComponent = ({ user }) => {...};
      ...
      export default createFragmentContainer(
        ChildComponent,
        graphql`
          fragment UserComponent_user on User {
            id
            username
            email
            firstName
            lastName
            jobTitle
            phone
          }
        `
      );
      
      /Component.js
      const ComponentQuery = graphql`
      query ComponentQuery ($companyId: ID!) {
        viewer {
          company(id: $companyId) {
            id
            name
            enabled
            users {
              ...UserComponent_user
            }
          }
        }
      }`;
      

      每次您需要渲染 UserComponent 时,请确保您在某些顶级查询中包含该片段。

      【讨论】:

        猜你喜欢
        • 2012-11-23
        • 2019-04-08
        • 2012-12-21
        • 2018-12-21
        • 1970-01-01
        • 1970-01-01
        • 2013-08-12
        • 2019-06-24
        • 2020-12-03
        相关资源
        最近更新 更多