Question Faire une requête HTTP dans Scala


J'essaie d'envoyer une simple requête POST à ​​un webservice qui renvoie du XML dans Scala.

Il paraît que Envoi est la bibliothèque standard utilisée pour cette tâche, mais je ne trouve pas de documentation pour cela. Le site principal, que je relie ci-dessus, explique en détail ce qu'est une promesse et comment faire de la programmation asynchrone, mais ne documente pas réellement l’API. Il y a un tableau périodique - ce qui semble un peu effrayant - mais cela ne semble utile qu'aux personnes qui savent déjà quoi faire et n'ont besoin que d'un rappel pour la syntaxe cryptique.

Il semble aussi que Scalaz a quelques facilités pour HTTP, mais je ne trouve pas de documentation non plus.


65
2017-07-30 10:11


origine


Réponses:


J'utilise les éléments suivants: 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 POST:

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"

109
2017-07-30 11:20



Vous pourriez utiliser client de pulvérisation. La documentation manque (il m'a fallu creuser pour savoir comment faire des requêtes GET avec des paramètres de requête) mais c'est une excellente option si vous utilisez déjà du spray. Et la documentation est meilleure que l'envoi.

Nous l'utilisons à AI2 plus de envoi parce que les opérateurs sont moins symboliques et nous utilisons déjà des spray / 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)

6
2017-10-07 18:43



J'utilise expédition: http://dispatch.databinder.net/Dispatch.html

Ils viennent de sortir une nouvelle version (0.9.0) avec un nouvel api complet que j'aime beaucoup. Et c'est async.

Exemple 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


5
2017-07-30 11:33



Une autre option est le play-ws de Typesafe, qui est la bibliothèque Play Framework WS en librairie autonome:

http://blog.devalias.net/post/89810672067/play-framework-seperated-ws-library

Je ne proposerais pas nécessairement cela comme la meilleure option, mais cela mérite d'être mentionné.


3
2018-01-13 01:32



Pourquoi ne pas utiliser Apache HttpComponents ? Ici se trouve le application FAQ, qui couvre un large éventail de scénarios.


2
2017-07-30 10:16



Si je peux faire un plug sans vergogne, j'ai une API appelée Abeille-client qui est simplement un wrapper dans Scala pour Java HttpUrlConnection.


1
2017-07-31 07:37



J'ai dû faire la même chose pour tester un point final (dans le test d'intégration). Voici donc le code pour récupérer la réponse à la requête GET dans Scala. Je me sers de scala.io.Source pour lire des points de terminaison et ObjectMapper pour que json convertisse les objets.

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 de test pour le même

test("validate booksMasterData resource") {
    val booksMasterData = fetchBooksMasterData(Option(null))
    booksMasterData.size should be (740)
  }

0
2018-02-07 09:22