Graphql-ruby: Allow interfaces to implement other interfaces

Created on 5 Mar 2020  路  3Comments  路  Source: rmosolgo/graphql-ruby

The next version of the GraphQL spec (which I believe will be released at the end March 2020) allows interfaces to implement other interfaces. See the RFC more details. Any plans to support this in graphql-ruby? I'd be happy to pitch in and help if needed.

Most helpful comment

Thanks for the update on this change. I think we already support this in _implemenation_ via:

module SomeGeneralInterface 
  include GraphQL::Schema::Interface 
end 

module SomeSpecificInterface 
  include SomeGeneralInterface 
end 

(I think that will give SomeSpecificInterface _all_ the fields from SomeGeneralInterface, along with its own fields.)

But, we could make it first-class graphql with:

  • Adding implements(...) to interface definition modules;
  • When implements(...) is used, track the parent interface in the child's self.interfaces (just like GraphQL::Schema::Object -- maybe it could be extracted out into GraphQL::Schema::Member::HasInterfaces)
  • Make sure that the schema printer and introspection system return interfaces on interfaces

If you want to take a crack at it, go for it!

All 3 comments

Thanks for the update on this change. I think we already support this in _implemenation_ via:

module SomeGeneralInterface 
  include GraphQL::Schema::Interface 
end 

module SomeSpecificInterface 
  include SomeGeneralInterface 
end 

(I think that will give SomeSpecificInterface _all_ the fields from SomeGeneralInterface, along with its own fields.)

But, we could make it first-class graphql with:

  • Adding implements(...) to interface definition modules;
  • When implements(...) is used, track the parent interface in the child's self.interfaces (just like GraphQL::Schema::Object -- maybe it could be extracted out into GraphQL::Schema::Member::HasInterfaces)
  • Make sure that the schema printer and introspection system return interfaces on interfaces

If you want to take a crack at it, go for it!

The above example does not translate well client-side. (Well, I assume GraphQL's update does accounts for the following, would be a big miss if not!)

If the schema requires a field be of type SomeGeneralInterface, one cannot say implements SomeSpecificInterface and satisfy this.

Looks like the spec has been updated to accommodate this!

Although we can side-step the issue by including the interface into another interface, the outputted GraphQL schema is incorrect. We need to support implements within an interface definition module to support the behaviour properly.

E.g.

module Savable
   include(GraphQL::Schema::Interface)
   include(GraphQL::Types::Relay::Node)
   field :is_saved, Boolean, null: false
end

```graphql
interface Savable {
id: ID,
isSaved: Boolean
}

However, it should actually be this:

```graphql
interface Savable implements Node {
   id: ID,
   isSaved: Boolean
}
Was this page helpful?
0 / 5 - 0 ratings