我需要一个成熟的HTTP客户端库,它是scala惯用的,简洁的用法,简单的语义。我查看了Apache HTTP和Scala Dispatch以及许多新的库,这些库承诺提供惯用的Scala包装。 Apache HTTP客户端肯定要求冗长,而Dispatch很容易混淆。
什么是适合Scala使用的HTTP客户端?
答案 0 :(得分:29)
我最近开始使用Dispatch,有点神秘(很棒的一般介绍,严重缺乏详细的场景/基于用例的文档)。 Dispatch 0.9.1是一个围绕Ning Async Http Client的Scala包装器;要完全理解发生了什么,需要将自己引入该库。在实践中,我唯一需要关注的是RequestBuilder - 其他一切都很好地融入了我对HTTP的理解。
我给0.9发布了一个非常简单的赞助(到目前为止!),简单地完成工作......一旦你超越了初始学习曲线。
Dispatch的Http“builder”是不可变的,似乎在线程环境中运行良好。虽然我在文档中找不到任何说明它是线程安全的东西;一般阅读来源表明它是。
请注意RequestBuilder是可变的,因此不是线程安全的。
以下是我发现有用的其他链接:
我找不到0.9。*版本的ScalaDoc链接,所以我浏览source code for the 0.9.* release;
ScalaDoc for the 0.8 release;一个基本不同的野兽(今天)而不是0.9。
The "Periodic" Table运营商,也与0.8相关。
年龄较大的0.8 "dispatch-classic" docs帮助我了解了他们如何使用网址构建器,并提供了一些关于事情如何捆绑在一起的提示,并将其结合到0.9。
答案 1 :(得分:27)
我做了comparison of most major HTTP client libraries available
Dispatch和其他一些库不再维护。 目前唯一认真的是 spray-client 和 Play! WS 强>
spray-client 的语法有点神秘。 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
}
答案 2 :(得分:21)
这里的派对有点晚了,但我对spray-client印象深刻。
它有一个很好的DSL用于构建请求,支持同步和异步执行,以及各种(非)编组类型(JSON,XML,表单)。它与Akka的效果非常好。
答案 3 :(得分:13)
两个在最初回复这篇文章六年后,我会有不同的答案。
我一直在使用akka-http,这是喷雾和akka团队之间的合作。它受到Lightbend的支持,与akka异步环境紧密结合......它是这项工作的正确工具。
答案 4 :(得分:10)
在Apache客户端遇到过一些不愉快的经历后,我开始编写自己的。内置的HttpURLConnection被广泛认为是有缺陷的。但那不是我的体验。事实上,反过来一直如此,Apache客户端有一个有问题的线程模型。从Java6(或5?)开始,HttpURLConnection提供了高效的HTTP1.1连接,内置了keep-alive等基本功能,并且可以毫不费力地处理并发使用。
因此,为了弥补HttpURLConnection提供的不方便的API,我开始在Scala中编写一个新的API,作为一个开源项目。它只是HttpURLConnection的包装器,但与HttpURLConnection不同,它的目的是易于使用。与Apache客户端不同,它应该很容易适应现有项目。与Dispatch不同,它应该很容易学习。
它叫做Bee Client
我为无耻的插头道歉。 :)
答案 5 :(得分:5)
除了调度之外,没有太多东西。 scalaz尝试构建功能性http客户端。但它已经过时了一段时间scalaz7分支中没有它的版本。此外,playframework中还有一个非常有用的wrapper ning async-http-client。你可以在那里打电话:
WS.url("http://example.com/feed").get()
WS.url("http://example.com/item").post("content")
如果您不使用游戏,可以使用此API作为灵感!在您的项目中,不喜欢Dispatch API。
答案 6 :(得分:5)
sttp是我们一直在等待的Scala HTTP库!
它有一个流畅的DSL用于形成和执行请求(来自其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)
它通过可插拔后端支持同步,异步和流媒体调用,包括Akka-HTTP(以前的Spray)和古老的AsyncHttpClient(Netty):
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库。
另外还有一些额外的技巧:
它具有请求和响应的案例类表示(尽管它不具备例如强类型标题): 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
val test = "chrabąszcz majowy"
val testUri: Uri = uri"http://httpbin.org/get?bug=$test"
import com.softwaremill.sttp.circe._
val response: Either[io.circe.Error, Response] =
sttp
.post(uri"...")
.body(requestPayload)
.response(asJson[Response])
.send()
最后,它由软件工厂的可靠人员维护,并且它很棒documentation。
答案 7 :(得分:4)
<强>喷雾强>
你真的应该考虑使用Spray。在我看来,它有一些棘手的语法,但如果你的目标是构建一个高性能的http客户端,它仍然是非常有用的。使用Spray的主要优点是它基于akka actor库,它具有极高的可扩展性和强大功能。只需更改conf
文件,即可将http客户端扩展到多台计算机。
此外几个月前Spray加入Typesafe,据我所知,它将成为基本akka发行版的一部分。 proof
<强> Play2 强>
另一个选项是Play2 WS lib使用(doc)。据我所知,它仍然没有与Play发行版分开,但由于其非常简单,花一些时间附加整个Play框架来获得该部分是值得的。提供配置存在一些问题,因此对于丢弃和使用情况来说这并不是很好。但是,我们在几个非基于Play的项目中使用它,一切都很好。
答案 8 :(得分:1)
答案 9 :(得分:0)
我使用过Dispatch,Spray Client和Play WS Client Library ......它们都不是简单的使用或配置。所以我创建了一个更简单的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
答案 10 :(得分:0)
很惊讶没有人在这里提到过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