动态构建中继查询

时间:2017-11-06 17:58:47

标签: javascript reactjs graphql relayjs

我使用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模式中。我想要的只是动态构建查询,而不是动态的GraphQL架构。

2 个答案:

答案 0 :(得分:1)

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时,请确保将该片段包含在某个顶级查询中。

答案 1 :(得分:0)

虽然您无法像第二个示例中概述的那样以无限制的方式动态创建查询,但您可以使用@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)
      }
    }
  }
}