Skip to content

Commit

Permalink
Http4s simple integration (#100)
Browse files Browse the repository at this point in the history
* Http4s simple integration

* Http4s simple integration scalafmt fix

* added executeRequestF

* moved code to executeToJson
  • Loading branch information
fokot authored and ghostdogpr committed Dec 2, 2019
1 parent cbf1496 commit 25d4b96
Showing 1 changed file with 34 additions and 4 deletions.
38 changes: 34 additions & 4 deletions http4s/src/main/scala/caliban/Http4sAdapter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package caliban

import caliban.ResponseValue._
import caliban.Value._
import cats.data.OptionT
import cats.data.{ Kleisli, OptionT }
import cats.effect.Effect
import cats.effect.syntax.all._
import cats.~>
Expand All @@ -27,21 +27,38 @@ object Http4sAdapter {
): URIO[R, GraphQLResponse[E]] =
interpreter.execute(query.query, query.operationName, query.variables.getOrElse(Map()))

private def executeToJson[R, Q, M, S, E](
interpreter: GraphQL[R, Q, M, S, E],
query: GraphQLRequest
): URIO[R, Json] =
execute(interpreter, query)
.foldCause(cause => GraphQLResponse(NullValue, cause.defects).asJson, _.asJson)

def makeRestService[R, Q, M, S, E](interpreter: GraphQL[R, Q, M, S, E]): HttpRoutes[RIO[R, *]] = {
object dsl extends Http4sDsl[RIO[R, *]]
import dsl._

HttpRoutes.of[RIO[R, *]] {
case req @ POST -> Root =>
for {
query <- req.attemptAs[GraphQLRequest].value.absolve
result <- execute(interpreter, query)
.foldCause(cause => GraphQLResponse(NullValue, cause.defects).asJson, _.asJson)
query <- req.attemptAs[GraphQLRequest].value.absolve
result <- executeToJson(interpreter, query)
response <- Ok(result)
} yield response
}
}

def executeRequest[R0, R, Q, M, S, E](interpreter: GraphQL[R, Q, M, S, E], provideEnv: R0 => R): HttpApp[RIO[R0, *]] =
Kleisli { req =>
object dsl extends Http4sDsl[RIO[R0, *]]
import dsl._
for {
query <- req.attemptAs[GraphQLRequest].value.absolve
result <- executeToJson(interpreter, query).provideSome[R0](provideEnv)
response <- Ok(result)
} yield response
}

def makeWebSocketService[R, Q, M, S, E](interpreter: GraphQL[R, Q, M, S, E]): HttpRoutes[RIO[R, *]] = {

object dsl extends Http4sDsl[RIO[R, *]]
Expand Down Expand Up @@ -142,6 +159,15 @@ object Http4sAdapter {
.dimap((req: Request[F]) => req.mapK(toTask))((res: Response[Task]) => res.mapK(toF))
}

private def wrapApp[F[_]: Effect](app: HttpApp[Task])(implicit runtime: Runtime[Any]): HttpApp[F] = {
val toF: Task ~> F = λ[Task ~> F](_.toIO.to[F])
val toTask: F ~> Task = λ[F ~> Task](_.toIO.to[Task])

app
.mapK(toF)
.dimap((req: Request[F]) => req.mapK(toTask))((res: Response[Task]) => res.mapK(toF))
}

def makeWebSocketServiceF[F[_], Q, M, S, E](
interpreter: GraphQL[Any, Q, M, S, E]
)(implicit F: Effect[F], runtime: Runtime[Any]): HttpRoutes[F] =
Expand All @@ -152,4 +178,8 @@ object Http4sAdapter {
)(implicit F: Effect[F], runtime: Runtime[Any]): HttpRoutes[F] =
wrapRoute(makeRestService[Any, Q, M, S, E](interpreter))

def executeRequestF[F[_], Q, M, S, E](
interpreter: GraphQL[Any, Q, M, S, E]
)(implicit F: Effect[F], runtime: Runtime[Any]): HttpApp[F] =
wrapApp(executeRequest[Any, Any, Q, M, S, E](interpreter, identity))
}

0 comments on commit 25d4b96

Please sign in to comment.