From f5c1be39ea8b8dc521d271c9558a8cf2eafa9670 Mon Sep 17 00:00:00 2001 From: fokot Date: Mon, 2 Dec 2019 20:18:08 +0100 Subject: [PATCH 1/2] graphiql --- examples/README.md | 2 + examples/src/main/resources/graphiql.html | 156 ++++++++++++++++++ .../src/main/scala/caliban/ExampleApp.scala | 20 ++- 3 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 examples/src/main/resources/graphiql.html diff --git a/examples/README.md b/examples/README.md index 0b87ed098..bdf570269 100644 --- a/examples/README.md +++ b/examples/README.md @@ -9,3 +9,5 @@ libraryDependencies ++= Seq( "com.github.ghostdogpr" %% "caliban-cats" % "0.3.0" ) ``` + +Run `ExampleApp` and open [http://localhost:8088/graphiql](http://localhost:8088/graphiql) diff --git a/examples/src/main/resources/graphiql.html b/examples/src/main/resources/graphiql.html new file mode 100644 index 000000000..7e35f08ca --- /dev/null +++ b/examples/src/main/resources/graphiql.html @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + +
Loading...
+ + + + diff --git a/examples/src/main/scala/caliban/ExampleApp.scala b/examples/src/main/scala/caliban/ExampleApp.scala index fd0a58f58..a138a1578 100644 --- a/examples/src/main/scala/caliban/ExampleApp.scala +++ b/examples/src/main/scala/caliban/ExampleApp.scala @@ -2,18 +2,23 @@ package caliban import caliban.ExampleData._ import caliban.GraphQL._ -import caliban.schema.Annotations.{ GQLDeprecated, GQLDescription } +import caliban.schema.Annotations.{GQLDeprecated, GQLDescription} import caliban.schema.GenericSchema +import cats.data.{Kleisli, OptionT} +import org.http4s.{EntityEncoder, HttpApp, HttpRoutes, Response, Status} import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder import org.http4s.server.middleware.CORS import zio._ +import zio.blocking.Blocking import zio.clock.Clock -import zio.console.{ putStrLn, Console } +import zio.console.{Console, putStrLn} import zio.interop.catz._ import zio.stream.ZStream +import scala.io.Source + object ExampleApp extends CatsApp with GenericSchema[Console with Clock] { case class Queries( @@ -25,13 +30,17 @@ object ExampleApp extends CatsApp with GenericSchema[Console with Clock] { case class Mutations(deleteCharacter: CharacterArgs => URIO[Console, Boolean]) case class Subscriptions(characterDeleted: ZStream[Console, Nothing, String]) - type ExampleTask[A] = RIO[Console with Clock, A] + type ExampleTask[A] = RIO[Console with Clock with Blocking, A] implicit val roleSchema = gen[Role] implicit val characterSchema = gen[Character] implicit val characterArgsSchema = gen[CharacterArgs] implicit val charactersArgsSchema = gen[CharactersArgs] + def staticResource(path: String): ExampleTask[Response[ExampleTask]] = + blocking.effectBlocking(Source.fromResource(path).getLines().mkString("\n")) + .map(content => Response[ExampleTask](Status.Ok, body = EntityEncoder[ExampleTask, String](EntityEncoder.stringEncoder).toEntity(content).body)) + override def run(args: List[String]): ZIO[ZEnv, Nothing, Int] = (for { service <- ExampleService.make(sampleCharacters) @@ -48,9 +57,10 @@ object ExampleApp extends CatsApp with GenericSchema[Console with Clock] { _ <- BlazeServerBuilder[ExampleTask] .bindHttp(8088, "localhost") .withHttpApp( - Router( + Router[ExampleTask]( "/api/graphql" -> CORS(Http4sAdapter.makeRestService(interpreter)), - "/ws/graphql" -> CORS(Http4sAdapter.makeWebSocketService(interpreter)) + "/ws/graphql" -> CORS(Http4sAdapter.makeWebSocketService(interpreter)), + "/graphiql" -> Kleisli.liftF(OptionT.liftF(staticResource("graphiql.html"))) ).orNotFound ) .resource From 1b4a021355b778d93105cd785648c21f5b3cf58e Mon Sep 17 00:00:00 2001 From: fokot Date: Tue, 3 Dec 2019 11:36:21 +0100 Subject: [PATCH 2/2] graphiql with StaticFile.fromResource --- .../src/main/scala/caliban/ExampleApp.scala | 47 ++++++++++--------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/examples/src/main/scala/caliban/ExampleApp.scala b/examples/src/main/scala/caliban/ExampleApp.scala index a138a1578..ece6382ad 100644 --- a/examples/src/main/scala/caliban/ExampleApp.scala +++ b/examples/src/main/scala/caliban/ExampleApp.scala @@ -4,8 +4,9 @@ import caliban.ExampleData._ import caliban.GraphQL._ import caliban.schema.Annotations.{GQLDeprecated, GQLDescription} import caliban.schema.GenericSchema -import cats.data.{Kleisli, OptionT} -import org.http4s.{EntityEncoder, HttpApp, HttpRoutes, Response, Status} +import cats.data.Kleisli +import cats.effect.Blocker +import org.http4s.StaticFile import org.http4s.implicits._ import org.http4s.server.Router import org.http4s.server.blaze.BlazeServerBuilder @@ -17,8 +18,6 @@ import zio.console.{Console, putStrLn} import zio.interop.catz._ import zio.stream.ZStream -import scala.io.Source - object ExampleApp extends CatsApp with GenericSchema[Console with Clock] { case class Queries( @@ -30,17 +29,13 @@ object ExampleApp extends CatsApp with GenericSchema[Console with Clock] { case class Mutations(deleteCharacter: CharacterArgs => URIO[Console, Boolean]) case class Subscriptions(characterDeleted: ZStream[Console, Nothing, String]) - type ExampleTask[A] = RIO[Console with Clock with Blocking, A] + type ExampleTask[A] = RIO[Console with Clock, A] - implicit val roleSchema = gen[Role] - implicit val characterSchema = gen[Character] - implicit val characterArgsSchema = gen[CharacterArgs] + implicit val roleSchema = gen[Role] + implicit val characterSchema = gen[Character] + implicit val characterArgsSchema = gen[CharacterArgs] implicit val charactersArgsSchema = gen[CharactersArgs] - def staticResource(path: String): ExampleTask[Response[ExampleTask]] = - blocking.effectBlocking(Source.fromResource(path).getLines().mkString("\n")) - .map(content => Response[ExampleTask](Status.Ok, body = EntityEncoder[ExampleTask, String](EntityEncoder.stringEncoder).toEntity(content).body)) - override def run(args: List[String]): ZIO[ZEnv, Nothing, Int] = (for { service <- ExampleService.make(sampleCharacters) @@ -54,17 +49,23 @@ object ExampleApp extends CatsApp with GenericSchema[Console with Clock] { Subscriptions(service.deletedEvents) ) ) + blocker <- ZIO + .accessM[Blocking](_.blocking.blockingExecutor.map(_.asEC)) + .map(Blocker.liftExecutionContext) _ <- BlazeServerBuilder[ExampleTask] - .bindHttp(8088, "localhost") - .withHttpApp( - Router[ExampleTask]( - "/api/graphql" -> CORS(Http4sAdapter.makeRestService(interpreter)), - "/ws/graphql" -> CORS(Http4sAdapter.makeWebSocketService(interpreter)), - "/graphiql" -> Kleisli.liftF(OptionT.liftF(staticResource("graphiql.html"))) - ).orNotFound - ) - .resource - .toManaged - .useForever + .bindHttp(8088, "localhost") + .withHttpApp( + Router[ExampleTask]( + "/api/graphql" -> CORS(Http4sAdapter.makeRestService(interpreter)), + "/ws/graphql" -> CORS( + Http4sAdapter.makeWebSocketService(interpreter) + ), + "/graphiql" -> Kleisli + .liftF(StaticFile.fromResource("/graphiql.html", blocker, None)) + ).orNotFound + ) + .resource + .toManaged + .useForever } yield 0).catchAll(err => putStrLn(err.toString).as(1)) }