Filter interface by type

with a schema:


interface I_Actor {
  id:ID!
  name:String @search
}
type User implements I_Actor{
    username:String! @search
}
type Robot implements I_Actor{
    robotname:String! @search
}

and these data (2 Users and 2 Robots):

query qq { 
  queryI_Actor{
    id
    name
    ...on User{  username  }
    ...on Robot{  robotname  }
  }
}

-->>
{
  "data": {
    "queryI_Actor": [
      {
        "id": "0x2712",
        "name": "a1",
        "username": "user1"
      },
      {
        "id": "0x2713",
        "name": "a2",
        "username": "user2"
      },
      {
        "id": "0x2714",
        "name": "a4",
        "robotname": "robot2"
      },
      {
        "id": "0x2715",
        "name": "a3",
        "robotname": "robot1"
      }
    ]
  }
}

I’d like to query I_Actor of a specific type .
there’s no filter option for filtering out implementations
so I tried

query qq {
  queryI_Actor(first:3) @cascade{
    ...on User{
      id
      name
      username
    }
  }
}
 
-->>
{
  "data": {
    "queryI_Actor": [
      {
        "id": "0x2712",
        "name": "a1",
        "username": "user1"
      },
      {
        "id": "0x2713",
        "name": "a2",
        "username": "user2"
      }
    ]
  }
}

seems to work…
but selecting the other type

 query qq {
  queryI_Actor(first:3) @cascade{
    ...on Robot{
      id
      name
      robotname
    }
  }
}

-->>
{
  "data": {
    "queryI_Actor": [
      {
        "id": "0x2714",
        "name": "a4",
        "robotname": "robot2"
      }
    ]
  }
}

that’s because it counts the skipped items too , in fact withouot @cascade these are the responses:

for Users:

{
  "data": {
    "queryI_Actor": [
      {
        "id": "0x2712",
        "name": "a1",
        "username": "user1"
      },
      {
        "id": "0x2713",
        "name": "a2",
        "username": "user2"
      },
      {}                                   # <- this is a Robot
    ]
  }
}

for Robots:

{
  "data": {
    "queryI_Actor": [
      {},                                   # <- this is a User
      {},                                   # <- this is a User
      {
        "id": "0x2714",
        "name": "a4",
        "robotname": "robot2"
      }
    ]
  }
}

Hi @aleclofabbro,

Can you provide more details of your use case ?

In case you want to obtain only robots, you may simply use queryRobot and get them. Similarly, you could get Users by using queryUser instead of using queryI_Actor.

yes, sure,
I gave an oversimlpified version of the schema and query…
things get concrete with this schema:

interface I_Actor {
  id:ID! 
  name:String @search
  activities:[ActorActivity!]! @hasInverse(field: actor)
}
type User implements I_Actor{
    username:String! @search
}
type Robot implements I_Actor{
    robotname:String! @search
}
type ActorActivity {
    id:ID!
    desc: String
    actor: I_Actor! @hasInverse(field: activities)
}

I added 4 activities , 1 for each User and Robot

now I want to query Activities made by a Robot:

query queryRobotActivities{
  queryActorActivity{
    id
    desc
    actor {
      ...on Robot{
        name
        robotname
      }
    }
  }
}

this yelds all activities, those of a User just contain an empty actor object

@cascade only strips User out, but the count goes banana

Yes, it does not seem possible to get only Activities made by a Robot this way.

One possible workaround could be to start with queryRobot and then get Activities, this way all the Activities you get will be that made by a Robot.

Another workaround could be to have just one single type for Robot and User and use @cascade in queryActorActivity to filter actor by Robot or User.

@aleclofabbro, The issue arises because @cascade is applied after pagination. This is a known issue and was reported here. You may track any progress with the issue on the same link.