Skip to content

Feature Request: Allow interfaces to resolve to other interfaces #3253

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

Closed
SleeplessOne1917 opened this issue Aug 28, 2021 · 3 comments
Closed

Comments

@SleeplessOne1917
Copy link

I originally raised this in Apollo Server and was told that it's actually implemented here.

Suppose I have the following schema:

interface Node {
    id: ID!
}

interface Product implements Node {
    id: ID!
    price: Float!
}

type Food implements Product & Node {
    id: ID!
    price: Float!
    expirationDate: String
}

I'd like to set up my resolvers for Node and Product like so:

const Node = {
    __resolveType(node) {
        if (node.price)
            return 'Product';
        return null;
    }
}

const Product = {
    __resolveType(product) {
         if (product.expirationDate)
            return 'Food'
        return null;
    }
}

In the current implementation of graphql-js, the Node resolver will result in an error because it resolves to Product, an interface type. This is despite the fact that Prodcut goes on to resolve to a concrete type. To make this work, the developer has to add logic for resolving Food to both the Product and Node resolver. This introduces code duplication, which becomes worse as more implementations of Product are added, and especially if other interfaces that implement Node and have own implementations are introduced.

I propose that it would be easier for the developer to maintain their resolvers if resolution of interface types could be chained. For the Node resolver in the example, that would mean when it resolves to Product, it goes on to use Product's __resolveType to resolve to the concrete type Food.

@gwenker
Copy link

gwenker commented Jan 14, 2022

I think i have a similar issue so i add here my case :

Suppose I have the following schema:

enum MessageType {
  message
  action
}

interface Message {
  type : MessageType!
}

type Action implements Message {
  type : MessageType!
  action : String
}

type Text implements Message {
  type : MessageType!
  text : String
}

type Document {
  id: ID!
}

union TransactionData =
   Message
  | Document

enum TransactionType {
  message
  document
  action
}
  
type Transaction {
  id: ID!
  type: TransactionType!
  data: TransactionData!
}

I can't use interface in union even i have a __resolveType defined for Action and Text in MessageResolver.
I have to define union like that :

union TransactionData =
   Action
  | Text
  | Document

and can't use Message resolver.

@yaacovCR
Copy link
Contributor

@gwenker => I think your comments are unrelated to a resolveType hiearchy, but is related to discussion at graphql/graphql-spec#711

yaacovCR added a commit to yaacovCR/graphql-js that referenced this issue Jun 1, 2022
= The child interfaces must eventually resolve to a runtime object type.
= Interface cycles raise a runtime error.

implements: graphql#3253
yaacovCR added a commit to yaacovCR/graphql-js that referenced this issue Jun 1, 2022
= The child interfaces must eventually resolve to a runtime object type.
= Interface cycles raise a runtime error.

implements: graphql#3253
yaacovCR added a commit to yaacovCR/graphql-js that referenced this issue Jun 1, 2022
= The child interfaces must eventually resolve to a runtime object type.
= Interface cycles raise a runtime error.

implements: graphql#3253
yaacovCR added a commit to yaacovCR/graphql-js that referenced this issue Jun 1, 2022
= The child interfaces must eventually resolve to a runtime object type.
= Interface cycles raise a runtime error.

implements: graphql#3253
yaacovCR added a commit to yaacovCR/graphql-spec that referenced this issue Jun 10, 2022
This formalizes the proprosed feature within `graphql-js` whereby the internal method provided by JavaScript for runtime type resolution is allowed to return an intermediate interface.

See:
Issue: graphql/graphql-js#3253
PR: graphql/graphql-js#3599

@IvanGoncharov [suggested](graphql/graphql-js#3599 (review)) that this would require a spec change. Alternatively, perhaps the recursion [should be considered to be a feature of  the internal system](graphql/graphql-js#3599 (comment)) itself, possibly limited to JavaScript-like implementations.

This PR provides some potential spec text, were a spec change to be considered necessary.
@yaacovCR
Copy link
Contributor

yaacovCR commented Nov 4, 2024

This is doable in user land, but if graphql/graphql-spec#960 or something like it lands, we should implement it within the reference implementation. Until then, closing this issue in the name of general clean up.

@yaacovCR yaacovCR closed this as completed Nov 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants