【问题标题】:Fetching relations with different types获取不同类型的关系
【发布时间】:2018-12-24 13:52:53
【问题描述】:

我有以下结构:

对象X:

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

ObjectY(映射表):

(objectZId: UUID, objectXId: UUID) 

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

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我需要在fetcher中使用相同的类型,但是有没有办法使用不同的类型?


另一个问题是当我在 fetcher 中使用相同类型时:

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 执行,但 getObjectXByIds 没有)。

【问题讨论】:

    标签: scala graphql sangria


    【解决方案1】:

    Fetchers 在您从数据库加载关系数据时支持中间数据结构。这个中间数据结构的类型是通过RelRes类型参数提供的。

    在您的情况下,当您从基于objectZId 的数据库中加载ObjectX 时,您还需要告诉fetcher 如何加载ObjectX 与一个(或多个)提供的objectZIds 相关(因为您一次加载多个关系)。这就是中间数据结构发挥作用的地方。在您的情况下,它可以像元组 (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))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-16
      • 2017-04-02
      • 2022-08-24
      • 2015-10-09
      • 1970-01-01
      • 2016-11-24
      • 2018-10-31
      • 2021-04-24
      相关资源
      最近更新 更多