From 7646db12ad78c966e88b73c0b7bd0ff93359179b Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 18 Dec 2023 20:01:57 +1100 Subject: [PATCH 1/4] Add method for unsafely running the server --- .../src/main/scala/caliban/quick/package.scala | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/adapters/quick/src/main/scala/caliban/quick/package.scala b/adapters/quick/src/main/scala/caliban/quick/package.scala index e635b44c1c..80056603d3 100644 --- a/adapters/quick/src/main/scala/caliban/quick/package.scala +++ b/adapters/quick/src/main/scala/caliban/quick/package.scala @@ -2,7 +2,7 @@ package caliban import caliban.Configurator.ExecutionConfiguration import zio.http._ -import zio.{ RIO, Trace, ZIO } +import zio.{ RIO, Trace, ZIO, ZIOAppDefault } package object quick { @@ -70,4 +70,20 @@ package object quick { gql.interpreter.map(QuickAdapter(_).configure(config).handler) } + implicit class GraphqlAnyServerOps[R](val gql: GraphQL[Any]) extends AnyVal { + + /** + * Convenience method for impurely running the server. + * + * Useful for scripts / demos / showing off Caliban to your colleagues etc. + */ + def unsafeRunServer( + port: Int = 8080, + apiPath: String = "/graphql", + graphiqlPath: Option[String] = Some("/graphiql"), + uploadPath: Option[String] = None + )(implicit trace: Trace): Unit = + ZIOAppDefault(gql.runServer(port, apiPath, graphiqlPath, uploadPath)).main(Array.empty) + } + } From 384307a9d5ba4c4e44a4191d2ad6fe2865043e46 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Mon, 18 Dec 2023 20:21:27 +1100 Subject: [PATCH 2/4] Remove [R] from GraphqlAnyServerOps --- adapters/quick/src/main/scala/caliban/quick/package.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapters/quick/src/main/scala/caliban/quick/package.scala b/adapters/quick/src/main/scala/caliban/quick/package.scala index 80056603d3..2ff5f39681 100644 --- a/adapters/quick/src/main/scala/caliban/quick/package.scala +++ b/adapters/quick/src/main/scala/caliban/quick/package.scala @@ -70,7 +70,7 @@ package object quick { gql.interpreter.map(QuickAdapter(_).configure(config).handler) } - implicit class GraphqlAnyServerOps[R](val gql: GraphQL[Any]) extends AnyVal { + implicit class GraphqlAnyServerOps(val gql: GraphQL[Any]) extends AnyVal { /** * Convenience method for impurely running the server. From 4e177b6f6e32d309c9637e361826ab4e5f0e76b8 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Fri, 22 Dec 2023 21:35:40 +1100 Subject: [PATCH 3/4] PR comments --- .../main/scala/caliban/quick/package.scala | 41 ++++++++++++++++--- core/src/main/scala/caliban/GraphQL.scala | 8 ++-- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/adapters/quick/src/main/scala/caliban/quick/package.scala b/adapters/quick/src/main/scala/caliban/quick/package.scala index 2ff5f39681..925c65183b 100644 --- a/adapters/quick/src/main/scala/caliban/quick/package.scala +++ b/adapters/quick/src/main/scala/caliban/quick/package.scala @@ -1,8 +1,8 @@ package caliban import caliban.Configurator.ExecutionConfiguration +import zio._ import zio.http._ -import zio.{ RIO, Trace, ZIO, ZIOAppDefault } package object quick { @@ -68,22 +68,51 @@ package object quick { trace: Trace ): ZIO[R, CalibanError.ValidationError, RequestHandler[R, Response]] = gql.interpreter.map(QuickAdapter(_).configure(config).handler) + + /** + * Unsafe API which allows running the server impurely + */ + def unsafe: UnsafeApi[R] = gql.interpreterEither.fold(throw _, new UnsafeApi(_)) } - implicit class GraphqlAnyServerOps(val gql: GraphQL[Any]) extends AnyVal { + final class UnsafeApi[R]( + interpreter: GraphQLInterpreter[R, Any], + executionConfig: ExecutionConfiguration = ExecutionConfiguration() + ) { /** * Convenience method for impurely running the server. * * Useful for scripts / demos / showing off Caliban to your colleagues etc. + * + * Note that in order to call this method, you need to provide all dependencies required by the GraphQL environment. You can do that by passing a `ZLayer` to [[provideLayer]]. */ - def unsafeRunServer( + def runServer( port: Int = 8080, apiPath: String = "/graphql", graphiqlPath: Option[String] = Some("/graphiql"), uploadPath: Option[String] = None - )(implicit trace: Trace): Unit = - ZIOAppDefault(gql.runServer(port, apiPath, graphiqlPath, uploadPath)).main(Array.empty) - } + )(implicit trace: Trace, ev: R =:= Any): Unit = { + implicit val tag: Tag[R] = ev.substituteContra(Tag[Any]) + val bootstrap = ev.substituteContra(ZLayer.empty) + val run: RIO[R, Nothing] = + QuickAdapter(interpreter) + .configure(executionConfig) + .runServer(port, apiPath, graphiqlPath, uploadPath) + ZIOApp(run, bootstrap).main(Array.empty) + } + + def provideLayer(layer: ZLayer[Any, Any, R]): UnsafeApi[Any] = + new UnsafeApi(interpreter.provideLayer(layer)) + + def provideSomeLayer[R0](layer: ZLayer[R0, Any, R])(implicit tag: Tag[R]): UnsafeApi[R0] = + new UnsafeApi(interpreter.provideSomeLayer(layer)) + + def configure(cfg: ExecutionConfiguration): UnsafeApi[R] = + new UnsafeApi(interpreter, cfg) + + def configureWith(cfg: ExecutionConfiguration => ExecutionConfiguration): UnsafeApi[R] = + new UnsafeApi(interpreter, cfg(executionConfig)) + } } diff --git a/core/src/main/scala/caliban/GraphQL.scala b/core/src/main/scala/caliban/GraphQL.scala index d888b5f84b..7de0f7f00d 100644 --- a/core/src/main/scala/caliban/GraphQL.scala +++ b/core/src/main/scala/caliban/GraphQL.scala @@ -58,12 +58,10 @@ trait GraphQL[-R] { self => * adding some middleware around the query execution. * Fails with a [[caliban.CalibanError.ValidationError]] if the schema is invalid. */ - final def interpreter(implicit trace: Trace): IO[ValidationError, GraphQLInterpreter[R, CalibanError]] = { - val i = cachedInterpreter - ZIO.fromEither(i) - } + final def interpreter(implicit trace: Trace): IO[ValidationError, GraphQLInterpreter[R, CalibanError]] = + ZIO.fromEither(interpreterEither) - private lazy val cachedInterpreter = + private[caliban] final lazy val interpreterEither = Validator.validateSchemaEither(schemaBuilder).map { schema => new GraphQLInterpreter[R, CalibanError] { private val rootType = From f24c56e8dfd6fb81dac3c66a0146db99277d2a71 Mon Sep 17 00:00:00 2001 From: Kyri Petrou Date: Fri, 22 Dec 2023 22:34:53 +1100 Subject: [PATCH 4/4] Can't have nice things with Scala 2.12 --- adapters/quick/src/main/scala/caliban/quick/package.scala | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/adapters/quick/src/main/scala/caliban/quick/package.scala b/adapters/quick/src/main/scala/caliban/quick/package.scala index 925c65183b..405a8dbea5 100644 --- a/adapters/quick/src/main/scala/caliban/quick/package.scala +++ b/adapters/quick/src/main/scala/caliban/quick/package.scala @@ -92,15 +92,13 @@ package object quick { apiPath: String = "/graphql", graphiqlPath: Option[String] = Some("/graphiql"), uploadPath: Option[String] = None - )(implicit trace: Trace, ev: R =:= Any): Unit = { - implicit val tag: Tag[R] = ev.substituteContra(Tag[Any]) - val bootstrap = ev.substituteContra(ZLayer.empty) + )(implicit trace: Trace, ev: Any =:= R): Unit = { val run: RIO[R, Nothing] = QuickAdapter(interpreter) .configure(executionConfig) .runServer(port, apiPath, graphiqlPath, uploadPath) - ZIOApp(run, bootstrap).main(Array.empty) + ZIOApp.fromZIO(run.asInstanceOf[RIO[Any, Nothing]]).main(Array.empty) } def provideLayer(layer: ZLayer[Any, Any, R]): UnsafeApi[Any] =