Graphql query only not null objects
Asked Answered
A

2

22

im trying to perform a query like this:

{
 people{
   pet{
     name
   }
 }
}

result:

{
 "people": {
   "pet": null
 }
},
{
 "people": {
   "pet": {
     name: "steve"
  }
 }
}

What i want is to get only people that contains a pet, is there any way to achieve this not coding on my resolver ?

Afghan answered 22/6, 2016 at 13:11 Comment(2)
#36452410Blackmun
You can have a look at this github.com/gridsome/gridsome/issues/1053#issuecomment-605328928Scheider
R
4

This is not possible the way you describe. GraphQL will call resolve functions to fetch the data. If you don't want certain data in your response, you have to filter it somewhere on the server. The only thing you have control over is the query, the schema and the resolve functions.

There is no way to express your requirement purely in the query. If you put it in the schema, you would no longer be able to query for people without pets. So the only way to do it is to write it in your resolve function. You could for example add a boolean argument called hasPet to your people field, and do this in the resolver:

people(root, { hasPet }){
  // get allPeople
  if (typeof hasPet === 'undefined'){
    return allPeople
  }
  return allPeople.filter((person) => person.hasPet() === hasPet)
}

The unfortunate thing is that this will require you to 'look ahead' and figure out if a person has a pet in the first place, but if you cache backend or DB requests with something like DataLoader, this isn't actually costly, because you would have to fetch the pet anyway. This way you just fetch it a bit earlier.

If you're fetching your people from a database, it would of course make sense to already filter them there, and not in the resolve function.

Ratib answered 23/6, 2016 at 3:37 Comment(0)
D
12

Actually, it is possible with the filter: { pet: {ne: null} } filtering:

query allPeople(filter: { people: { pet: {ne: null} } }) {
    people {
       pet
    }
}
Downhaul answered 5/10, 2021 at 11:57 Comment(2)
Do you have any documentation reference for this? I wonder whether this filter functionality is specific to a particular stack, as it doesn't seem to work in Apollo Studio Star Wars APIModlin
@Modlin Actually I've been looking at gatsby's docs - Don't know why it doesn't work on apollo and didn't find much info in their docs unfortunately. Hopefully this resource might help you find the needed info.Downhaul
R
4

This is not possible the way you describe. GraphQL will call resolve functions to fetch the data. If you don't want certain data in your response, you have to filter it somewhere on the server. The only thing you have control over is the query, the schema and the resolve functions.

There is no way to express your requirement purely in the query. If you put it in the schema, you would no longer be able to query for people without pets. So the only way to do it is to write it in your resolve function. You could for example add a boolean argument called hasPet to your people field, and do this in the resolver:

people(root, { hasPet }){
  // get allPeople
  if (typeof hasPet === 'undefined'){
    return allPeople
  }
  return allPeople.filter((person) => person.hasPet() === hasPet)
}

The unfortunate thing is that this will require you to 'look ahead' and figure out if a person has a pet in the first place, but if you cache backend or DB requests with something like DataLoader, this isn't actually costly, because you would have to fetch the pet anyway. This way you just fetch it a bit earlier.

If you're fetching your people from a database, it would of course make sense to already filter them there, and not in the resolve function.

Ratib answered 23/6, 2016 at 3:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.