Graphql-tools: Need help in understanding, how fragments are being used in stitching

Created on 10 Nov 2017  路  2Comments  路  Source: ardatan/graphql-tools

Hi,

Can someone help me in understanding how fragments are used in schema stitching.

Will WeatherLocationArgs as a fragment be part of the underlying query which will be sent to the remote graphql servers and why it is a mandatory to have fragments.

for example

const schema = mergeSchemas({
    schemas: [universeSchema, weatherSchema],
    links: [
      {
        name: 'location',
        from: 'Event',
        to: 'location',
        resolveArgs: parent => ({ place: parent.cityName }),
        fragment: '
          fragment WeatherLocationArgs on Event {
            cityName
          }
        ',
      },
    ],
  });

Thanks

Most helpful comment

I'm unfamiliar with the links syntax, but in general you define a fragment to define fields you need to be able to call the delegate query.

first Schema:

type Query {
   allPosts: [Post]
}

type Post {
   id: ID!
   title: String!
}

second Schema:

type Query {
   allComments(filter: CommentFilter): [Comment]
}

type Comment {
   postId: ID!
   comment: String!
}

type CommentFilter {
   postId: ID!
}

Now stitching them together:

extend type Post {
   comments: [Comment]
}

And mergeSchemas:

const schema = mergeSchemas({
  schemas: [postSchema, commentSchema, newTypeDefs],
  resolvers: mergeInfo => ({
     Post: {
       comments: {
         fragment: `fragment PostFragment on Post { id }`
         async resolve(parent, args, context, info) {
             const postId = parent.id
             return mergeInfo.delegate('query', 'allComments', { filter: { postId } }, context, info)
         }
       }
     }
  })
});

Now this fragment definition makes sure that the query engine adds the id field on Post to the query, because it's needed for the delegate. So if I query:

query {
  allPosts {
    title
    comments {
       comment
    }
  }
}

It will add the fragment I defined automatically:

query {
  allPosts {
    ...PostFragment
    title
    comments {
       comment
    }
  }
}

fragment PostFragment on Post { id }

All 2 comments

I'm unfamiliar with the links syntax, but in general you define a fragment to define fields you need to be able to call the delegate query.

first Schema:

type Query {
   allPosts: [Post]
}

type Post {
   id: ID!
   title: String!
}

second Schema:

type Query {
   allComments(filter: CommentFilter): [Comment]
}

type Comment {
   postId: ID!
   comment: String!
}

type CommentFilter {
   postId: ID!
}

Now stitching them together:

extend type Post {
   comments: [Comment]
}

And mergeSchemas:

const schema = mergeSchemas({
  schemas: [postSchema, commentSchema, newTypeDefs],
  resolvers: mergeInfo => ({
     Post: {
       comments: {
         fragment: `fragment PostFragment on Post { id }`
         async resolve(parent, args, context, info) {
             const postId = parent.id
             return mergeInfo.delegate('query', 'allComments', { filter: { postId } }, context, info)
         }
       }
     }
  })
});

Now this fragment definition makes sure that the query engine adds the id field on Post to the query, because it's needed for the delegate. So if I query:

query {
  allPosts {
    title
    comments {
       comment
    }
  }
}

It will add the fragment I defined automatically:

query {
  allPosts {
    ...PostFragment
    title
    comments {
       comment
    }
  }
}

fragment PostFragment on Post { id }

Thank you @kbrandwijk

I was missing the point of having the parameter always available in the parent.

Was this page helpful?
0 / 5 - 0 ratings