-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC: Allow interfaces to implement other interfaces #373
RFC: Allow interfaces to implement other interfaces #373
Conversation
To clarify a point that came up in the WG meeting, the main use case (what can't currently be accomplished) is representing generic multi-level wrappers using interfaces. For example, representing # generic types
interface Node {
id: ID!
}
interface Connection {
pageInfo: PageInfo!
edges: [Edge]
}
interface Edge {
cursor: String
node: Node
}
type PageInfo {
hasPreviousPage: Boolean
hasNextPage: Boolean
startCursor: String
endCursor: String
}
# pet-specific types
interface Pet {
id: ID!
name: String
}
type PetEdge implements Edge {
cursor: String
node: Pet
}
type PetConnection implements Connection {
pageInfo: PageInfo!
edges: [PetEdge]
}
type Cat implements Pet & Node {
id: ID!
name: String
}
type Dog implements Pet & Node {
id: ID!
name: String
}
# furniture-specific types
interface Furniture implements Node {
id: ID!
packageWidth: Number!
packageHeight: Number!
packageDepth: Number!
}
type FurnitureEdge implements Edge {
cursor: String
node: Furniture
}
type FurnitureConnection implements Connection {
pageInfo: PageInfo!
edges: [FurnitureEdge]
}
type Chair implements Furniture & Node {
id: ID!
packageWidth: Number!
packageHeight: Number!
packageDepth: Number!
seatHeight: Number!
}
type Table implements Furniture & Node {
id: ID!
packageWidth: Number!
packageHeight: Number!
packageDepth: Number!
minSeats: Number!
maxSeats: Number!
}
# query
type Query {
pets: PetConnection
furniture: FurnitureConnection
} |
I know this has been sitting for a while, but I think it has what it takes to move from Proposal to Draft. |
(@leebyron Slightly confused about the label, shouldn’t that then be |
@mike-marcacci are you still championing this? I haven't been an attendee to WG meetings before but I'd like to help in anyway to move this forward. I can't think of a single change to GraphQL that would improve its use for my team and myself more than this |
Hi @slightlytyler - thanks for the note! I am (or am at least am intending to) continue pushing for this. I missed the last WG meeting because the agenda filename was misnamed with the wrong date 😑 but am certainly planning on bringing this up at the next meeting. It seems I have some new merge conflicts to fix here, which I'll make sure to address before then. The biggest roadblock for this RFC has actually been getting the right eyes on the js implementation I made last January. It's now all merge conflicts, so my main goal for the WG meeting is getting a commitment from maintainers to seriously consider the PR when I update it. To be honest, I believe your appeal here – and any other votes of support – will help propel this feature forward. In past meetings the group's hesitance has not been due any technical criticism, but rather a general reluctance to introduce complexity without a clear demand. I don't totally agree that this actually adds complexity, but it is a change, and so I understand giving some pushback. So if you have a real-world use case that is made much better by this proposal, describing it here would go a long way in helping me argue for incorporation of this feature into the spec! |
I can give a simple(ish) example which highlights a reoccurring issue I have encountered in developing GraphQL APIs for various applications. I'll give as real-world of an example as possible without over complicating it. It's actually very close to your example. For reference, I currently work at Docker on our distribution products. We use the concept of interface Node {
id: ID!
}
interface Edge {
cursor: String!
node: Node!
}
interface Connection {
edges: [Edge!]!
page: PageInfo!
}
# ...
interface Image {
digest: String!
size: Int!
# ...
}
type SingleArchImage implements Image, Node {
id: ID!
digest: String!
size: Int!
layers: [Layer!]!
}
type MultiArchImage implements Image, Node {
id: ID!
digest: String!
size: Int!
references: [PlatformReference!]!
}
# ...
type ImageEdge implements Edge {
cursor: String!
node: Image! # this breaks cus Image isn't a Node
}
type ImageConnection implements Connection {
edges: [ImageEdge!]!
page: PageInfo!
} The above schema is close to what I would consider an optimal model, only lacking the interface composition to make it work. interface Image implements Node {
id: ID!
digest: String!
size: Int!
# ...
}
type SingleArchImage implements Image {
id: ID!
digest: String!
size: Int!
layers: [Layer!]!
}
type MultiArchImage implements Image {
id: ID!
digest: String!
size: Int!
references: [PlatformReference!]!
}
# ...
type ImageEdge implements Edge {
cursor: String!
node: Image! # it should work?!
} Let me know if this makes sense or if you require an clarification. If I can help you in anyway moving this forward please let me know |
I just stumbled upon this as well. Is there anything I can do to help to move this forward? |
4fffcd5
to
4a2aadc
Compare
There is finally a new WG meeting on the schedule, so I have rebased the PR. @leebyron per your comment above can we get this moved to draft status? |
Hi @mike-marcacci, we spoke about this item at the last wg meeting and I want to get this one further. |
Here is the discussion we had on the wg
the protocol is not yet approved but can be read in this pull request: |
Hi @michaelstaib - I am definitely committed to this. I had become a bit exasperated by the lack of participation: despite 18 months trying to get some eyes on the implementation PR, no one stepped up. I am thrilled that there's renewed interest, and will definitely start pushing this again. Updates since the last meeting in which I participated:
I will add this to the next meeting's agenda and make sure I'm available to join. If there's any interest in discussing this or the proposed validation rules in an informal ad-hoc call, let me know and I'll make it happen. 🎉🎉🎉 |
Copying those who participated in the last WG discussion according to the (AMAZING) WG agenda notes: @michaelstaib @leebyron @IvanGoncharov @mjmahone |
This is per the RFC 373 found here: graphql/graphql-spec#373
This is per the RFC 373 found here: graphql/graphql-spec#373
@mike-marcacci should unions also be allowed to implement interfaces for all the same reasons and in the exact same way? |
This fixes #295 by describing the way in which an interface may implement another interface. The rules are essentially identical to the rules governing implementation of an interface by an object. I'd be more than happy to champion this change (per the CONTRIBUTING.md process) so please direct any questions my way.
This is a pretty small change, but adds substantially to the expressiveness of GraphQL's type system.
If someone in the WG can give me a nod, I'll go ahead and implement it in graphql-js.
Thanks in advance!