Damon Smith
Damon Smith

Reputation: 1790

GraphQL server - how to pass more than one level of root in a field resolver

I'm just starting with Apollo GraphQL. I have a structure like

sportsgame -> teams -> players

I have a schema where I can get all sportsgames, one with all teams, and one with all players, all of that is fine. I also implemented getting each by their id.

I then wrote field resolvers for team and player and it all works well getting teams for a sportsgame or players for a team,

so these sorts of queries are fine and give me team names for a given sportsgame.

query Query {
  sportsgame(gameId: "12345") {
    teams {
      name
    }   
  }
}

And likewise for player I can query:

query Query {
    teams {
      name
      players {
        name
        number
      }
    }   
  }
}

And that works fine too, giving me a list of all teams and the players in each one.

Next I wanted to implement getting all players for a team for a sportsgame, like this:

query Query {
  sportsgame(externalId: "12345") {
    teams {
      name
      players {
        name
      }
    }   
  }
}

But the problem is, I don't want all players for those teams, only the ones that are actually playing in the event. And that requires my fieldResolver to know about the sportsgame at the very top.

So my fieldResolver can get the Root object which is the team, but it doesn't get the sportsgame at the top and so I can't access the sportsgame's id to further filter the player list.

My question is, should I just pass the sportsgame id through the team as an optional bit of hidden data? Or is the some more idiomatic way to do this sort of thing in Apollo? Or am I doing something conceptually weird even trying to make this work?

Upvotes: 1

Views: 903

Answers (2)

Christof Aenderl
Christof Aenderl

Reputation: 4512

You can use the context object for your nested resolvers.

The signature of a resolver function is:

fieldName(obj, args, context, info) { result }

context is an object shared by all resolvers in a particular query, and is used to contain per-request state. From the apollo page

That means, in the resolver for sportgame you set the gameId on the context object and use it in the resolver for players.

Upvotes: 1

jkettmann
jkettmann

Reputation: 707

You may try to add a parameter to players as well. So something like

query Query {
  sportsgame(externalId: "12345") {
    teams {
      name
      players(gameId: "12345") {
        name
      }
    }   
  }
}

This way you can get the game ID from the resolvers args.

To not duplicate the game ID you might want to extract the parameter to your Query component.

query Query($gameId: String!) {
  sportsgame(externalId: $gameId) {
    teams {
      name
      players(gameId: $gameId) {
        name
      }
    }   
  }
}

Upvotes: 1

Related Questions