Bibliothèque de clients HTTP simple et concise pour Scala

J’ai besoin d’une bibliothèque de clients HTTP mature, idiomatique à la scala, à l’utilisation concise, à la sémantique simple. J’ai regardé le HTTP Apache et le Scala Dispatch et de nombreuses nouvelles bibliothèques qui promettent un emballage Scala idiomatique. Le client HTTP Apache exige une certaine verbosité, tandis que Dispatch est facilement déroutant.

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

J’ai récemment commencé à utiliser Dispatch , un peu mystérieux (excellente introduction générale, manque sérieux de docs détaillés basés sur des scénarios / cas d’utilisation). Dispatch 0.9.1 est un wrapper Scala autour du client Async Http de Ning; pour comprendre pleinement ce qui se passe, il faut se présenter à cette bibliothèque. En pratique, la seule chose que je devais vraiment regarder était le RequestBuilder – tout le rest entrait parfaitement dans ma compréhension de HTTP.

Je donne à la version 0.9 un coup de pouce solide (jusqu’à présent!) Pour 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 docs pour affirmer qu’il est compatible avec les threads; une 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:

  • Je ne parviens pas à trouver un lien ScalaDoc pour la version 0.9. * Je consulte donc le code source pour la version 0.9. * ;

  • ScalaDoc pour la version 0.8 ; une bête sensiblement différente (aujourd’hui) de 0,9.

  • Le tableau “périodique” des opérateurs, également 0.8 lié.

  • Les documents plus anciens de 0.8 “dispatch-classic” m’ont aidé à comprendre comment ils utilisaient les générateurs d’url, et ont donné quelques indices sur la manière dont les choses sont liées entre elles et qui ont été rescopes à 0.9.

J’ai comparé la plupart des principales bibliothèques de clients HTTP disponibles

Dispatch et quelques autres bibliothèques ne sont plus maintenues . Les seuls sérieux sont actuellement le client de pulvérisation et Play! WS .

spray-client est un peu mystérieux 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 } 

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

Il dispose d’un DSL bien conçu pour la création de requêtes, prend en charge à la fois l’exécution synchrone et asynchrone, ainsi qu’une variété de types (un) marshalling (JSON, XML, formulaires). Cela joue très bien avec Akka aussi.

Deux Six ans après avoir initialement répondu à cet article, j’aurais une réponse différente.

J’ai utilisé akka-http , une collaboration entre les équipes spray et akka. Il est soutenu par Lightbend, étroitement aligné avec l’environnement async akka, c’est le bon outil pour ce travail.

Ayant vécu des expériences malheureuses avec le client Apache, je me suis mis à écrire le mien. Le HttpURLConnection intégré est largement reconnu comme étant bogué. Mais ce n’est pas mon expérience. En fait, le client Apache avait un modèle de thread quelque peu problématique. Depuis Java6 (ou 5?), HttpURLConnection a fourni des connexions HTTP1.1 efficaces avec des éléments essentiels tels que keep-alive en cours de construction, et il gère l’utilisation simultanée sans problème.

Donc, pour compenser l’inconvénient de l’API offerte 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 pouvoir s’intégrer facilement dans un projet existant. Contrairement à Dispatch, il devrait être facile à apprendre.

Il s’appelle Bee Client

Mes excuses pour le bouchon sans vergogne. 🙂

Outre 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 certain temps et sa version n’existe pas dans la twig scalaz7. En outre, il existe un wrapper utile du client async-http ning dans le playframework. 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.

Vaporisateur

Vous devriez vraiment envisager d’utiliser Spray . A mon avis, il a un peu de syntaxe délicate, mais il est encore très utilisable si vous souhaitez créer un client http hautes performances. L’avantage principal 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 vers plusieurs machines en modifiant uniquement les fichiers de conf .

De plus, il y a quelques mois, Spray a rejoint Typesafe, et si je comprends bien, elle fera partie de la dissortingbution de base de l’akka. preuve

Jouer2

Une autre option est l’utilisation de la librairie WS Play2 ( doc ). Pour autant que je sache, il n’est toujours pas séparé de la dissortingbution Play, mais en raison de sa simplicité extrême, cela vaut la peine de passer du temps à attacher l’ensemble du framework Play pour obtenir cette partie. Il y a quelques problèmes avec la configuration, donc ce n’est pas parfait pour les cas d’utilisation directe. Cependant, nous l’avons utilisé dans quelques projets non basés sur le jeu et tout allait bien.

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

Il possède un DSL courant pour former et exécuter des requêtes (exemples de code à partir 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 systèmes dorsaux enfichables, notamment Akka-HTTP (anciennement Spray) et le vénérable AsyncHttpClient (Netty):

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

Il supporte scala.concurrent.Future , scalaz.concurrent.Task , monix.eval.Task et cats.effect.IO – toutes les principales librairies Scala IO monad.

De plus, il a quelques astuces supplémentaires dans son sac:

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 de requête / réponses, 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 maintenu par les gens fiables de softwaremill et sa documentation est excellente.

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

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

Je le recommande si vous avez besoin d’un client Scala sans cérémonie.

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

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 …

 ... 

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 

Surpris que personne n’a mentionné 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