1
votes

I'm trying to use circe to do my JSON (de)serialization in an Akka-Http app, rather than spray-json. For that reason, I want to use the entity directive with as[String] to get the string representation of the request body, and then do my own deserialization. But it seems that entity is too smart for its own good, and is rejecting anything that does not have the Content-Type text/plain.

My understanding from the docs is that implicit magic should let me be able to do something like:

import akka.http.scaladsl.model.ContentTypes
entity(as[String].forContentTypes(ContentTypes.`application/json`))

But the compiler is not doing the whole thing of inferring that I want as to resolve to a FromEntityUnmarshaller[String], which has that implicit method forContentTypes, whose result should be converted to a FromMessageUnmarshaller[String], which (due to contravariance) should satisfy the need for a FromRequestUnmarshaller[String].

However, even holding the compilers hand by doing:

val jsonRequestToStringUnmarshaller: FromRequestUnmarshaller[String] = 
  messageUnmarshallerFromEntityUnmarshaller(implicitly[FromEntityUnmarshaller[String]].forContentTypes(ContentTypes.`application/json`))
entity(jsonRequestToStringUnmarshaller)

my server is still rejecting application/json requests.

What gives?

Update

I can see now that I misunderstood forContentTypes, and that it will only narrow, not expand, the Content-Type range that an Unmarshaller will accept. That just explains why my solution isn't working.

1

1 Answers

1
votes

I would suggest to give Akka-Http direct marshallers-unmarshallers from / to desired types using circe under the hood.

It may look like: https://github.com/PDXostc/rvi_sota_server/blob/master/common/src/main/scala/org/genivi/sota/marshalling/CirceMarshallingSupport.scala