Skip to content

Commit

Permalink
feat: set correct content type when sending json
Browse files Browse the repository at this point in the history
  • Loading branch information
MoeQuadrat committed Jan 15, 2024
1 parent aaa2a44 commit 535d702
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package de.innfactory.smithy4play

import akka.util.ByteString
import cats.data.{EitherT, Kleisli}
import cats.data.{ EitherT, Kleisli }
import cats.implicits.toBifunctorOps
import de.innfactory.smithy4play
import de.innfactory.smithy4play.middleware.MiddlewareBase
import play.api.mvc._
import smithy4s.codecs.{PayloadError, StringAndBlobCodecs}
import smithy4s.http.{HttpEndpoint, HttpResponse, Metadata, PathParams}
import smithy4s.codecs.{ PayloadError, StringAndBlobCodecs }
import smithy4s.http.{ HttpEndpoint, HttpResponse, Metadata, PathParams }
import smithy4s.json.Json
import smithy4s.kinds.FunctorInterpreter
import smithy4s.schema.{CachedSchemaCompiler, Schema}
import smithy4s.xml.{Xml, XmlDecodeError}
import smithy4s.{Blob, Endpoint, Service}
import smithy4s.schema.{ CachedSchemaCompiler, Schema }
import smithy4s.xml.{ Xml, XmlDecodeError }
import smithy4s.{ Blob, Endpoint, Service }

import scala.concurrent.{ExecutionContext, Future}
import scala.concurrent.{ ExecutionContext, Future }

class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
_,
Expand Down Expand Up @@ -112,8 +112,8 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
EitherT(
Future {
val contentType = request.contentType.getOrElse("application/json")
val x = inputMetadataDecoder.decode(metadata)
val codecs = contentType match {
val x = inputMetadataDecoder.decode(metadata)
val codecs = contentType match {
case "application/json" => (blob: Blob) => Json.read(blob)(inputSchema)
case "application/xml" => (blob: Blob) => Xml.read(blob)(inputSchema)
case _ =>
Expand All @@ -124,8 +124,8 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[
.decode(blob)
}
codecs(Blob(request.body.asBytes().getOrElse(ByteString.empty).toByteBuffer)).leftMap {
case error: PayloadError => Smithy4PlayError(error.expected, smithy4play.Status(Map.empty, 400))
case error: XmlDecodeError => Smithy4PlayError(error.getMessage(), smithy4play.Status(Map.empty, 400))
case error: PayloadError => Smithy4PlayError(error.expected, smithy4play.Status(Map.empty, 500))
case error: XmlDecodeError => Smithy4PlayError(error.getMessage(), smithy4play.Status(Map.empty, 500))
}
}
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ package de.innfactory
package smithy4play
package client
import cats.implicits._
import smithy4s.codecs.{ PayloadError, StringAndBlobCodecs }
import smithy4s.http.{ CaseInsensitive, HttpEndpoint, Metadata, MetadataError }
import smithy4s.codecs.{PayloadError, StringAndBlobCodecs}
import smithy4s.http.{CaseInsensitive, HttpEndpoint, Metadata, MetadataError}
import smithy4s.json.Json
import smithy4s.xml.{ Xml, XmlDecodeError }
import smithy4s.{ Blob, Endpoint, Schema }
import smithy4s.json.Json.payloadCodecs
import smithy4s.schema.CachedSchemaCompiler
import smithy4s.xml.internals.XmlEncoder
import smithy4s.xml.{Xml, XmlDecodeError, XmlDocument}
import smithy4s.{Blob, Endpoint, Schema}

import scala.concurrent.{ ExecutionContext, Future }
import scala.concurrent.{ExecutionContext, Future}

private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O, SI, SO](
endpoint: Endpoint[Op, I, E, O, SI, SO],
Expand All @@ -33,12 +36,35 @@ private[smithy4play] class SmithyPlayClientEndpoint[Op[_, _, _, _, _], I, E, O,
val metadata = inputMetadataEncoder.encode(input)
val path = buildPath(metadata)
val headers = metadata.headers.map(x => (x._1.toString.toLowerCase, x._2))
val contentType = headers.getOrElse("content-type", Seq("application/json"))
val headersWithAuth = if (additionalHeaders.isDefined) headers.combine(additionalHeaders.get) else headers
val code = httpEndpoint.code
val response = client.send(httpEndpoint.method.toString, path, headersWithAuth, Json.writeBlob(input))
val response =
client.send(
httpEndpoint.method.toString,
path,
headersWithAuth.combine(Map("content-type" -> contentType)),
writeInputToBlob(input, contentType)
)
decodeResponse(response, code)
}

private def writeInputToBlob(input: I, contentType: Seq[String]): Blob = {
//TODO: Use Correct Encoders for Json and Xml and fix StringAndBlobCodecs
contentType match {
case Seq("application/json") => Json.writeBlob(input)
case Seq("application/xml") => Xml.write(input)
case _ =>
StringAndBlobCodecs.encoders
.fromSchema(inputSchema)
.map(_.encode(input))
.getOrElse({
logger.info("sending empty blob")
Blob.empty
})
}
}

private def decodeResponse(
response: Future[SmithyClientResponse],
expectedCode: Int
Expand Down

0 comments on commit 535d702

Please sign in to comment.