Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make jsoniter a required dependency and use it for enc/dec in tapir adapters #2341

Merged
merged 6 commits into from
Sep 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import sttp.capabilities.akka.AkkaStreams
import sttp.capabilities.akka.AkkaStreams.Pipe
import sttp.model.StatusCode
import sttp.monad.{ FutureMonad, MonadError }
import sttp.tapir.Codec.JsonCodec
import sttp.tapir.PublicEndpoint
import sttp.tapir.model.ServerRequest
import sttp.tapir.server.ServerEndpoint
Expand All @@ -34,9 +33,7 @@ class AkkaHttpAdapter private (private val options: AkkaHttpServerOptions)(impli

def makeHttpUploadService[R, E](interpreter: HttpUploadInterpreter[R, E])(implicit
runtime: Runtime[R],
materializer: Materializer,
requestCodec: JsonCodec[GraphQLRequest],
mapCodec: JsonCodec[Map[String, Seq[String]]]
materializer: Materializer
): Route =
akkaInterpreter.toRoute(interpreter.serverEndpointFuture[AkkaStreams](AkkaStreams)(runtime))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,9 @@ import akka.http.scaladsl.Http
import akka.http.scaladsl.server.Directives._
import akka.stream.Materializer
import caliban.interop.tapir.TestData.sampleCharacters
import caliban.interop.tapir.{
FakeAuthorizationInterceptor,
HttpInterpreter,
HttpUploadInterpreter,
TapirAdapterSpec,
TestApi,
TestService,
WebSocketInterpreter
}
import caliban.interop.tapir._
import caliban.uploads.Uploads
import sttp.client3.UriContext
import sttp.tapir.json.circe._
import zio._
import zio.test._

Expand All @@ -40,7 +31,7 @@ object AkkaHttpAdapterSpec extends ZIOSpecDefault {
HttpInterpreter(interpreter).intercept(FakeAuthorizationInterceptor.bearer[TestService & Uploads])
)(runtime, mat)
} ~ path("upload" / "graphql") {
adapter.makeHttpUploadService(HttpUploadInterpreter(interpreter))(runtime, mat, implicitly, implicitly)
adapter.makeHttpUploadService(HttpUploadInterpreter(interpreter))(runtime, mat)
} ~ path("ws" / "graphql") {
adapter.makeWebSocketService(WebSocketInterpreter(interpreter))(runtime, mat)
}
Expand Down
10 changes: 2 additions & 8 deletions adapters/http4s/src/main/scala/caliban/Http4sAdapter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import org.http4s.server.websocket.WebSocketBuilder2
import sttp.capabilities.WebSockets
import sttp.capabilities.fs2.Fs2Streams
import sttp.capabilities.zio.ZioStreams
import sttp.tapir.Codec.JsonCodec
import sttp.tapir.Endpoint
import sttp.tapir.integ.cats.effect.CatsMonadError
import sttp.tapir.server.ServerEndpoint
Expand All @@ -37,16 +36,11 @@ object Http4sAdapter {
Http4sServerInterpreter().toRoutes(endpointsF)
}

def makeHttpUploadService[R, E](interpreter: HttpUploadInterpreter[R, E])(implicit
requestCodec: JsonCodec[GraphQLRequest],
mapCodec: JsonCodec[Map[String, Seq[String]]]
): HttpRoutes[RIO[R, *]] =
def makeHttpUploadService[R, E](interpreter: HttpUploadInterpreter[R, E]): HttpRoutes[RIO[R, *]] =
ZHttp4sServerInterpreter().from(interpreter.serverEndpoint[R, ZioStreams](ZioStreams)).toRoutes

def makeHttpUploadServiceF[F[_]: Async, R, E](interpreter: HttpUploadInterpreter[R, E])(implicit
interop: ToEffect[F, R],
requestCodec: JsonCodec[GraphQLRequest],
mapCodec: JsonCodec[Map[String, Seq[String]]]
interop: ToEffect[F, R]
): HttpRoutes[F] = {
val endpoint = interpreter.serverEndpoint[R, Fs2Streams[F]](Fs2Streams[F])
val endpointF = convertHttpEndpointToF[F, R](endpoint)
Expand Down
45 changes: 8 additions & 37 deletions adapters/http4s/src/test/scala/caliban/Http4sAdapterSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,11 @@ import caliban.interop.tapir.TestData.sampleCharacters
import caliban.interop.tapir._
import caliban.uploads.Uploads
import com.comcast.ip4s._
import com.github.plokhotnyuk.jsoniter_scala.core._
import com.github.plokhotnyuk.jsoniter_scala.macros._
import fs2.io.net.Network
import org.http4s.ember.server.EmberServerBuilder
import org.http4s.server.Router
import org.http4s.server.middleware.CORS
import sttp.client3.UriContext
import sttp.tapir.Codec.JsonCodec
import zio._
import zio.interop.catz._
import zio.test.{ Live, ZIOSpecDefault }
Expand All @@ -27,13 +24,7 @@ object Http4sAdapterSpec extends ZIOSpecDefault {

private val envLayer = TestService.make(sampleCharacters) ++ Uploads.empty

private def apiLayer(implicit
requestCodec: JsonCodec[GraphQLRequest],
mapCodec: JsonCodec[Map[String, Seq[String]]],
responseValueCodec: JsonCodec[ResponseValue],
wsInputCodec: JsonCodec[GraphQLWSInput],
wsOutputCodec: JsonCodec[GraphQLWSOutput]
) = envLayer >>> ZLayer.scoped {
private def apiLayer = envLayer >>> ZLayer.scoped {
for {
interpreter <- TestApi.api.interpreter
_ <- EmberServerBuilder
Expand Down Expand Up @@ -65,33 +56,13 @@ object Http4sAdapterSpec extends ZIOSpecDefault {
}

override def spec = suite("Http4sAdapterSpec") {
val suites =
List(
Some({
import sttp.tapir.json.circe._
TapirAdapterSpec
.makeSuite(
"circe codec",
uri"http://localhost:8087/api/graphql",
uploadUri = Some(uri"http://localhost:8087/upload/graphql"),
wsUri = Some(uri"ws://localhost:8087/ws/graphql")
)
.provideLayerShared(apiLayer)
}),
Some({
import sttp.tapir.json.jsoniter._
implicit val mapCodec: JsonValueCodec[Map[String, Seq[String]]] = JsonCodecMaker.make

TapirAdapterSpec
.makeSuite(
"jsoniter codec",
uri"http://localhost:8087/api/graphql",
uploadUri = Some(uri"http://localhost:8087/upload/graphql"),
wsUri = Some(uri"ws://localhost:8087/ws/graphql")
)
.provideLayerShared(apiLayer)
})
TapirAdapterSpec
.makeSuite(
"jsoniter codec",
uri"http://localhost:8087/api/graphql",
uploadUri = Some(uri"http://localhost:8087/upload/graphql"),
wsUri = Some(uri"ws://localhost:8087/ws/graphql")
)
ZIO.succeed(suites.flatten)
.provideLayerShared(apiLayer)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import sttp.capabilities.pekko.PekkoStreams
import sttp.capabilities.pekko.PekkoStreams.Pipe
import sttp.model.StatusCode
import sttp.monad.{ FutureMonad, MonadError }
import sttp.tapir.Codec.JsonCodec
import sttp.tapir.PublicEndpoint
import sttp.tapir.model.ServerRequest
import sttp.tapir.server.ServerEndpoint
Expand All @@ -34,9 +33,7 @@ class PekkoHttpAdapter private (val options: PekkoHttpServerOptions)(implicit ec

def makeHttpUploadService[R, E](interpreter: HttpUploadInterpreter[R, E])(implicit
runtime: Runtime[R],
materializer: Materializer,
requestCodec: JsonCodec[GraphQLRequest],
mapCodec: JsonCodec[Map[String, Seq[String]]]
materializer: Materializer
): Route =
pekkoInterpreter.toRoute(interpreter.serverEndpointFuture[PekkoStreams](PekkoStreams)(runtime))

Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
package caliban

import caliban.interop.tapir.TestData.sampleCharacters
import caliban.interop.tapir._
import caliban.uploads.Uploads
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.http.scaladsl.Http
import org.apache.pekko.http.scaladsl.server.Directives._
import org.apache.pekko.stream.Materializer
import caliban.interop.tapir.TestData.sampleCharacters
import caliban.interop.tapir.{
FakeAuthorizationInterceptor,
HttpInterpreter,
HttpUploadInterpreter,
TapirAdapterSpec,
TestApi,
TestService,
WebSocketInterpreter
}
import caliban.uploads.Uploads
import sttp.client3.UriContext
import sttp.tapir.json.circe._
import zio._
import zio.test._

Expand All @@ -40,7 +31,7 @@ object PekkoHttpAdapterSpec extends ZIOSpecDefault {
HttpInterpreter(interpreter).intercept(FakeAuthorizationInterceptor.bearer[TestService & Uploads])
)(runtime, mat)
} ~ path("upload" / "graphql") {
adapter.makeHttpUploadService(HttpUploadInterpreter(interpreter))(runtime, mat, implicitly, implicitly)
adapter.makeHttpUploadService(HttpUploadInterpreter(interpreter))(runtime, mat)
} ~ path("ws" / "graphql") {
adapter.makeWebSocketService(WebSocketInterpreter(interpreter))(runtime, mat)
}
Expand Down
5 changes: 1 addition & 4 deletions adapters/play/src/main/scala/caliban/PlayAdapter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import sttp.capabilities.pekko.PekkoStreams
import sttp.capabilities.pekko.PekkoStreams.Pipe
import sttp.model.StatusCode
import sttp.monad.FutureMonad
import sttp.tapir.Codec.JsonCodec
import sttp.tapir.PublicEndpoint
import sttp.tapir.model.ServerRequest
import sttp.tapir.server.ServerEndpoint
Expand All @@ -32,9 +31,7 @@ class PlayAdapter private (private val options: Option[PlayServerOptions]) {

def makeHttpUploadService[R, E](interpreter: HttpUploadInterpreter[R, E])(implicit
runtime: Runtime[R],
materializer: Materializer,
requestCodec: JsonCodec[GraphQLRequest],
mapCodec: JsonCodec[Map[String, Seq[String]]]
materializer: Materializer
): Routes =
playInterpreter.toRoutes(interpreter.serverEndpointFuture[PekkoStreams](PekkoStreams)(runtime))

Expand Down
14 changes: 2 additions & 12 deletions adapters/play/src/test/scala/caliban/PlayAdapterSpec.scala
Original file line number Diff line number Diff line change
@@ -1,15 +1,7 @@
package caliban

import caliban.interop.tapir.TestData.sampleCharacters
import caliban.interop.tapir.{
FakeAuthorizationInterceptor,
HttpInterpreter,
HttpUploadInterpreter,
TapirAdapterSpec,
TestApi,
TestService,
WebSocketInterpreter
}
import caliban.interop.tapir._
import caliban.uploads.Uploads
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.stream.Materializer
Expand All @@ -24,8 +16,6 @@ import zio.test.{ Live, ZIOSpecDefault }
import scala.language.postfixOps

object PlayAdapterSpec extends ZIOSpecDefault {
import sttp.tapir.json.play._

private val envLayer = TestService.make(sampleCharacters) ++ Uploads.empty

private val apiLayer = envLayer >>> ZLayer.scoped {
Expand All @@ -44,7 +34,7 @@ object PlayAdapterSpec extends ZIOSpecDefault {
.apply(req)
case req @ POST(p"/upload/graphql") =>
PlayAdapter
.makeHttpUploadService(HttpUploadInterpreter(interpreter))(runtime, mat, implicitly, implicitly)
.makeHttpUploadService(HttpUploadInterpreter(interpreter))(runtime, mat)
.apply(req)
case req @ GET(p"/ws/graphql") =>
PlayAdapter.makeWebSocketService(WebSocketInterpreter(interpreter))(runtime, mat).apply(req)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import caliban.uploads.{ FileMeta, GraphQLUploadRequest, Uploads }
import caliban.wrappers.Caching
import caliban.ws.Protocol
import com.github.plokhotnyuk.jsoniter_scala.core._
import com.github.plokhotnyuk.jsoniter_scala.macros.JsonCodecMaker
import zio._
import zio.http.ChannelEvent.UserEvent.HandshakeComplete
import zio.http._
Expand All @@ -24,6 +23,7 @@ final private class QuickRequestHandler[R](
wsConfig: quick.WebSocketConfig[R]
) {
import QuickRequestHandler._
import ValueJsoniter.stringListCodec

def configure(config: ExecutionConfiguration)(implicit trace: Trace): QuickRequestHandler[R] =
new QuickRequestHandler[R](
Expand Down Expand Up @@ -311,6 +311,4 @@ object QuickRequestHandler {
}

private implicit val responseCodec: JsonValueCodec[ResponseValue] = ValueJsoniter.responseValueCodec

private implicit val stringListCodec: JsonValueCodec[Map[String, List[String]]] = JsonCodecMaker.make
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import scala.language.postfixOps

object QuickAdapterSpec extends ZIOSpecDefault {
import caliban.quick._
import sttp.tapir.json.jsoniter._

private val envLayer = TestService.make(sampleCharacters) ++ Uploads.empty

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package caliban.json

import caliban.Value._
import caliban.interop.circe.json.GraphQLResponseCirce.{ graphQLResponseEncoder => circeEncoder }
import caliban.interop.zio.GraphQLResponseZioJson.{ graphQLResponseEncoder => zioEncoder }
import caliban.{ GraphQLResponse, ResponseValue }
import com.github.plokhotnyuk.jsoniter_scala.core._
import org.openjdk.jmh.annotations._
Expand Down Expand Up @@ -47,13 +45,7 @@ class JsonEncodingBenchmark {

private val testData: GraphQLResponse[Any] = GraphQLResponse(mkObject(5, 20), Nil, None)

@Benchmark
def circe(): Unit = circeEncoder(testData).noSpaces

@Benchmark
def jsoniter(): Unit = writeToString(testData)

@Benchmark
def zio(): Unit = zioEncoder.encodeJson(testData)

}
Loading
Loading