2015-08-10 17 views
12

Una delle caratteristiche di Akka HTTP (formalmente noto come Spray) è la sua capacità di effettuare il marshalling automatico e dati unmarshal avanti e indietro da json a case classes, ecc. Ho avuto successo nel far funzionare tutto questo.Parametri di query per richieste GET utilizzando Akka HTTP (formalmente noto come Spray)

Al momento, sto tentando di creare un client HTTP che esegue una richiesta GET con parametri di query. Il codice è attualmente il seguente:

val httpResponse: Future[HttpResponse] = 
    Http().singleRequest(HttpRequest(
    uri = s"""http://${config.getString("http.serverHost")}:${config.getInt("http.port")}/""" + 
      s"query?seq=${seq}" + 
      s"&max-mismatches=${maxMismatches}" + 
      s"&pam-policy=${pamPolicy}")) 

Beh, non è così bello. Sarebbe bello se potessi semplicemente passare in una case case contenente i parametri di query, e avere Akka HTTP generasse automagicamente i parametri di query, un po 'come fa per json. (Inoltre, il lato server di Akka HTTP ha un modo un po 'elegante di analizzare i parametri di query GET, quindi si potrebbe pensare che avrebbe anche un modo un po' elegante di generarli.)

Mi piacerebbe fare qualcosa come il seguente:

val httpResponse: Future[HttpResponse] = 
    Http().singleRequest(HttpRequest(
    uri = s"""http://${config.getString("http.serverHost")}:${config.getInt("http.port")}/query""", 
    entity = QueryParams(seq = seq, maxMismatches = maxMismatches, pamPolicy = pamPolicy))) 

Solo, quanto sopra non funziona.

È ciò che voglio in qualche modo fattibile con Akka HTTP? O devo solo fare le cose alla vecchia maniera? I.e, generare i parametri di query esplicitamente, come faccio nel primo blocco di codice sopra.

(So che se dovessi cambiare questo da un GET a un POST, potrei probabilmente farlo funzionare più come vorrei che funzionasse, da allora potrei ottenere il contenuto della richiesta POST automagicamente convertito da una case class a JSON, ma non lo desidero davvero.)

risposta

16

è possibile sfruttare la classe Uri a fare quello che vuoi. Offre diversi modi per ottenere un set di parametri nella stringa di query utilizzando il metodo withQuery. Ad esempio, si potrebbe fare qualcosa di simile:

val params = Map("foo" -> "bar", "hello" -> "world") 
HttpRequest(Uri(hostAndPath).withQuery(params)) 

O

HttpRequest(Uri(hostAndPath).withQuery(("foo" -> "bar"), ("hello" -> "world"))) 
+3

La cosa buona con questo metodo è che la fuga sarà fatto automaticamente utilizzando questo metodo. – jrudolph

+0

Grazie !!! Questo è solo il tipo di cosa che stavo cercando. – Douglas

+13

Con Akka-http 2.4.8, sembra che sia necessario un involucro 'Query':' .withQuery (Query (params))) ' – akauppi

1

Ovviamente questo potrebbe essere fatto modificando l'estensione della capacità di Akka HTTP, ma per quello che ti serve (solo in un modo più ordinato per costruire la stringa di query), si potrebbe fare con un certo divertimento scala:

type QueryParams = Map[String, String] 

object QueryParams { 

    def apply(tuples: (String, String)*): QueryParams = Map(tuples:_*) 
} 

implicit class QueryParamExtensions(q: QueryParams) { 

    def toQueryString = "?"+q.map{ 
    case (key,value) => s"$key=$value" //Need to do URL escaping here? 
    }.mkString("&") 
} 

implicit class StringQueryExtensions(url: String) { 
    def withParams(q: QueryParams) = 
    url + q.toQueryString 
} 

val params = QueryParams(
    "abc" -> "def", 
    "xyz" -> "qrs" 
) 

params.toQueryString // gives ?abc=def&xyz=qrs 

"http://www.google.com".withParams(params) // gives http://www.google.com?abc=def&xyz=qrs