简单而简洁的Scala的HTTP客户端库

我需要一个成熟的HTTP客户端库,它是scala的惯用语,简洁的用法,简单的语义。 我看了Apache HTTP和Scala Dispatch以及许多承诺一个惯用的Scala包装的新库。 Apache HTTP客户端确实需要冗长,而Dispatch很容易混淆。

什么是适合Scala使用的HTTP客户端?

我最近开始使用调度 ,有点神秘(伟大的一般介绍,严重缺乏详细的情况/基于用例的文档)。 Dispatch 0.9.1是Ning的asynchronousHttp客户端的一个Scala包装器; 要充分了解发生了什么事,需要将自己介绍给该图书馆。 实际上,我唯一需要考虑的就是RequestBuilder ,其他所有东西都很好地融入了我对HTTP的理解。

我把0.9版本放在了一个坚实的大拇指上(迄今为止!),完成工作非常简单..一旦你通过了最初的学习曲线。

派遣的Http“builder”是不可变的,似乎在一个线程环境中工作得很好。 虽然我在文档中找不到任何东西,说它是线程安全的; 一般的来源阅读表明它是。

请注意, RequestBuilder是可变的,因此不是线程安全的。

这里有一些额外的链接,我发现有帮助:

  • 我无法find0.9。*版本的ScalaDoc链接,因此我浏览了0.9。*版本的源代码。

  • ScalaDoc为0.8版本 ; (今天)比0.9大不相同。

  • 运营商的“周期表”也有0.8个关系。

  • 较老的0.8“dispatch-classic”文档帮助我理解他们是如何使用urlbuild设者的,并且提供了一些关于如何结合在一起的提示到0.9的提示。

这里的晚会有点迟,但是我对喷客户印象深刻。

它有一个很好的DSL构build请求,支持同步和asynchronous执行,以及各种(联合)编组types(JSON,XML,表单)。 它也和Akka很好地搭配。

我对大多数主要的HTTP客户端库进行了比较

调度,和其他一些库, 不再维护 。 目前唯一严重的是喷客户端播放! WS

喷客户端在语法上有点神秘。 play-ws非常容易使用:

(build.sbt)

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

(基本用法)

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

在和Apache客户端有过不愉快的经历之后,我开始写自己的。 内置的HttpURLConnection被广泛认为是越野车。 但那不是我的经验。 事实上,事实恰恰相反,Apache客户端有一个有点问题的线程模型。 从Java6(或5?)开始,HttpURLConnection已经提供了高效的HTTP1.1连接,并且内置了keep-alive这样的基本要素,并且可以毫不费力地处理并发使用。

所以,为了弥补由HttpURLConnection提供的不方便的API,我开始着手在Scala中编写一个新的API,作为一个开源项目。 这只是HttpURLConnection的一个包装,但是与HttpURLConnection不同,它的目标是易于使用。 不像Apache客户端,它应该很容易地适合现有的项目。 不像调度,它应该很容易学习。

它被称为Bee Client

  • 网站: http : //www.bigbeeconsultants.co.uk/bee-client
  • API文档: http : //www.bigbeeconsultants.co.uk/docs/bee-client/latest.html

我为无耻的插头道歉。 🙂

在回复这篇文章两年之后,我会有一个不同的答案。

我首先要仔细看看akka-http ,这是喷雾和阿卡队之间的合作。 截至今日,尚未达到1.0版本发布; 它即将推出,由types安全支持,并看起来不错。

除了调度,没有太多的东西。 scalaz尝试构build一个function性的http客户端。 但它已经过时了一段时间没有在scalaz7分支中存在的版本。 另外,在playframework中还有一个非常有用的ning async-http-client包装。 在那里你可以打电话,如:

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

如果你不使用游戏,你可以使用这个API作为灵感! 在你的项目中,并不喜欢调度API。

喷雾

你真的应该考虑使用喷雾 。 在我看来,它有一些棘手的语法,但如果你打算build立一个高性能的http客户端,它仍然是非常有用的。 使用Spray的主要优势在于它基于akka actor库,它非常具有可扩展性和强大function。 您可以通过只更改conf文件将您的http客户端扩展到多台机器。

此外几个月前喷雾joinTypesafe,据我所知它将成为基本的akka​​分布的一部分。 certificate

Play2

另一种select是Play2 WS lib的使用( doc )。 据我所知,它仍然没有与Play发行版分离,但由于其非常简单,因此花费一些时间来附加整个Play框架来获得该部分是值得的。 提供configuration有一些问题,所以这对于drop-and-use的情况并不好。 但是,我们已经在很less的非Play项目中使用过,一切都很好。

ScalaJ-Http是一个非常简单的同步HTTP客户端

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

我会推荐它,如果你需要一个没有仪式的准系统Scala客户端。

sttp是我们一直在等待的Scala HTTP库!

它具有stream畅的DSL,用于形成和执行请求(自述文件中的代码示例):

 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) 

它支持通过可插入后端(包括Akka-HTTP(以前称为Spray)和古老的AsyncHttpClient(Netty))进行同步,asynchronous和串stream调用。

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

它支持scala.concurrent.Futurescalaz.concurrent.Taskmonix.eval.Taskcats.effect.IO – 所有主要的Scala IO monad库。

再加上它有一些额外的技巧:

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

  • 它支持请求机构/响应的编码器/解码器,例如通过Circe的JSON:

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

最后,它由softwaremill的可靠人员维护,并且有很好的文档 。

我使用了Dispatch,Spray Client和Play WS Client Library …都不是简单的使用或configuration。 所以我创build了一个更简单的HTTP客户端库,可以让您以简单的一行内容执行所有经典的HTTP请求。

看一个例子:

 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) } 

生产…

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

这个图书馆叫做Cirrus,可以通过Maven Central获得

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

该文档在GitHub上可用

 https://github.com/Godis/Cirrus 

惊讶的是没有人在这里提到finagle。 这是非常简单的使用:

 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) }) } 

请参阅快速入门指南: https : //twitter.github.io/finagle/guide/Quickstart.html