Graphql Inner and Left Join

Graphql Inner and Left Join


1

We are using Apollo Router + Netflix DGS to build federated graphql services. Suppose that we have a common relational database right now for books and authors, but want to move towards a microservice architecture, where books and authors are stored separately in their own database.

Suppose that I have the following graphql schema:

type Author {
  name: String
  books: [Book]
}

type Book {
  title: String!
}

type Query {
  getAuthors(name: String!, title: String) {
    authors: [Authors]
  }
}

Here are two query scenarios / results:

Scenario 1 – returns multiple authors named Lewis and list of books (0:N) associated with each author named Lewis

query {
  getAuthors("Lewis") {
    name
    books
  }
}

Scenario 2

query {
  getAuthors(name: "Lewis", title: "Cronicles of Narnia") {
    name
    books
  }
}

In a single relational database where books and authors are stored together, my query could be:

Single Relational DB Query

select * from authors a inner join books b on a.id = b.author_id where name = "Lewis" and title = "Cronicles of Narnia";

select * from authors a left join books b where a.id = b.author_id and name = "Lewis" and title = "Cronicles of Narnia";

In my future, microservice, multi-database where books and authors are stored seperately, my query could be:

Microservice / Multi-database Query:

select * from authors where name = "Lewis";

select * from books where title = "Cronicles of Narnia";

  • Then allow Apollo or Netflix DSG to join at the application level.

Question 1

What should my Scenario 2 graphql query return? I actually need to support both options below in different scenarios, so is there a different way to write the query for each?

  • Option 1) just one author named Lewis and just one book named "Cronicles of Narnia"? (this is the INNER JOIN)

  • Option 2) a list of authors named Lewis and, where linked to a specific "Lewis", append the book(s) named "Cronicles of Narnia"? (this is the LEFT JOIN)

Question 2

In my future, multi-database scenario, how would graphql (Apollo, Netflix DSG) behave? Is it more like Option 1 or Option 2? As mentioned, would need to support both.

Question 3

I’ve also seen a similar query written like this. Do these queries have different meanings? Is this widely supported?

query {
  getAuthors(name: "Lewis") {
    name
    books (title: "Cronicles of Narnia")
  }
}

Thanks!

Justin

New contributor

Justin W is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

1

  • A filter that sits at the "authors" level implies that you are filtering the authors, not the books that they've written. So Scenario 2 would return all authors named "Lewis" that have written a book named "Narnia". It would also return all books that this author has written. That's why IMO Option 3 is the way to go – you'd find all authors named Lewis, and then filter their books to only include ones named "Narnia". Under the hood the engine can optimize the DB queries, so you shouldn't worry about joins when designing the API. Never worked with DGS though, this is only my GQL knowledge.

    – Avius

    1 hour ago


Load 3 more related questions


Show fewer related questions

0



Leave a Reply

Your email address will not be published. Required fields are marked *