Skip to content
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

Interface not working as expected with imlp #1161

Closed
IvanRodriCalleja opened this issue Apr 6, 2023 · 3 comments
Closed

Interface not working as expected with imlp #1161

IvanRodriCalleja opened this issue Apr 6, 2023 · 3 comments
Assignees
Labels
bug Something isn't working k::api Related to API (application interface)
Milestone

Comments

@IvanRodriCalleja
Copy link

IvanRodriCalleja commented Apr 6, 2023

Hi,

I don't know if the problems is a misunderstood from my side, if i am using interface wrong or if it is an issue. The problem is related to using an interface when i implement the interface to my models (via impl not struct) the definition of the interface is not in the result schema i have to define it in the implementation but then it uses the interface method.

Let me explain it better, i am doing an initial POC implementing the relay schema (at the moment not conections) to see how to have relay support in Juniper so i created the following:

//node.rs
#[graphql_interface(for = [Faction, Ship])]
pub trait Node {
    fn id(&self) -> ID;
}

//faction.rs
pub struct Faction {
    pub id: String,
    pub name: String,
}

#[graphql_interface]
impl Node for Faction {
    fn id(&self) -> ID {
        ID::new(&self.id)
    }
}

#[graphql_object(impl = NodeValue)]
impl Faction {
    fn name(&self) -> &str {
        &self.name
    }
}


//ship.rs
pub struct Ship {
    pub id: String,
    pub name: String,
}

#[graphql_interface]
impl Node for Ship {
    fn id(&self) -> ID {
        ID::new(&self.id)
    }
}

#[graphql_object(impl = NodeValue)]
impl Ship {
    fn name(&self) -> &str {
        &self.name
    }
}

I created a Node interface with an id function and each model has the Node implementation for the interface, the result of this schema is:

type Ship implements Node {
  name: String!
}

type Faction implements Node {
  name: String!
}

interface Node {
  id: ID!
}

From what i understand this is not correct and the schema result should be:

type Ship implements Node {
  id: ID!
  name: String!
}

type Faction implements Node {
  id: ID!
  name: String!
}

interface Node {
  id: ID!
}

If i want to have this definition i should have the following rust implementation:

//node.rs
#[graphql_interface(for = [Faction, Ship])]
pub trait Node {
    fn id(&self) -> ID;
}

//faction.rs
pub struct Faction {
    pub id: String,
    pub name: String,
}

#[graphql_interface]
impl Node for Faction {
    fn id(&self) -> String {
        ID::new(&self.id)
    }
}

#[graphql_object(impl = NodeValue)]
impl Faction {
    fn id(&self) -> String {
        ID::new(&self.id)
    }
    
    fn name(&self) -> &str {
        &self.name
    }
}


//ship.rs
pub struct Ship {
    pub id: String,
    pub name: String,
}

#[graphql_interface]
impl Node for Ship {
    fn id(&self) -> String {
        ID::new(&self.id)
    }
}

#[graphql_object(impl = NodeValue)]
impl Ship {
    fn id(&self) -> String {
        ID::new(&self.id)
    }
    
    fn name(&self) -> &str {
        &self.name
    }
}

As you can see i added the id function resolver to each of the implementation so now it is duplicated but the schema is how i want it to be.

When i consume any of the model throw the NodeValue for examlpe for NodeValue::Ship() (like the node(id: "") query) the id is resolved by the impl Node for Ship interface but if i have a simple relation like Vec<Ship> this is resolved by ´impl Ship´ function but i expect to always use the id function from impl Node for Ship.

So my question is, is it the expected behaviour and i understood wrong? is the implementation wrong on my side? do you think it is a bug?

@IvanRodriCalleja
Copy link
Author

I created a reproduction repository just in case it is easier https://github.com/IvanRodriCalleja/juniper_interface_issue

@ilslv
Copy link
Member

ilslv commented Apr 7, 2023

@IvanRodriCalleja this is a known issue on 0.15.x that is already fixed on master. There is no plans to backport this fix to 0.15.x, as master Interfaces are completely redesigned.

@ilslv ilslv self-assigned this Apr 7, 2023
@ilslv ilslv added k::api Related to API (application interface) bug Something isn't working labels Apr 7, 2023
@ilslv ilslv added this to the 0.16.0 milestone Apr 7, 2023
@ilslv ilslv closed this as completed Apr 7, 2023
@IvanRodriCalleja
Copy link
Author

Works perfect!!

Thanks to point to the issues, i didn't find them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working k::api Related to API (application interface)
Projects
None yet
Development

No branches or pull requests

2 participants