2014-12-30 18 views
6

ho questo percorso:Come paramare POST unmarshal e corpo JSON in una singola route?

val routes = 
    pathPrefix("api") { 
     path("ElevationService"/DoubleNumber/DoubleNumber) { (long, lat) => 
     post { 
      requestContext => 
      println(long, lat) 
     } 
     } 
    } 

Questo funziona bene, posso chiamare il mio ElevationService come:

http://localhost:8080/api/ElevationService/39/80 

Il problema è, voglio anche di analizzare il corpo inviatami nella richiesta come JSON. Sembra come segue:

{ 
    "first": "test", 
    "second": 0.50 
} 

Sono riuscito a farlo funzionare in un percorso separato seguente the documentation on the entity directive:

path("test") { 
    import scrive.actors.ScriveJsonProtocol 
    import spray.httpx.SprayJsonSupport._ 
    post { 
     entity(as[ScriveRequest]) { scrive => 
     complete(scrive) 
     } 
    } 
} 

Ma io non so come unire questi due percorsi in una sola. Dal momento che sono avvolti in funzioni, non posso chiamare i parametri long, lat all'interno della funzione entity, non esistono in tale ambito, suppongo. Lo stesso vale o viceversa.

Voglio essere in grado di accedere sia i miei params e il mio corpo POST, e poi chiamare un servizio che passa tutti i dati:

val elevationService = actorRefFactory.actorOf(Props(new ElevationService(requestContext))) 
elevationService ! ElevationService.Process(long, lat, bodyParams) 

risposta

6

Si può solo nidificare le direttive:

path("ElevationService"/DoubleNumber/DoubleNumber) { (long, lat) => 
    post { 
    entity(as[ScriveRequest]) { scrive => 
     onSuccess(elevationService ? ElevationService.Process(long, lat, bodyParams)) { 
     actorReply => 
      complete(actorReply) 
     } 
    } 
} 

è inoltre possibile utilizzare & per combinare due direttive più direttamente:

(path("ElevationService"/DoubleNumber/DoubleNumber) & entity(as[ScriveRequest])) { 
    (long, lat, scriveRequest) => ... 
+0

Grazie, lo darò una prova, ma ottengo "Tipo parametro mancante: actorReply", ovviamente dal momento che non è definito da nessuna parte. È questo "attoreReply" una sorta di callback per l'attore, o per cosa serve. Mi dispiace se chiedo una domanda stupida, sto solo iniziando con spray e questo routing di dsl è così confuso. –

+2

'actorReply' è quello che stavo usando come nome per la risposta dell'attore. Ho dimenticato che Akka non è tipizzato, quindi probabilmente avrebbe bisogno di un cast. Se non hai bisogno di aspettare una risposta dall'attore allora non hai bisogno di '?' O 'onSuccess', puoi semplicemente usare'! 'Per inviare un messaggio fire-and-forget all'attore e lascialo lì. – lmm