web-dev-qa-db-fra.com

Bibliothèque client HTTP simple et concise pour Scala

J'ai besoin d'une bibliothèque client HTTP mature, idiomatique à l'analyse, à l'utilisation concise, à la sémantique simple. J'ai examiné Apache HTTP et Scala Dispatch ainsi que de nombreuses nouvelles bibliothèques qui promettent un wrapping idiomatique de Scala. Le client HTTP Apache exige certainement de la verbosité, tandis que Dispatch prêtait à confusion.

Qu'est-ce qu'un client HTTP adapté à l'utilisation de Scala?

70
Jesvin Jose

J'ai récemment commencé à utiliser Dispatch , un peu mystérieux (excellente introduction générale, manque sérieux de documentation détaillée basée sur des scénarios/cas d'utilisation). Dispatch 0.9.1 est un wrapper Scala autour du client HTTP asynchrone de Ning; pour bien comprendre ce qui se passe, il faut se présenter à cette bibliothèque. En pratique, la seule chose que je devais vraiment examiner était le RequestBuilder - tout le reste s'inscrivant bien dans ma compréhension de HTTP.

J'approuve (jusqu'à présent!) La version 0.9 de faire le travail très simplement… une fois que vous avez dépassé cette courbe d'apprentissage initiale.

Le "constructeur" Http de Dispatch est immuable et semble bien fonctionner dans un environnement threadé. Bien que je ne trouve rien dans la documentation indiquant qu'il est thread-safe; la lecture générale de la source suggère que c'est le cas.

Sachez que les RequestBuilder sont mutables et ne sont donc pas thread-safe.

Voici quelques liens supplémentaires que j'ai trouvés utiles:

29
Richard Sitze

J'ai fait une comparaison des principales bibliothèques client HTTP disponibles } _

Dispatch, ainsi que quelques autres bibliothèques, ne sont plus maintenues . Les seules applications sérieuses sont actuellement spray-client et Play! WS.

spray-client est un peu complexe dans sa syntaxe. play-ws est assez facile à utiliser:

(build.sbt)

libraryDependencies += "com.typesafe.play" %% "play-ws" % "2.4.3"

(utilisation de base)

val wsClient = NingWSClient()
wsClient
  .url("http://wwww.something.com")
  .get()
  .map { wsResponse =>
    // read the response
}
23
implicitdef

Un peu tard pour la fête ici, mais j'ai été impressionné par spray-client .

Il possède un joli DSL pour la création de requêtes, prend en charge l'exécution synchrone et asynchrone, ainsi que divers types de (dés) marshalling (JSON, XML, formulaires). Il joue très bien avec Akka aussi.

21
Mark Tye

Deux Six ans après avoir initialement répondu à ce message, j'aurais une réponse différente.

J'utilise akka-http , une collaboration entre les équipes Spray et Akka. Il est soutenu par Lightbend, étroitement aligné sur l’environnement async d’akka ... c’est le bon outil pour ce travail.

11
Richard Sitze

Ayant eu quelques expériences malheureuses avec le client Apache, je me suis mis à écrire le mien. La connexion HttpURLConnection intégrée est généralement considérée comme un buggy. Mais ce n'est pas mon expérience. En fait, l'inverse a été le cas, le client Apache ayant un modèle de threading quelque peu problématique. Depuis Java6 (ou 5?), HttpURLConnection fournit des connexions HTTP 1.1 efficaces avec des fonctionnalités essentielles telles que Keep-Alive intégrée, et gère les utilisations simultanées sans complications.

Donc, pour compenser les API peu pratiques offertes par HttpURLConnection, je me suis mis à écrire une nouvelle API dans Scala, en tant que projet open-source. C'est juste un wrapper pour HttpURLConnection, mais contrairement à HttpURLConnection, il se veut simple d'utilisation. Contrairement au client Apache, il devrait s'intégrer facilement dans un projet existant. Contrairement à Dispatch, il devrait être facile à apprendre.

C'est ce qu'on appelle Bee Client

Mes excuses pour la fiche éhontée. :)

10
Rick-777

sttp est la bibliothèque HTTP Scala que nous attendions tous!

Il a un DSL fluide pour former et exécuter des requêtes (échantillons de code de leur fichier README):

val request = sttp
  .cookie("session", "*!@#!@!$")
  .body(file) // of type Java.io.File
  .put(uri"http://httpbin.org/put")
  .auth.basic("me", "1234")
  .header("Custom-Header", "Custom-Value")
  .response(asByteArray)

Il prend en charge les appels synchrones, asynchrones et en continu via des moteurs enfichables, y compris Akka-HTTP (anciennement Spray) et le vénérable AsyncHttpClient (Netty):

implicit val sttpHandler = AsyncHttpClientFutureHandler()
val futureFirstResponse: Future[Response[String]] = request.send()

Il prend en charge scala.concurrent.Future, scalaz.concurrent.Task, monix.eval.Task et cats.effect.IO - toutes les principales bibliothèques monades Scala IO.

De plus, il a quelques astuces supplémentaires dans sa manche:

val test = "chrabąszcz majowy" val testUri: Uri = uri"http://httpbin.org/get?bug=$test"

  • Il prend en charge les codeurs/décodeurs pour les corps/réponses de demandes, par exemple. JSON via Circé:

import com.softwaremill.sttp.circe._ val response: Either[io.circe.Error, Response] = sttp .post(uri"...") .body(requestPayload) .response(asJson[Response]) .send()

Enfin, il est géré par les spécialistes de softwaremill et il possède une excellente documentation .

5
tksfz

En dehors de Dispatch, il n'y a pas grand chose là-bas. scalaz a tenté de créer un client http fonctionnel. Mais il est obsolète depuis un moment et aucune version n’existe dans la branche scalaz7. En outre, il existe un utilitaire wrapper du client async-http de ning dans le cadre de lecture. Là vous pouvez faire des appels comme:

WS.url("http://example.com/feed").get()
WS.url("http://example.com/item").post("content")

Vous pouvez utiliser cette API comme source d'inspiration si vous n'utilisez pas le jeu! dans votre projet et n'aime pas l'API Dispatch. 

5
opeth

Vaporisateur

Vous devriez vraiment envisager d'utiliser Spray . À mon avis, la syntaxe est un peu compliquée, mais elle reste tout à fait utilisable si vous souhaitez créer un client http hautes performances. Le principal avantage de l'utilisation de Spray est qu'il est basé sur la bibliothèque d'acteurs akka , extrêmement évolutive et puissante. Vous pouvez faire évoluer votre client http sur plusieurs ordinateurs en ne modifiant que les fichiers conf

En outre, il y a quelques mois, Spray adhère à Typesafe et, si j'ai bien compris, il fera partie de la distribution de base d'akka. preuve

Play2

Une autre option est l'utilisation de la librairie WS Play2 ( doc ). Autant que je sache, elle n’est pas encore séparée de la distribution Play, mais, en raison de sa simplicité extrême, cela vaut la peine de passer du temps à attacher tout le cadre Play pour obtenir cette partie. Il y a quelques problèmes avec la configuration, donc ce n’est pas génial pour les cas de largage. Cependant, nous l'avons utilisé dans quelques projets autres que Play et tout s'est bien passé.

4
Alex Povar

ScalaJ-Http est un client HTTP synchrone très simple 

https://github.com/scalaj/scalaj-http

Je le recommanderais si vous avez besoin d'un client Scala barebones sans cérémonie. 

1
tdmadeeasy

J'ai utilisé Dispatch, Spray Client et la bibliothèque client Play WS ... Aucun d'entre eux n'était simplement à utiliser ou à configurer. J'ai donc créé une bibliothèque client HTTP plus simple qui vous permet d'exécuter toutes les requêtes HTTP classiques dans une ligne simple.

Voir un exemple:

import cirrus.clients.BasicHTTP.GET

import scala.concurrent.Await
import scala.concurrent.duration._

object MinimalExample extends App {

  val html = Await.result(Cirrus(GET("https://www.google.co.uk")), 3 seconds)

  println(html)
}

... produit ...

<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en-GB">...</html>

La bibliothèque s'appelle Cirrus et est disponible via Maven Central.

libraryDependencies += "com.github.godis" % "cirrus_2.11" % "1.4.1"

La documentation est disponible sur GitHub

https://github.com/Godis/Cirrus
0

Surpris que personne ne mentionne finagle ici. C'est super simple à utiliser:

import com.Twitter.finagle.{Http, Service}
import com.Twitter.finagle.http
import com.Twitter.util.{Await, Future}

object Client extends App {
  val client: Service[http.Request, http.Response] = Http.newService("www.scala-lang.org:80")
  val request = http.Request(http.Method.Get, "/")
  request.Host = "www.scala-lang.org"
  val response: Future[http.Response] = client(request)
  Await.result(response.onSuccess { rep: http.Response =>
    println("GET success: " + rep)
  })
}

Voir le guide de démarrage rapide pour plus de détails: https://Twitter.github.io/finagle/guide/Quickstart.html

0
Yuchen Zhong