Skip to content

Commit

Permalink
refactor: using codedecider to choose correct codec from contenttype
Browse files Browse the repository at this point in the history
  • Loading branch information
MoeQuadrat committed Jan 18, 2024
1 parent a8413a9 commit b5cf9c4
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 46 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package de.innfactory.smithy4play

import smithy4s.codecs.{ PayloadDecoder, PayloadEncoder }
import smithy4s.schema.CachedSchemaCompiler
import smithy4s.xml.Xml

object CodecDecider {

def encoder(
contentType: Seq[String]
)(implicit encoder: CachedSchemaCompiler[PayloadEncoder]): CachedSchemaCompiler[PayloadEncoder] =
contentType match {
case Seq("application/json") => encoder
case Seq("application/xml") => Xml.encoders
case _ =>
CachedSchemaCompiler
.getOrElse(smithy4s.codecs.StringAndBlobCodecs.encoders, encoder)
}

def decoder(
contentType: Seq[String]
)(implicit decoder: CachedSchemaCompiler[PayloadDecoder]): CachedSchemaCompiler[PayloadDecoder] =
contentType match {
case Seq("application/json") => decoder
case Seq("application/xml") => Xml.decoders
case _ =>
CachedSchemaCompiler
.getOrElse(smithy4s.codecs.StringAndBlobCodecs.decoders, decoder)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
private implicit val inputSchema: Schema[I] = endpoint.input
private implicit val outputSchema: Schema[O] = endpoint.output

private val inputMetadataDecoder: Metadata.Decoder[I] =
Metadata.Decoder.fromSchema(inputSchema)
// private val inputMetadataDecoder: Metadata.Decoder[I] =
// Metadata.Decoder.fromSchema(inputSchema)

private val outputMetadataEncoder: Metadata.Encoder[O] =
Metadata.Encoder.fromSchema(outputSchema)

private val jsonEncoders: CachedSchemaCompiler[PayloadEncoder] = payloadCodecs.encoders
private val jsonDecoders: CachedSchemaCompiler[PayloadDecoder] = payloadCodecs.decoders
private implicit val jsonEncoders: CachedSchemaCompiler[PayloadEncoder] = payloadCodecs.encoders
private implicit val jsonDecoders: CachedSchemaCompiler[PayloadDecoder] = payloadCodecs.decoders

def handler(v1: RequestHeader): Handler =
httpEndpoint.map { httpEp =>
Expand Down Expand Up @@ -93,12 +93,7 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
(k.toString.toLowerCase, v.mkString(""))
}
val contentType = outputHeaders.getOrElse("content-type", "application/json")

val codec = contentType match {
case "application/xml" => Xml.encoders
case "application/json" => jsonEncoders
case _ => CachedSchemaCompiler.getOrElse(smithy4s.codecs.StringAndBlobCodecs.encoders, jsonEncoders)
}
val codec = CodecDecider.encoder(Seq(contentType))
logger.debug(s"[SmithyPlayEndpoint] Headers: ${outputHeaders.mkString("|")}")
EndpointResult(codec.fromSchema(outputSchema).encode(o), status = smithy4play.Status(outputHeaders, statusCode))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.innfactory
package smithy4play
package client

import cats.implicits._
import smithy4s.codecs.{ BlobEncoder, PayloadDecoder, PayloadEncoder }
import smithy4s.http._
Expand All @@ -21,15 +22,15 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
client: RequestClient
)(implicit executionContext: ExecutionContext) {

private implicit val inputSchema: Schema[I] = endpoint.input
private implicit val outputSchema: Schema[O] = endpoint.output
val jsonEncoders: CachedSchemaCompiler[PayloadEncoder] = payloadCodecs.encoders
val jsonDecoders: CachedSchemaCompiler[PayloadDecoder] = payloadCodecs.decoders
private implicit val inputSchema: Schema[I] = endpoint.input
private implicit val outputSchema: Schema[O] = endpoint.output
private implicit val jsonEncoders: CachedSchemaCompiler[PayloadEncoder] = payloadCodecs.encoders
private implicit val jsonDecoders: CachedSchemaCompiler[PayloadDecoder] = payloadCodecs.decoders

private val inputMetadataEncoder =
private val inputMetadataEncoder =
Metadata.Encoder.fromSchema(inputSchema)
private val outputMetadataDecoder =
Metadata.Decoder.fromSchema(outputSchema)
// private val outputMetadataDecoder =
// Metadata.Decoder.fromSchema(outputSchema)

def send(
): ClientResponse[O] = {
Expand All @@ -49,23 +50,9 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
decodeResponse(response, code)
}

private def metadataWriter[Body] = { (req: HttpRequest[Body], meta: Metadata) =>
val oldUri = req.uri
val newUri =
oldUri.copy(queryParams = oldUri.queryParams ++ meta.query)
req.addHeaders(meta.headers).copy(uri = newUri)
}

private def writeInputToBlob(input: I, contentType: Seq[String]): Blob = {
val x: CachedSchemaCompiler[BlobEncoder] = contentType match {
case Seq("application/json") => jsonEncoders
case Seq("application/xml") => Xml.encoders
case _ =>
CachedSchemaCompiler
.getOrElse(smithy4s.codecs.StringAndBlobCodecs.encoders, jsonEncoders)

}
x.fromSchema(inputSchema).encode(input)
val codecs: CachedSchemaCompiler[BlobEncoder] = CodecDecider.encoder(contentType)
codecs.fromSchema(inputSchema).encode(input)
}

private def decodeResponse(
Expand All @@ -79,26 +66,19 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
else handleError(res)
} yield output

def handleSuccess(response: HttpResponse[Blob]): ClientResponse[O] = {
val headers = response.headers.map(x => (x._1, x._2))
val contentType = headers.getOrElse(CaseInsensitive("content-type"), Seq("application/json"))
val codec = contentType match {
case "application/json" :: _ => jsonDecoders
case "application/xml" :: _ => Xml.decoders
case _ =>
CachedSchemaCompiler
.getOrElse(smithy4s.codecs.StringAndBlobCodecs.decoders, jsonDecoders)
}
Future(
def handleSuccess(response: HttpResponse[Blob]): ClientResponse[O] =
Future {
val headers = response.headers.map(x => (x._1, x._2))
val contentType = headers.getOrElse(CaseInsensitive("content-type"), Seq("application/json"))
val codec = CodecDecider.decoder(contentType)
codec
.fromSchema(outputSchema)
.decode(response.body)
.map(o => HttpResponse(response.statusCode, headers, o))
.leftMap { error =>
SmithyPlayClientEndpointErrorResponse(error.expected.getBytes, response.statusCode)
}
)
}
}
private def handleError(response: HttpResponse[Blob]): ClientResponse[O] = Future(
Left {
SmithyPlayClientEndpointErrorResponse(
Expand Down

0 comments on commit b5cf9c4

Please sign in to comment.