下面是我当前如何处理延迟字段参数的示例。
一个Parent
类包含一个延迟Page
的Child
对象。子项的分页参数在children
字段上定义。我需要能够将分页参数连同父 ID 一起传递给 deferred Fetcher
,所以我将它们与父 ID 一起捆绑在一个临时DeferredChildInput
对象中,然后将它们传递给Fetcher
. 相应DeferredChildResult
的返回查询的结果 (the Page[Child]
) 和 the DeferredChildInput
(use in the HasId
)。
问题是,有没有更好的方法将字段参数和父 id 传递给 deferred Fetcher
?
case class Page[T](
data: Seq[T],
pageNumber: Int,
pageSize: Int,
totalRecords: Long
)
case class Parent(
id: Long,
children: Page[Children] // this field is deferred
)
case class Child(
id: Long
parentId: Long
)
// the field's query parameters
case class DeferredChildInput(
parentId: Long,
pageNumber: Int,
pageSize: Int
)
// used to temporarily hold the result of the deferred resolution
case class DeferredChildResult(
input: DeferredChildInput // this is used to resolve the HasId check
page: Page[Child] // this is what we really want
)
trait ChildService {
def getChildrenByParentId(
parentId: Long,
pageNumber: Int,
pageSize: Int
): Page[Child]
}
val childFetcher: Fetcher[MyContext, DeferredChildResult, DeferredChildResult, DeferredChildInput] = Fetcher {
(ctx: MyContext, inputs: Seq[DeferredChildInput]) =>
val futures = inputs.map { input =>
ctx.childService.getChildrenByParentId(
input.parentId,
input.pageNumber,
input.pageSize
).map { childPage =>
DeferredChildResult(input, childPage)
}
}
Future.sequence {
futures
}
}(HasId(_.input))
}
val ChildObjectType = derivedObjectType[Unit, Child]()
val ParentObjectType = deriveObjectType[Unit, Parent](
ReplaceField(
fieldName = "children",
field = Field(
name = "children",
fieldType = PageType(childObjectType),
arguments = List(
Argument(
name = "pageNumber",
argumentType = IntType
), Argument(
name = "pageSize",
argumentType = IntType,
)
),
resolve = ctx => {
// bundle the field/query parameters into a single input object
val input = DeferredChildInput(
parentId = ctx.value.id,
pageNumber = ctx.args[Int]("pageNumber"),
pageSize = ctx.args[Int]("pageSize")
)
DeferredValue(childFetcher.defer(input)).map { results =>
results.page
}
}
)
)
)