提取不同类型的关系

时间:2018-07-17 00:24:54

标签: scala graphql sangria

我具有以下结构:

ObjectX:

(id: UUID, name: String, title: String)

ObjectY(映射表):

(objectZId: UUID, objectXId: UUID) 

我正在尝试使用以下代码通过ObjectX来获取objectZId

val objectXByZ = RelationIds[ObjectY, UUID]("byObjectZId", c => Seq(c.objectZId))
implicit val objectXId = HasId[ObjectX, UUID](_.id)

val objectX = Fetcher.rel[GraphQLContext, ObjectX, ObjectY, UUID](
    (ctx: GraphQLContext, objectXIds: Seq[UUID]) =>
      ctx.app.service.Service.getObjectXByIds(objectXIds)(ctx.trace),
    (ctx: GraphQLContext, rels: RelationIds[XobjectX]) =>
      ctx.app.service.Service.getObjectYByX(rels(objectXByZ))(ctx.trace)
  )

,然后在此处使用它:

...

implicit val textX: ObjectType[GraphQLContext, ObjectX] = deriveObjectType(AddFields(
  Field(
    name = "objectX",
    fieldType = ListType(objectXType),
    resolve = c => TestFetchers.objectX.deferRelSeq(
      TestFetchers.objectXByZ, c.value.id
    )
)

...

但是出现错误:

[error]  found   : scala.concurrent.Future[Seq[com.fevo.coco.nut.models.ObjectX]]
[error]  required: scala.concurrent.Future[Seq[com.fevo.coco.nut.models.ObjectY]]
[error] Error occurred in an application involving default arguments.
[error]       ctx.app.service.Service.getObjectYByX(rels(objectXByZ))(ctx.trace)
[error]                                                    ^
[info] scala.concurrent.Future[Seq[com.fevo.coco.nut.models.ObjectX]] <: scala.concurrent.Future[Seq[com.fevo.coco.nut.models.ObjectY]]?
[info] false

根据此answer,我需要在提取程序中使用相同的类型,但是有没有办法使用不同的类型?


另一个问题是当我在提取程序中使用相同类型的数据时:

val objectX = Fetcher.rel[GraphQLContext, ObjectX, ObjectX, UUID](
  (ctx: GraphQLContext, objectXIds: Seq[UUID]) =>
    ctx.app.service.Service.getObjectXByIds(objectXIds)(ctx.trace),
  (ctx: GraphQLContext, rels: RelationIds[XobjectX]) =>
    ctx.app.service.Service.getObjectYByX(rels(objectXByZ))(ctx.trace)
  )

我没有得到任何结果(执行getObjectYByX,但没有执行)。

1 个答案:

答案 0 :(得分:1)

从数据库中加载关系数据时,

Fetcher支持中间数据结构。中间数据结构的类型是通过RelRes类型参数提供的。

在您的情况下,当您基于ObjectX从数据库中加载objectZId时,还需要告诉fetcher ObjectX的加载方式与其中一个(或几个)提供了objectZId个(因为您一次要加载多个关系)。这就是中间数据结构发挥作用的地方。就您而言,它可以像元组(ObjectY, ObjectX)一样简单:

val objectXByZ = Relation[ObjectX, (ObjectY, ObjectX), UUID]("byObjectZId", 
  intermediate ⇒ Seq(intermediate._1.objectZId),
  intermediate ⇒ intermediate._2)

val objectX = Fetcher.rel[GraphQLContext, ObjectX, (ObjectY, ObjectX), UUID](
  (ctx, objectXIds) ⇒ ctx.app.service.Service.getObjectXByIds(objectXIds)(ctx.trace),
  // returns list of tuples: Future[Seq[(ObjectY, ObjectX)]]
  (ctx, rels) ⇒ ctx.app.service.Service.getObjectXRelationsByZIds(rels(objectXByZ))(ctx.trace))