1

Lets say I have a Play Controller with this method -

def persons(): Action[AnyContent] =
  Action { _ =>
    Ok.chunked(personSource.map { p => JsObject(p) }
  )
}

The Akka Source stream is a large but finite stream of Persons from, say our db. Loading all of it into memory at once would lead to out of memory exceptions.

The code above works fine, I get a long stream of json objects:

{"name": "TestPerson1}{"name": "TestPerson2"}

But now a client has requested the response has this format:

[{"name": "TestPerson1},{"name": "TestPerson2"}]

I am having troubles finding how to emit prefix/suffix to the stream. Maybe a filter, or nesting Actions? But the examples I find of that tend to operate on the Request such as redirecting, or having side-effecting operations such as logging something before handing over processing to the inner Action.

I would like to emit "[" at the start of the http response, keep the Source async chunked processing in the middle, and then emit a "]" at the end.

Lars Westergren
  • 2,119
  • 15
  • 25
  • 1
    You can easily concat sources of chunks – cchantep Jul 04 '17 at 11:14
  • @cchantep Ah right I can do it on stream Source level if I map the Person source to a Source[String], and then use Source.concat(next). Thanks I will post a full solution if I get it to work. – Lars Westergren Jul 04 '17 at 11:30

1 Answers1

2

Solution found thanks to @cchantep

val persons = source.map { p => JsObject(p).toString }.intersperse(",")
Action { _ =>
  Ok.chunked(Source(List("[")).concat(persons).concat(Source(List("]"))))
}

Or even simpler (thanks to this page, which I didn't find before):

Ok.chunked(source.map { p => JsObject(p).toString }.intersperse("[", ",", "]") )
Lars Westergren
  • 2,119
  • 15
  • 25