Graphqlbundle: Interfaces / inheritance not working (Runtime Object type A is not a possible type for B.)

Created on 12 Jun 2018  路  3Comments  路  Source: overblog/GraphQLBundle

| Q | A
| ---------------- | -----
| Bug report? | yes
| Feature request? | no
| BC Break report? | no
| RFC? | no
| Version/Branch | 0.11.0

In my php model, i have an abstract class Acme\\Entity\\User with some fields, say displayName and username. I also have a concrete class Acme\\Entity\\LocalUser which extends User and has additional fields, say firstName and lastName.

I want to represent that same model in GraphQL. Following the type inheritance documentation, I ended up with this schema:

Query:    # root query
  type: object
  config:
    fields:
      user:
        type: User
        args:
          username: String
          self: Boolean
        resolve: '@=resolver(''my_user_resolver'', [args])'

User:
  type: interface
  config:
    fields:
      username:
        type: "String"
      displayName:
        type: "String" 
    resolveType: '@=resolver(''my_usertype_resolver'', [value])' # returns string 'LocalUser'

LocalUser:
  type: object
  inherits:
    - User
  config:
    fields:
      firstName:
        type: "String"
      lastName:
        type: "String"

However, when I send a query that has to do with these types, like:

{
  user(self: true) {
   displayName
  }
}

I get the following error:

{
"errors": [
    {
     "debugMessage": "Runtime Object type \"LocalUser\" is not a possible type for \"User\".",
     "message": "Internal server Error",
     "category": "internal",
     "locations": [
        {
         "line": 2,
         "column": 3
        }
     ],
     "path": [
        "user"
     ],
     "trace": [
        {
         "file": "\\My\\Project\\Location\\vendor\\webonyx\\graphql-php\\src\\Executor\\Executor.php",
         "line": 1106,
         "call": "GraphQL\\Executor\\Executor::ensureValidRuntimeType('LocalUser', GraphQLType: User, instance of ArrayObject(1), instance of GraphQL\\Type\\Definition\\ResolveInfo, instance of Acme\\Entity\\LocalUser)"
        },
        ...
     ],
     "data": {
        "user": null
     }
    }
}

Also when I use an inline-fragment, I get a slightly differently formulated error, though it essentially says the same:

{
  user(self: true) {
    displayName
    ... on LocalUser {
      firstName
    }
  }
}

{
  "errors": [
    {
      "message": "Fragment cannot be spread here as objects of type \"User\" can never be of type \"LocalUser\".",
      "category": "graphql",
      "locations": [
        {
          "line": 4,
          "column": 5
        }
      ]
    }
  ]
}

Things I tried which didn't work

  • declaring User as object
    With this I can get fields of User, but still can't use inline-fragments to get fields of LocalUser (Fragment cannot be spread here as objects of type \"User\" can never be of type \"LocalUser\".")

  • added heirs: [ LocalUser ] to User
    I tried this with User as interface as well as object, neither did work.

  • explicitly declare LocalUser
    As described in the upgrade guide. Had no effect.

  • clearing cache after all the above
    No effect.

Most helpful comment

Your LocalUser type only inherits of User type config (fields) this does not replace graphQL interface implementation. You still have to explicit declare that LocalUser implement User:

LocalUser:
  type: object
  inherits:
    - User
  config:
+   interfaces: [User]
    fields:
      firstName:
        type: "String"
      lastName:
        type: "String"

I'm closing this since it is not a bug but feel free to continue discussion if needed :+1:

All 3 comments

Your LocalUser type only inherits of User type config (fields) this does not replace graphQL interface implementation. You still have to explicit declare that LocalUser implement User:

LocalUser:
  type: object
  inherits:
    - User
  config:
+   interfaces: [User]
    fields:
      firstName:
        type: "String"
      lastName:
        type: "String"

I'm closing this since it is not a bug but feel free to continue discussion if needed :+1:

@mcg-web could you please update GraphQLBundle/docs/definitions/type-system/interface.md to introduce a basic usage example of an interface please ?

@bastos71 we have in plan to rewrite totally the documentation introducing some examples but we missing time right now, you can find a complete example here https://github.com/mcg-web/graphql-symfony-doctrine-sandbox/tree/master/src/AppBundle/Resources/config/graphql

Was this page helpful?
0 / 5 - 0 ratings