简体   繁体   中英

How to generate the same graphql query with different fields

I'm using graphql-tag so i'm going to use that syntax.

Lets say I have this query:

const query = gql`
 query user(id: String) {
  user(id: $id) {
   id
  }
 }
`

Whats the best patten to reuse that same query document node if on a different call I want the fields username and email in addition to id without having to rewrite the entire query again like:

const query = gql`
 query user(id: String) {
  user(id: $id) {
   id
   username
   email
  }
 }
`

I'm using react-apollo on the frontend if that makes things anymore interesting.

Edit:

Just to clarify... something like this

const userIdFrag = gql`
  fragment UserId on User {
    id
  }
`

const fullUserFrag = gql`
  fragment FullUser on User {
    id
    username
    email
  }
`

const generateQuery = (documentNode) => {
  return gql`
   query user(id: String) {
      user(id: $id) {
       ...documentNode
      }
     }
     ${documentNode}
  `
}

const idQuery = generateQuery(userIdFrag);
const fullUserQuery = generateQuery(fullUserFrag);

(The above does work but give me errors from graphql in the console, which leads me to believe this is not something I should be doing)

Based on your comment the following should work:


const generateQuery = (documentNode, fragment) => {
  return gql`
   query user(id: String) {
      user(id: $id) {
       ...${fragment}
      }
     }
     ${documentNode}
  `
}

const idQuery = generateQuery(userIdFrag, 'UserId');
const fullUserQuery = generateQuery(fullUserFrag, 'FullUser');

Basically the fragment name used is the actual one that needs to be spread while the whole documentNode object is put at the end, after query's closing bracket

I am not the very expert on the topic, but here is what I have been able to find out. (if you see any mistakes in my assumptions, let me know).

I found this article that makes some good points against dynamically generating gql queries/mutations. It seems like you get some nice benefits with the static approach, although it's a bit more typing.

But, in case you do need to have dynamic fields, I haven't been able to find anything bad about using the @skip directive GraphQL provides. Here the docs ref .

For the case of using it in react-apollo they also have it in their docs .

So, your code can end up looking something like this:

const query = gql`
 query user($id: String, $skipUserMeta: Boolean!) {
  user(id: $id) {
   id
   username @skip(if: $skipUserMeta)
   email @skip(if: $skipUserMeta)
  }
 }
`

You just pass the skipUserMeta as a variable alongside the id field.

NOTE: I actually found a video which talks about the exact same approach here

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM