diff --git a/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala b/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala index 64b682f5..ff24b1f4 100644 --- a/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala +++ b/smithy4play/src/main/scala/de/innfactory/smithy4play/SmithyPlayEndpoint.scala @@ -27,10 +27,11 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[_, _ private val endpointHints = endpoint.hints private val serviceContentType: String = serviceHints.toMimeType - private implicit val inputSchema: Schema[I] = endpoint.input - private implicit val outputSchema: Schema[O] = endpoint.output - - def handler(v1: RequestHeader): Handler = + private implicit val inputSchema: Schema[I] = endpoint.input + private implicit val outputSchema: Schema[O] = endpoint.output + private val outputMetadataEncoder: Metadata.Encoder[O] = + Metadata.Encoder.fromSchema(outputSchema) + def handler(v1: RequestHeader): Handler = httpEndpoint.map { httpEp => Action.async(parse.raw) { implicit request => if (request.body.size > 0 && request.body.asBytes().isEmpty) { @@ -63,9 +64,13 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[_, _ private def mapToEndpointResult( statusCode: Int - )(output: O)(implicit defaultContentType: ContentType): HttpResponse[Blob] = + )(output: O)(implicit defaultContentType: ContentType): HttpResponse[Blob] = { + val outputContentType = outputMetadataEncoder.encode(output).headers.get(CaseInsensitive("content-type")) match { + case Some(value) => value + case None => Seq(defaultContentType.value) + } codecDecider - .httpMessageEncoder(Seq(defaultContentType.value)) + .httpMessageEncoder(outputContentType) .fromSchema(outputSchema) .write( HttpResponse( @@ -75,6 +80,7 @@ class SmithyPlayEndpoint[Alg[_[_, _, _, _, _]], F[_] <: ContextRoute[_], Op[_, _ ), output ) + } private def getPathParams( v1: RequestHeader, diff --git a/smithy4playTest/app/controller/TestController.scala b/smithy4playTest/app/controller/TestController.scala index 20ec6951..6c51b118 100644 --- a/smithy4playTest/app/controller/TestController.scala +++ b/smithy4playTest/app/controller/TestController.scala @@ -4,7 +4,7 @@ import cats.data.{ EitherT, Kleisli } import controller.models.TestError import de.innfactory.smithy4play.{ AutoRouting, ContextRoute, ContextRouteError } import play.api.mvc.ControllerComponents -import smithy4s.Blob +import smithy4s.{ Blob, Document } import testDefinitions.test._ import javax.inject.{ Inject, Singleton } @@ -67,4 +67,8 @@ class TestController @Inject() (implicit override def testWithOtherStatusCode(): ContextRoute[Unit] = Kleisli { rc => EitherT.rightT[Future, ContextRouteError](()) } + + override def testWithJsonInputAndBlobOutput(body: JsonInput): ContextRoute[BlobResponse] = Kleisli { rc => + EitherT.rightT[Future, ContextRouteError](BlobResponse(Blob(body.message), "image/png")) + } } diff --git a/smithy4playTest/test/TestControllerTest.scala b/smithy4playTest/test/TestControllerTest.scala index 7bdb8c9b..f03ea09c 100644 --- a/smithy4playTest/test/TestControllerTest.scala +++ b/smithy4playTest/test/TestControllerTest.scala @@ -11,9 +11,10 @@ import play.api.libs.json.{ Json, OWrites } import play.api.mvc.Result import play.api.test.FakeRequest import play.api.test.Helpers._ -import smithy4s.Blob +import smithy4s.{ Blob, Document } import smithy4s.http.CaseInsensitive import testDefinitions.test.{ + JsonInput, SimpleTestResponse, TestControllerServiceGen, TestRequestBody, @@ -167,6 +168,14 @@ class TestControllerTest extends TestBase { pngAsBytes mustBe result.body.body } + "route with json body to Blob Endpoint" in { + val testString = "StringToBeParsedCorrectly" + val result = genericClient.testWithJsonInputAndBlobOutput(JsonInput(testString)).awaitRight(global, 5.hours) + + result.statusCode mustBe 200 + testString mustBe result.body.body.toUTF8String + } + "route to Auth Test" in { val result = genericClient.testAuth().awaitLeft diff --git a/smithy4playTest/testSpecs/TestController.smithy b/smithy4playTest/testSpecs/TestController.smithy index 066ffd2c..2de835da 100644 --- a/smithy4playTest/testSpecs/TestController.smithy +++ b/smithy4playTest/testSpecs/TestController.smithy @@ -14,6 +14,7 @@ service TestControllerService { Health TestWithBlob TestWithQuery + TestWithJsonInputAndBlobOutput TestThatReturnsError TestAuth TestWithOtherStatusCode @@ -27,6 +28,17 @@ service TestControllerService { operation TestWithOtherStatusCode { } +@auth([]) +@http(method: "POST", uri: "/jsoninput/bloboutput", code: 200) +operation TestWithJsonInputAndBlobOutput { + input:= { + @httpPayload + @required + body: JsonInput + } + output: BlobResponse +} + @auth([]) @http(method: "POST", uri: "/blob", code: 200) operation TestWithBlob { @@ -134,6 +146,12 @@ structure TestResponseBody { bodyMessage: String } + +structure JsonInput { + @required + message: String +} + @http(method: "GET", uri: "/auth", code: 200) operation TestAuth { }