I'm curious if it's possible to define a case class's field as deferred while still using the deriveObjectType
macro to define everything else.
Here's an example. Dashboards contain a sequence of tabs:
case class Tab(id: Long, dashboardId: Long, name: String, order: Long)
case class Dashboard(id: Long, name: String, tabs: Seq[Tab])
I'm deferring resolution of the Dashboard.tabs
field using a Fetcher
, AND I'd like to continue using the deriveObjectType
macro (if possible). So here's how I've defined my ObjectType
s:
val TabType = deriveObjectType[Unit, Dashboard]()
val DashboardType = deriveObjectType[Unit, Dashboard](
AddFields(
fields =
Field(
name = "tabs",
fieldType = ListType(TabType),
resolve = ctx => {
TabsFetcher.fetcher.defer(ctx.value.id)
}
)
)
)
But, when I run the code, I get the following error:
sangria.schema.NonUniqueFieldsError: All fields within 'Dashboard' type should have unique names! Non-unique fields: 'tabs'.
If I remove the tabs
field from the Dashboard
case class the error goes away, but I lose some of the benefit of using a case class (especially in unit tests). And if I avoid the use of the deriveObjectType
macro (and define the Dashboard
's ObjectType
manually), then I lose the benefits of the macro (less boilerplate).
So, I'm curious if there's a better way, or another way, around this issue short of defining the DashboardType
without the use of the macro or removing the tags
field from the Dashboard
case class.
(I was hoping that there might be some sort of @GraphQLDeferred
annotation that I could apply to the Dashboard.tabs
field or something similar???)
You almost got it right. You need use ReplaceField
instead of AddFields
. Alternatively you can ExcludeFields("tabs")
and continue using AddFields
.