Joshua Clark
Joshua Clark

Reputation: 15

Creating relationships over two joins with GraphQL in Hasura (i.e. skipping over a nested relationship)

I have a query that resolves what "product" objects a user currently owns. The user has transactions, these transactions are linked to a particular product, and so we resolve the query as below, which reflects the database structure and schema.

Assume the schema is as below:

type User {
  id: int
  name: string
  transactions: [Transaction]
}

type Transaction {
  id: int
  user_id: int
  product_id: int
  product_sku: int
  amount: number
  purchase_date: datetime
  user: User
  product: Product
}

type Product {
  id: int
  name: string
  transactions: [Transactions]
}

Then the query to resolve purchased products would be:

query purchased_products {
  user {
    transactions {
      product {
        id
      }
    }
  }
}

I would like to simplify this query for the front end, who doesn't need to know about the transactions. They would like to answer the question "what products does each user own?". I would like to add some kind of relationship or query to User that can directly answer this question, extending the User schema to include:

type User {
  id: int
  name: string
  transactions: [Transaction]
  products_owned: [Product]
}

query purchased_products_simple {
  user {
    products_owned {
      id
    }
  }
}

I'd like to do this without using an external remote schema or resolver.

How would I go about doing this? Am I breaking any assumptions of graphql doing so?

Thanks!

Upvotes: 0

Views: 469

Answers (1)

Jesse Carter
Jesse Carter

Reputation: 21157

The best way to accomplish this with Hasura is to create either a view or a computed function that hides this complexity/implementation detail from consumers of your API.

Eg:

CREATE VIEW user_products AS SELECT u.id, p.* FROM users u 
    JOIN transactions t ON t.user_id = u.id 
    JOIN products p ON t.product_id = p.id

Once the view has been created, you can track it in Hasura and then join the relationship manually between the users table and the new view by linking on user_id

Then you'd be able to query it something like this:

query {
  user {
    id
    name
    products {
       name
    }
  }
}

Upvotes: 1

Related Questions