2

I'm using Netflix DGS to wire up my data fetchers and loaders. So far I've been using my own entity classes with loaders and everything is working fine.

Relationship

img

Entity classes

My entity relationship is one-to-N as in above diagram. My Expense entity looks like this. This is the direct mapping of my db table.

data class Expense(
   val id: Int? = 0,
   val amount: Int? = null,
   val remarks: String? = null,
   val isIncome: Boolean? = false,
   val acNumber: Int? = 0
)

So, when I try to get account info in the graphql schema, I use loader and feed the acNumber field to it. And it solved the N+1 gracefully and the nested object is never touched when selection doesn't mention account field.

Fetcher & Loader

@DgsData(parentType = "Query", field = "expenses")
fun expenses(): List<Expense> {
   return expenseRepository.findAll().toList()
}

Fetcher returns list of expense entities. GraphQL makes use of below relationship defined in Account Fetcher to get the Account using a loader.

`@DgsData(parentType = "Expense", field = "account")
fun getAccounts(dfe: DgsDataFetchingEnvironment): CompletableFuture<Account> {
   val dataLoader: DataLoader<Int, Account> =
        dfe.getDataLoader(AccountsDataLoader::class.java)
   val source = dfe.getSource<Expense>()
   val acNumber = source.acNumber
   return dataLoader.load(acNumber)
}

Schema

type Expense {
    id: ID
    remarks: String
    amount: Int
    isIncome: Boolean
    account: Account
}

type Account {
    acNumber: ID,
    nickName: String,
    balance: Int
}

Codegen

Later I decided to use DGS codegen to create models for me. The generated Expense class looks like this.

public data class Expense(
  `@JsonProperty("id")
  public val id: String? = null,
  `@JsonProperty("remarks")
  public val remarks: String? = null,
  `@JsonProperty("amount")
  public val amount: Int? = null,
  `@JsonProperty("isIncome")
  public val isIncome: Boolean? = null,
  `@JsonProperty("account")
  public val account: Account? = null. <--- account object itself present here
) 

Since the generated class doesn't have acNumber field in it, I lack the ability to use loaders when I use code-gen.

Am I missing anything?

How can I make use of code-gen and use Loaders?

Mahendran
  • 2,719
  • 5
  • 28
  • 50
  • I'm struggling with the same problem right now. Did you find any solution yet? To me `generateInterfaces` sounded promising: "Generate interfaces for data classes. This is useful if you would like to extend the generated POJOs for more context and use interfaces instead of the data classes in your data fetchers.". However, setting `generateInterfaces = true` still seems to generate data classes for data types... – Marvin Oct 05 '21 at 16:09
  • You can potentially use the internal classes to pass the id and not expose it like described here https://netflix.github.io/dgs/advanced/context-passing/ – Gerhard Jun 07 '23 at 16:35

0 Answers0