question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Using Bindings with Fragments for a Stitched Schema

See original GitHub issue

My questions are how to use fragments with bindings and how to use Dataloader with bindings.

To preface, I may be completely lost in my own head on this problem. So let me give the 100,000ft view and hopefully there’s an answer.

I have two servers, one for vehicles and one for files. The vehicles server needs to stitch in the file server. The vehicle server wants to query:

{
   vehicles {
         year
         make
         ....
         heroImages {
               url
         }
}

heroImages comes from the file server. Here’s how I’ve implemented this so far.

I used get-schema to save a copy of the file server to the vehicle server. I imported the needed types through schema.graphql.

My app schema:

  const appSchema = makeExecutableSchema({
    typeDefs: [
      importSchema(`./src/schema.graphql`),
      `extend type Vehicle { heroImages: [FileGroup!]! }`
    ],
    resolvers
  })

Then I build the binding for the file server

const makeFileServiceLink = new HttpLink({
  uri: `url`,
  fetch
})

const remoteSchema = makeRemoteExecutableSchema({
    schema: await introspectSchema(makeFileServiceLink),
    link: makeFileServiceLink
})

const fileServer = new Binding({
    schema: remoteSchema,
    fragmentReplacements: {}
})

All good so far. But here’s where things go sideways. Obviously heroImages is an N+1 call. So I made a Dataloader…

  const heroImagesLoader = new DataLoader(async ids => {
    const images = await fileServer.query.vehicleHeroImages(
      { input: { vehicleIds: ids } },
    )
    return ids.map(id => {
      const FileGroup = images.find(({ groupId }) => groupId === id)
      return FileGroup ? [FileGroup] : []
    })
  })

And the resolver…

{
  Vehicle: {
     heroImages: {
        fragment: `fragment VehicleFrag on Vehicle { stockNo }`,
        resolve: async ({ stockNo }, source, ctx, info) => {
          const { heroImagesLoader } = ctx.loaders
           return heroImagesLoader.load(stockNo)
       }
    }
  }
}

The first few problems rear their heads.

  1. How to get info into the binding query. DataLoader’s API is pretty strict. I’ve made it work by turning it into an object, but whoa hack… heroImagesLoader.load({ id: stockNo, info}) and then mapping the ids and passing ids[0].info for the info binding parameter.

  2. How to get a field into the binding if it’s not queried. In my set up, the vehicle server stores a stockNo for each vehicle. The file server groups files by a groupId. For vehicles, the stockNo is the groupId. Therefore, I cannot map the results back without knowing the groupId field. I’m sure there’s a hack I could do to info, but isn’t there a better way?

I tried messing with the binding’s fragmentReplacement to no avail. e.g.

 const fragmentReplacements = extractFragmentReplacements({
    Query: {
      vehicleHeroImages: {
        fragment: `fragment GroupId on FileGroup { groupId }`
      }
    }
  })

 const imageServer = new Binding({
    schema: remoteSchema,
    fragmentReplacements
  })

to no avail.

Any help is a huge help! Thanks everyone as always for your time and effort!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

4reactions
marktanicommented, Mar 22, 2018

Thanks a lot for your detailed description, @LawJolla.

I am curious to hear the perspective of @kbrandwijk, @schickling and @freiksenet on this topic 🙂

2reactions
LawJollacommented, Apr 2, 2018

Thanks @schickling !

Here’s the minimal repo. (I kept my development / shared endpoints in the code to make it faster on everyone)

https://github.com/LawJolla/graphql-stitched-bindings-example

Read more comments on GitHub >

github_iconTop Results From Across the Web

Schema Stitching: Customizing GraphQL API more easily with ...
Very easy. You can use several tools. Direction. Utilize extend for customizing definitions; Utilize Binding or SchemaTransforms for customizing ...
Read more >
GraphQL Schema Stitching explained: Schema Delegation
In essence, schema delegation is about being able to easily forward queries to an existing GraphQL API. Schema binding: An easy way to...
Read more >
GraphQL schema delegation
Schema stitching is a process of combining multiple GraphQL schemas together. It simplifies the creation of a gateway schema — especially when ...
Read more >
View Binding with Fragments in Android Jetpack
View Binding with Fragments in Android Jetpack · Step 1: Create a new empty activity project · Step 2: Enable the ViewBinding feature...
Read more >
Data Binding with Fragments in Android! - YouTube
Support Me on Patreon https://bit.ly/YCPatreonIn this video, you will learn how to get started using the Data binding with fragments, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found