简单而简洁的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项目中使用过,一切都很好。
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.Future
, scalaz.concurrent.Task
, monix.eval.Task
和cats.effect.IO
– 所有主要的Scala IO monad库。
再加上它有一些额外的技巧:
-
它有请求和响应的案例类表示(尽pipe它没有像强types的头文件): https : //github.com/softwaremill/sttp/blob/master/core/src/main/scala /com/softwaremill/sttp/RequestT.scala https://github.com/softwaremill/sttp/blob/master/core/src/main/scala/com/softwaremill/sttp/Response.scala
-
它提供了一个URIstring插入器 :
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