0

Imagine there is a schema like

type Country {
  id String
  name String
  continent String
  languages [Language]
}
type Language {
  id String
  code String
  globalSpeakers Int
}

and I want to query for countries on some continent with some language. And I only want the language field in the country to include the language I'm searching for. So if I wanted countries in Eurasia that spoke French, and didn't want any other languages on the country object...

Is there a recommended way to do this?

Typically I would use a dataloader to batch load the language list on the country, but, as far as I can tell, they really only want to get data by id. So the returned data would have a bunch of languages on the country that I don't want and would need to get rid of on the consumer.

Using one query:

I've thought of trying to get the dataloader (batch loader) to accept arguments other than id, and then trying to batch load by ids and query arguments. Like getting the Country.Language dataloader to accept country id and query args.

I've thought about doing all the querying at the top resolver. But then, in the Country.Language dataloader, I would need to check the country instance, see if it already has language data, and then call or not call the dataloader.

Some other option?

Using multiple queries

I've thought about creating two queries where one can search for countries by criteria and one can search for languages by criteria. And then join the data on the consumer (with potentially some additional filtering).

Some other option?

1
  • I ended up doing the entire search in the top level resolver and then priming the dataloader along with a new "datastore". When the sub-resolvers hit, they check for a datastore first and load from that. Else they check the dataloader. Commented Dec 28, 2022 at 22:43

1 Answer 1

1

Define a query:

GetCountryByContinentAndLanguage(continent: String, language: String): [Country]

In your query resolver search your database for matches based on the continent and country. This search should yield 0-N countries.

Then in your Country Languages resolver - look at the args - if you see a language variable then only return that single language instead of all the languages for that country.

OTOH, if you're running this search from the client then you already know what language you want and you can just ignore the languages field in the return object and replace it with your single language.

Sign up to request clarification or add additional context in comments.

4 Comments

If I'm going to need to search the database for something on the Language, in this case, when do I do that? Like if the language search is on a fulltext property in the database. Do I do that during the initial query and load some data store that can be referenced in the Country.Language resolver?
You want to get the list of countries in the initial query based on the continent and language. In the Country.language resolver look for the language variable in the args and if it's there just return that one language (as an array of length 1)
I think I simplified my example too far. What if I was searching for the languages part with globalSpeakers less than some number? So the query would be GetCountryByContinentAndLanguage(continent: String, languageGlobalSpeakersCountLT: Int): [Country]. In my real use case the filter is an object with a number of different potential filters for "Language" and "Country". And mostly the filters want to be run at the database.
Similar logic should apply. You don't want to join on the client. Use the args and even info parameters in the resolver to figure out what to return in the type resolvers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.