Can not understand Fetcher.rel

谁都会走 提交于 2019-12-11 12:08:21

问题


I have the following case classes :

case class OrganizationId(value: Long) extends AnyVal
case class Organization(id: OrganizationId, name: String, iban: Option[String], bic: Option[String], updatedAt: LocalDateTime, insertedAt: LocalDateTime)
case class EventId(value: Long) extends AnyVal
case class Event(
  id: EventId, organizationId: OrganizationId, name: String, description: Option[String], updatedAt: LocalDateTime, insertedAt: LocalDateTime
)

They represent a simple schema where an Organization can have multiple Event.
Basically I'm trying to define two graphql queries : one that list all organizations with its nested events and the second query is the other way : list all events with its corresponding organization. In both cases I'd like to avoid N+1 queries. I think it's possible for both queries to be run in 2 SQL queries each.
To solve this issue I had a look at the high level Fetch API and specifically the Fetcher.rel part. If I understand correctly I'll need to define a relation like this : val byOrganization = Relation[Event, OrganizationId]("byOrganization", e => Seq(e.organizationId)) and then a Fetcher.rel, but I can't make it work.
Here is my full code for my schema definition :

class GraphqlSchema {
  val byOrganization = Relation[Event, OrganizationId]("byOrganization", e => Seq(e.organizationId))
  val organizationsFetcher = Fetcher(
    (context: GraphqlContext, ids: Seq[OrganizationId]) => {
      context.organizations.all(ids)
    }
  )(HasId(_.id))
  val eventsFetcher = Fetcher.rel[GraphqlContext, Event, Organization, EventId](
    (context: GraphqlContext, ids: Seq[EventId]) => {
      context.events.all(ids)
    },
    (context: GraphqlContext, ids: RelationIds[Event]) => {
      ???
    }
  )(HasId(_.id))

  val deferredResolver = DeferredResolver.fetchers(organizationsFetcher, eventsFetcher)

  implicit val OrganizationIdType = CustomScalarTypes.organiaztionIdType
  implicit val EventIdType = CustomScalarTypes.eventIdType
  implicit val UuidType = CustomScalarTypes.uuidType
  implicit val LocalDateTimeType = CustomScalarTypes.localDateTimeType
  implicit val UserType = deriveObjectType[GraphqlContext, User]()
  implicit val OrganizationType: ObjectType[GraphqlContext, Organization] = deriveObjectType[GraphqlContext, Organization](
    AddFields(
      Field("events", ListType(EventType), resolve = (ctx) => {
        eventsFetcher.deferRelSeq(byOrganization, ctx.value.id)
      })
    )
  )
  implicit val EventType: ObjectType[GraphqlContext, Event] = deriveObjectType[GraphqlContext, Event](
    AddFields(
      Field("organization", OptionType(OrganizationType), resolve = (ctx) => {
        organizationsFetcher.deferOpt(ctx.value.organizationId)
      })
    )
  )

  val QueryType = deriveContextObjectType[GraphqlContext, Query, Unit](_.query)
  val MutationType = deriveContextObjectType[GraphqlContext, Mutation, Unit](_.mutation)

  val schema = Schema(QueryType, Some(MutationType))
}

It doesn't compile, I get this error: ound :

[error] /Users/matthieu/Code/runevent/runevent/scala/api/src/main/scala/com/runevent/api/graphql/GraphqlSchema.scala:39:35: type mismatch;
[error]  found   : sangria.execution.deferred.Relation[com.runevent.database.models.Event,com.runevent.database.models.Event,com.runevent.database.models.OrganizationId]
[error]  required: sangria.execution.deferred.Relation[com.runevent.database.models.Event,com.runevent.database.models.Organization,?]
[error]         eventsFetcher.deferRelSeq(byOrganization, ctx.value.id)
[error]                                   ^
[error] one error found
[error] (Compile / compileIncremental) Compilation failed

Could you help me find out what I'm missing?


回答1:


I believe eventsFetcher should be defined like this (so both Res and RelRes type parameters are of the same type Event):

val eventsFetcher = Fetcher.rel[GraphqlContext, Event, Event, EventId](
  (context: GraphqlContext, ids: Seq[EventId]) => {
    context.events.all(ids)
  },
  (context: GraphqlContext, ids: RelationIds[Event]) => {
    context.events.loadByOrganizationIds(ids(byOrganization))
  }
)(HasId(_.id))


来源:https://stackoverflow.com/questions/49833732/can-not-understand-fetcher-rel

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!