Smithy4s integration for Caliban.
In sbt:
libraryDependencies ++= Seq("org.polyvariant" %% "smithy4s-caliban" % version)
In scala-cli:
//> using lib "org.polyvariant::smithy4s-caliban:version"
Follow the quickstart steps.
For example:
$version: "2"
namespace hello
service HelloService {
operations: [GetHello]
}
@readonly
operation GetHello {
input := {
@required
name: String
}
output := {
@required
greeting: String
}
}
Make sure you can generate Smithy4s code for that spec.
Implement the trait generated by Smithy4s:
import hello._
import cats.effect._
val impl: HelloService[IO] = new HelloService[IO] {
override def getHello(name: String): IO[GetHelloOutput] =
IO.println("hello, " + name).as(GetHelloOutput("hello, " + name))
}
This is what the library will allow you to do: convert that service implementation to a GraphQL root.
import org.polyvariant.smithy4scaliban._
import caliban.GraphQL
val api: Resource[IO, GraphQL[Any]] = CalibanGraphQLInterpreter.server(impl)
This returns a Resource because it requires (and creates) a Dispatcher
.
Now, the last part - you have to connect this GraphQL instance to a server. How you do it is up to you, but http4s is recommended. Here's a full example (requires caliban-http4s
, tapir-json-circe
and http4s-ember-server
):
import caliban.Http4sAdapter
import caliban.CalibanError
import caliban.interop.tapir.HttpInterpreter
import sttp.tapir.json.circe._
import caliban.interop.cats.implicits._
import org.http4s.ember.server.EmberServerBuilder
val server: IO[Nothing] = api.evalMap { serverApi =>
implicit val rt: zio.Runtime[Any] = zio.Runtime.default
serverApi
.interpreterAsync[IO]
.map { interp =>
Http4sAdapter.makeHttpServiceF[IO, Any, CalibanError](HttpInterpreter(interp))
}
}
.flatMap { routes =>
EmberServerBuilder.default[IO].withHttpApp(routes.orNotFound).build
}.useForever
This will launch a server on localhost:8080
running your Smithy spec as a GraphQL API.