我使用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架构。
答案 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)
}
}
}
}