Stratos K
Stratos K

Reputation: 462

Scala and Akka HTTP: How to get the entity content as string

I am very new to Akka HTTP so please accept my apologies beforehand for the very elementary question.

In the following piece of code, I want to retrieve the entity from the HTTP request (entity will be plain text), get the text out of the entity, and return it as a response.

  implicit val system = ActorSystem("ActorSystem")
  implicit val materializer = ActorMaterializer
  import system.dispatcher

  val requestHandler: Flow[HttpRequest, HttpResponse, _] = Flow[HttpRequest].map {
    case HttpRequest(HttpMethods.POST, Uri.Path("/api"), _, entity, _) =>
      val entityAsText = ... // <- get entity content as text

      HttpResponse(
        StatusCodes.OK,
        entity = HttpEntity(
          ContentTypes.`text/plain(UTF-8)`,
          entityAsText
        )
      )
  }

  Http().bindAndHandle(requestHandler, "localhost", 8080)  

How can I get the string content of the entity?

Many thanks in advance!

Upvotes: 1

Views: 2467

Answers (2)

Ghashange
Ghashange

Reputation: 1206

Another approach would be to use the already Unmarshaller which is in scope (most likely it will be the akka.http.scaladsl.unmarshalling.PredefinedFromEntityUnmarshallers#stringUnmarshaller):

val entityAsText: Future[String] = Unmarshal(entity).to[String]

This approach ensures the consistent usage of the provided Unmarshaller for String and you wouldn't have to cope with timeouts.

Upvotes: 3

Jeffrey Chung
Jeffrey Chung

Reputation: 19497

One approach is to call toStrict on the RequestEntity, which loads the entity into memory, and mapAsync on the Flow:

import scala.concurrent.duration._

val requestHandler: Flow[HttpRequest, HttpResponse, _] = Flow[HttpRequest].mapAsync(1) {
  case HttpRequest(HttpMethods.GET, Uri.Path("/api"), _, entity, _) =>
    val entityAsText: Future[String] = entity.toStrict(1 second).map(_.data.utf8String)

    entityAsText.map { text =>
      HttpResponse(
        StatusCodes.OK,
        entity = HttpEntity(
          ContentTypes.`text/plain(UTF-8)`,
          text
        )
      )
    }
}

Adjust the timeout on the former and the parallelism level on the latter as needed.

Upvotes: 4

Related Questions