ghostdogpr / caliban

Functional GraphQL library for Scala

Home Page:https://ghostdogpr.github.io/caliban/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

RequestInterceptor is limiting changes on resource axis

aleksandr-vin opened this issue · comments

Current type declares idempotence for ZIO resource:

trait RequestInterceptor[-R] { self =>
  def apply[R1 <: R, A](request: ServerRequest)(e: ZIO[R1, TapirResponse, A]): ZIO[R1, TapirResponse, A]
  ...
}

while it can be beneficial to remove that limit to:

  • be able to provideSomeLayer, or
  • declare more resource dependency

Sort of:

trait RequestInterceptor[-R] { self =>
  def apply[R2, R1 <: R, A](request: ServerRequest)(e: ZIO[R1, TapirResponse, A]): ZIO[R2, TapirResponse, A]
  ...

As for now the provideSomeLayer requires a dirty lie:

  override def apply[R1 <: R, A](
        request: ServerRequest
      )(e: ZIO[R1, TapirAdapter.TapirResponse, A]
      ): ZIO[R1, TapirAdapter.TapirResponse, A] =
      for {
        userInfo <- authenticate(request)
        ne <- e.provideSomeLayer[R1](ZLayer.succeed(userInfo)) // TODO: WTF!!!
      } yield ne
  }

where in fact ne does not need UserInfo in it's R.

How would this compose though? R2 would still need to have some relationship with R in order to line up with what the interpreter expects:

  def makeHttpService[R, E](
    interpreter: GraphQLInterpreter[R, E],
    skipValidation: Boolean = false,
    enableIntrospection: Boolean = true,
    queryExecution: QueryExecution = QueryExecution.Parallel,
    requestInterceptor: RequestInterceptor[R] = RequestInterceptor.empty
  )(implicit
    requestCodec: JsonCodec[GraphQLRequest],
    responseCodec: JsonCodec[GraphQLResponse[E]]
  ): List[ServerEndpoint[Any, RIO[R, *]]] 

I think smth. like:

  def makeHttpService[RIN, R, E](
    interpreter: GraphQLInterpreter[RIN, E],
    skipValidation: Boolean = false,
    enableIntrospection: Boolean = true,
    queryExecution: QueryExecution = QueryExecution.Parallel,
    requestInterceptor: RequestInterceptor[RIN, R] = RequestInterceptor.empty
  )(implicit
    requestCodec: JsonCodec[GraphQLRequest],
    responseCodec: JsonCodec[GraphQLResponse[E]]
  ): List[ServerEndpoint[Any, RIO[R, *]]] = {
    ...

with

trait RequestInterceptor[-R, ROUT] { self =>
  def apply[R1 <: R, A](request: ServerRequest)(e: ZIO[R1, TapirResponse, A]): ZIO[ROUT, TapirResponse, A]
  ...