Cómo devolver el enumerador de JSON de ReactiveMongo en Play 2
-
21-12-2019 - |
Pregunta
En nuestro proyecto estamos usando ReactiveMongo
con Play 2.2.1
.
El problema es que transmitir datos en forma de Enumerator[A]
, devuelto por ReactiveMongo
es en realidad una secuencia de objetos de valor, que no están separados por comas y no tienen anotaciones de inicio y fin de secuencia, que pueden tratarse como declaraciones de apertura y cierre de matriz.
Esto crea un problema para JSON
consumidor JS client
, ya que el formato esperado es[A1,A2, ...]
Así que nos lanzamos al aro y transformamos nuestra Enumeratee[A]
a Enumerator[String]
, comprobando si es el primer elemento o no:
var first:Boolean = true
val aToStrs = (as.map(a => {
if(first) {
first = false;
Json.stringify(Json.toJson(a))
} else {
"," + Json.stringify(Json.toJson(a))
}
}))
Ok.chunked(
Enumerator.enumInput(Input.El("[")) andThen
aToStrs andThen
Enumerator.enumInput(Input.El("]")) andThen
Enumerator.enumInput(Input.EOF)
)
Esto funciona, pero parece como inventar la rueda.
¿Existe una solución mejor para este problema común?
Solución
Si usa Comet o EventCource, no tendrá que hacer una forma de manualización a mano para generar salida y también podrá analizar el elemento de respuesta para el artículo en el cliente.Respondiendo con una matriz le obligaría a escribir su propio código de análisis o esperar hasta que todo haya llegado al lado del cliente antes de poder usar el analizador de compilación INT JSON en su JavaScript.
Streaming con el protocolo de EventCource es bastante fácil con el juego, debería poder hacer algo como:
implicit val cometEncoder = new Comet.CometMessage[JsValue](_.toString)
Ok.chunked(yourEnumerator &> EventSource()).as(EVENT_STREAM)
y luego en el cliente HTML:
<script type="text/javascript">
var es = new EventSource(jsRouter.controllers.Application.streamIt().url)
es.addEventListener("message", function (event) {
var item = JSON.parse(event.data)
// ... do something with the json value ...
})
</script>
Hay un ejemplo de esto en los proyectos de muestra de juego que es posible que desee ver también $YOUR_PLAY_DIR/samples/scala/eventsource-clock/