Spring JPA and GraphQL

1.2k Views Asked by At

Given the following graph

type Movie {
   name: String!
   actors: [Actor!]!
}

type Actor {
   name: String!
   awards: [Award!]!
}

type Award {
   name: String!
   date: String!
}

type Query {
   movies(): [Movie!]!
}

I'd like to be able to run the following three types of queries as efficiently as possible:

Query 1:

query { 
  movies {
    actors {
      rewards {
        name
      }
    }
  }
} 

Query 2:

query {
  movies {
    name
  }
}

Query 3:

query {
  movies {
    name
    actors {
      rewards {
        date
      }
    }
  }
}

Please note, these are not the only queries I will be running, but I'd like my code to be able to pick the optimal path "automatically".

The rest of my business logic is using JPA. The data comes from three respective tables, that can have up to 40 columns each.


I am not looking for code examples, but rather for a high-level structure describing different elements of architecture with respective responsibilities.

1

There are 1 best solutions below

2
On

Without further context and details of your DB schema, what I could do is to just to give you the general advice that you need to aware of.

Most probably you would encounter N+1 loading performance issue when executing a query that contains several levels of related objects and these objects are stored in different DB tables.

Generally there are 2 ways to solve it :

  1. Use Dataloader . Its idea is to defer the actual loading time of each object to a moment that multiple objects can be batched loaded together by a single SQL. It also provides the caching feature to further improve the loading performance for the same query request.

  2. Use "look ahead pattern" (Refer this for an example). Its ideas is that when you resolve the parent object , you can look ahead to analyse the GraphQL query that you need to execute require to include others related children or not. If yes , you can then use the JOIN SQL to query the parent object together with their children such that when you resolve its children later , they are already fetched and you do not need to fetch them again.

Also, if the objects in your domain can contain infinity number in theory , you should consider to implement pagination behaviour for the query in order to restrict the maximum number of the objects that it can return.