Reputation: 1505
I am using akka-http
and writing an Unmarhsaller
for one of my classes. What I am trying to do is to get the body of the POST request as a String
so I can create my object with it :
case class MyClass(geom: String)
implicit def fromRequestUnmarshaller = Unmarshaller[HttpRequest, MyClass]({implicit ec: ExecutionContext =>
req: HttpRequest => Future(MyClass(req.entity.asInstanceOf[HttpEntity.Strict].data.map(_.toChar).mkString))
})
It seems like a very complicated line of code just to get the body as a String
. Plus, I am doing a very ugly asInstanceOf[HttpEntity.Strict]
just because I figured the HttpRequest
was of this type while debugging.
My question: is there a simpler/cleaner way to achieve my goal ?
Thanks a lot :)
Upvotes: 3
Views: 1834
Reputation: 17923
Be Careful
The reason akka implements the entity as a Source[ByteString,_]
is because the entity of an HttpRequest can potentially be infinite length. Therefore, you better make sure that your application has enough RAM to handle any request that is likely to be thrown at it...
toStrict
You can use HttpEntity#toStrict
:
implicit val materializer : Materializer = ???
implicit val executionContext : ExecutionContext = ???
val entityFromRequest : (HttpRequest, FiniteDuration) => Future[ByteString] =
(_ : HttpRequest)
.entity
.toStrict(_ : FiniteDuration)
.map(_.data)
Manual Conversion
You can access the "body", i.e. entity, of an HttpRequest as a Source[ByteString, _]
:
val getBodySource : HttpRequest => Source[ByteString,_] =
_.entity
.dataBytes
This Source can then be sent to a Sink which collects the ByteString
values into a Seq
:
val convertSrcToSeq : Source[ByteString,_] => Future[Seq[ByteString]] =
_ runWith Sink.seq
The body you are looking for is one continuous String
therefore these ByteStrings need to be reduced to a single value:
val reduceSeqToStr : Future[Seq[ByteString]] => Future[ByteString] =
_ map (_ reduceOption (_ ++ _) getOrElse ByteString.empty)
These steps can now be composed into a single function:
val getBodyStrFromRequest : HttpRequest => Future[ByteString] =
getBodySource andThen convertSrcToSeq andThen reduceSeqToStr
Upvotes: 3