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

How to handle both directions of one-to-many relation in federated graph #1480

Open
biwecka opened this issue Mar 4, 2024 · 0 comments
Open
Labels
question Further information is requested

Comments

@biwecka
Copy link

biwecka commented Mar 4, 2024

Hi,
I'm just starting out with GraphQL and want to implement a basic example of two federated services. For that I defined a the following data structure:

  • a Tenant has an id and a name
    • a Tenant has many Users (the ones with the tenant's id in user.tenant_id)
  • a User has an id, first_name, last_name and a tenant_id
    • a User belongs to a Tenant (the tenant with an id of user.tenant_id)

I only got one direction of the relation to work (User belongs to a Tenant) and I don't know how to implement the other direction. My code looks like this

// users-service.rs

/// User
#[derive(async_graphql::SimpleObject, Clone)]
#[graphql(complex)]
pub struct User {
    pub id: i32,
    pub first_name: String,
    pub last_name: String,
    pub tenant_id: i32,
}

#[async_graphql::ComplexObject]
impl User {
    async fn tenant(&self) -> Tenant {
        Tenant { id: self.tenant_id }
    }
}

/// Tenant (partially)
#[derive(async_graphql::SimpleObject, Clone)]
pub struct Tenant {
    #[graphql(external)]
    pub id: i32,
}

/// Query
pub struct Query {
    users: Vec<User>,
}

#[async_graphql::Object]
impl Query {
    async fn users(&self) -> Vec<User> {
        self.users.clone()
    }
}
// tenants-service.rs

/// Tenant
#[derive(async_graphql::SimpleObject, Clone)]
pub struct Tenant {
    pub id: i32,
    pub name: String,
}

/// Query
pub struct Query {
    tenants: Vec<Tenant>
}

#[async_graphql::Object]
impl Query {
    async fn tenants(&self) -> Vec<Tenant> {
        self.tenants.clone()
    }

    #[graphql(entity)]
    async fn find_tenant_by_id(&self, id: async_graphql::ID) -> Tenant {
        self.tenants
            .iter()
            .find(|t| id.to_string().eq(&t.id.to_string()))
            .unwrap()
            .clone()
    }
}

As far as I understand GraphQL, for a query like this query Example { users { tenant { ... } } } all users are fetched first and then the tenant related to every user is fetched by calling the function find_tenant_by_id of the users-service.
For the other direction of this relation there must be a way of fetching all users by their tenant_id but I couldn't find documentation/example covering this case nor do I really understand what the SQL should look like for this relation.

I'm very grateful for any kind of help. Thank you very much in advance :)

@biwecka biwecka added the question Further information is requested label Mar 4, 2024
@biwecka biwecka changed the title How to fetch both directions of one-to-many relation in federated graph How to handle both directions of one-to-many relation in federated graph Mar 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

1 participant