Faire une requête HTTP dans Scala
j'essaie d'envoyer une simple requête postale à un service web qui renvoie du XML en Scala.
il semble que Dispatch soit la bibliothèque standard utilisée pour cette tâche, mais je ne peux pas trouver de documentation pour cela. Le site principal, que je relie ci-dessus, explique en détail ce qui est une promesse et comment faire une programmation asynchrone, mais ne documente pas réellement l'API. Il ya un tableau périodique - qui semble un peu effrayant - mais cela semble seulement utile pour les gens qui savent déjà quoi faire et n'ont besoin que d'un rappel pour la syntaxe cryptique.
il semble également que Scalaz dispose d'une certaine facilité pour HTTP , mais je ne peux pas trouver de documentation pour cela non plus.
7 réponses
j'utilise ce qui suit: https://github.com/scalaj/scalaj-http .
Voici une simple requête GET:
import scalaj.http.Http
Http("http://foo.com/search").param("q", "monkeys").asString
et un exemple de message:
val result = Http("http://example.com/url").postData("""{"id":"12","json":"data"}""")
.header("Content-Type", "application/json")
.header("Charset", "UTF-8")
.option(HttpOptions.readTimeout(10000)).asString
Scalaj HTTP est disponible via SBT:
libraryDependencies += "org.scalaj" % "scalaj-http_2.11" % "2.3.0"
vous pouvez utiliser spray-client . La documentation fait défaut (il m'a fallu creuser pour trouver comment faire des requêtes GET avec les paramètres de requête ) mais c'est une excellente option si vous utilisez déjà spray. Et la documentation est meilleure que l'expédition.
nous l'utilisons à AI2 over dispatch parce que les opérateurs sont moins symboliques et que nous utilisons déjà pulvérisation/acteurs.
import spray.client.pipelining._
val url = "http://youruri.com/yo"
val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
// Post with header and parameters
val responseFuture1: Future[String] = pipeline(Post(Uri(url) withParams ("param" -> paramValue), yourPostData) map (_.entity.asString)
// Post with header
val responseFuture2: Future[String] = pipeline(Post(url, yourPostData)) map (_.entity.asString)
j'utilise le dispatch: http://dispatch.databinder.net/Dispatch.html
ils viennent de sortir une nouvelle version (0.9.0) avec une nouvelle api complète que j'aime vraiment. Et il est asynchrone.
exemple tiré de la page du projet:
import dispatch._
val svc = url("http://api.hostip.info/country.php")
val country = Http(svc OK as.String)
for (c <- country)
println(c)
edit: cela pourrait vous aider https://github.com/dispatch/reboot/blob/master/core/src/main/scala/requests.scala
une autre option est play-ws de Typesafe, qui est le cadre de lecture bibliothèque WS divisé en lib autonome:
http://blog.devalias.net/post/89810672067/play-framework-seperated-ws-library
ce n'est pas nécessairement la meilleure option, mais cela vaut la peine d'être mentionné.
pourquoi ne pas utiliser Apache HttpComponents ? Voici le application FAQ , qui couvre un large éventail de scénarios.
si je peux faire une fiche sans vergogne, j'ai une API appelée Bee-Client qui est simplement un wrapper en Scala pour la connexion Httpurl de Java.
j'ai dû faire la même chose pour tester un point final (test D'intégration). Voici donc le code pour récupérer la réponse à partir de la requête GET dans Scala. J'utilise scala.io.Source pour lire à partir de endpoint et ObjectMapper pour JSON à la conversion d'objet.
private def buildStockMasterUrl(url:String, stockStatus:Option[String]) = {
stockStatus match {
case Some(stockStatus) => s"$url?stockStatus=${stockStatus}"
case _ => url
}
}
private def fetchBooksMasterData(stockStatus:Option[String]): util.ArrayList[BooksMasterData] = {
val url: String = buildBooksMasterUrl("http://localhost:8090/books/rest/catalogue/booksMasterData",stockStatus)
val booksMasterJson : String = scala.io.Source.fromURL(url).mkString
val mapper = new ObjectMapper()
apper.readValue(booksMasterJson,classOf[util.ArrayList[BooksMasterData]])
}
case class BooksMasterData(id:String,description: String,category: String)
et voici ma méthode d'essai pour le même
test("validate booksMasterData resource") {
val booksMasterData = fetchBooksMasterData(Option(null))
booksMasterData.size should be (740)
}