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


76

我需要一个成熟的HTTP客户端库,它对scala来说是惯用的,用法简洁,语义简单。我看了Apache HTTP和Scala Dispatch以及许多新的库,它们承诺了惯用的Scala包装。Apache HTTP客户端肯定要求冗长,而Dispatch容易造成混乱。

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


1
我建议坚持使用Dispatch。当然,它的可操作性并不符合每个人的喜好(不是我的意思),但它确实不像初看起来那样糟糕,我想它会在一段时间内成为最受欢迎的Scala选项。
特拉维斯·布朗

4
这可能有点题外话,但我认为我们应该使用简单的英语方法名称来进行分派。这并不难做到和维持
Kim Stebel

3
@KimStebel Dispatch 0.9.x可以单独使用简单的英语方法。
Daniel C. Sobral 2012年

Answers:


29

我最近开始使用Dispatch,有点神秘(很棒的一般介绍,严重缺乏基于详细场景/用例的文档)。Dispatch 0.9.1是围绕Ning的Async Http Client的Scala包装器;要完全了解发生了什么,需要向该库介绍自己的知识。在实践中,我真正需要看的唯一一件事是RequestBuilder-其他一切都很好地落入了我对HTTP的理解中。

一旦完成该初始学习曲线,我就很简单地给0.9发布版表示赞许(到目前为止!)。

Dispatch的Http“构建器”是不可变的,并且似乎在线程环境中运行良好。尽管我在文档中找不到任何内容来声明它是线程安全的;一般阅读资料表明确实如此。

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

以下是一些我发现有帮助的其他链接:


2
请注意,运算符的周期表指的是以前的Dispatch的化身,其中大部分已从0.9.x中删除,并且可能不会再出现。
Daniel C. Sobral 2012年

谢谢您的澄清。我使用的工具效果很好:网址生成器快捷方式,POST,'<<'
Richard Sitze 2012年

是的,请求DSL在那里-除了像as.String和之外as.xml.Elem的不是符号的东西,都是转储的响应。
Daniel C. Sobral 2012年


12
为什么会有很多人推荐它?DSL很难理解,文档很差,例子很少,我不能用它做一个最简单的工作演示。
Freewind

29

比较了大多数可用的主要HTTP客户端库

调度和其他一些库不再维护。目前,唯一的严重问题是Spray-clientPlay!WS

spray-client的语法有点奥秘。玩游戏非常易于使用:

(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
Dispatch重新启动了:github.com/dispatch/reboot因此,它再次是一个可行的候选人。如果您可以克服隐秘函数“名称”,那么它是一个非常令人愉快的库。
mvherweg

不玩WS取决于Akka吗?
cdmckay

“ spray-client有点奥秘” -我亲自研究奥术语法,但是它可能会导致某些IDE故障。那就是说,我在IntelliJ IDEAspray-can规范测试中只遇到过一种语法错误。
乔纳森·诺伊费尔德'18

21

在这里参加聚会有点晚了,但是我对Spray-client印象深刻。

它具有用于构建请求的不错的DSL,支持同步和异步执行以及各种(非)编组类型(JSON,XML,表单)。它也可以和Akka一起很好地玩。


4
不幸的是,spray客户指出不支持分块的请求和响应。那么,如何在内存有限的系统中下载或上传非常大的文件呢?(即android&scala)
George Pligoropoulos

3
spray-client取决于spray-canspray-httpspray-httpxspray-util。很好,因为我需要整个Spray堆栈,所以没有外部依赖性。我在将其部署到OSGi容器时也遇到了问题。
Andrii Nemchenko

2
现在,喷雾取决于Akka。
2014年

14

六年后最初回应这篇文章中,我将有一个不同的答案。

我一直在使用akka-http,这是浪花团队和akka团队之间的合作。它得到了Lightbend的支持,与akka异步环境紧密结合……这是完成此任务的正确工具。


1
可悲的是,今天的客户端API文档仍然是空的doc.akka.io/docs/akka-stream-and-http-experimental/1.0-M2/scala/...
瓦尔德马Wosiński

这里的官方客户端的文档的阿卡-HTTP:doc.akka.io/docs/akka-http/10.0.11/scala/http/client-side/...
安德鲁·诺曼

akka-http客户端是作为akka-http-core库的一部分提供的。@WaldemarWosiński提供的实验链接是akka-http的正式客户的初始原型项目。因此,您将要使用akka-http链接,而不是指向孤立的“实验”项目的早期链接。
安德鲁·诺曼

本文比较了几个解决方案来自于2015年11月:implicitdef.com/2015/11/19/...
杰西·奇泽姆

10

在对Apa​​che客户端有一些不愉快的经历之后,我着手编写自己的。内置HttpURLConnection被广泛认为是错误的。但这不是我的经验。实际上,情况正好相反,Apache客户端的线程模型有些问题。从Java6(或5?)开始,HttpURLConnection就提供了有效的HTTP1.1连接,并内置了诸如keep-alive之类的基本功能,并且可以轻松处理并发使用情况。

因此,为了补偿HttpURLConnection提供的不便的API,我着手在Scala中编写一个新API作为开源项目。它只是HttpURLConnection的包装,但是与HttpURLConnection不同,它的目标是易于使用。与Apache客户端不同,它应该容易地适合现有项目。与Dispatch不同,它应该易于学习。

叫做蜜蜂客户端

对于无耻的插件,我深表歉意。:)


我正在尝试将其添加为Maven依赖项,但不走运。也许我必须先添加另一个存储库?
显示名称

出于好奇,您是否能够HttpUrlConnection在每个连接的基础上使用keep-alive ,或者除全局系统属性外,真的没有其他方法吗?
Nicolas Rinaudo 2014年

Config对象具有一个keepAlive布尔值:它控制每个连接是关闭连接还是保持活动状态(bigbeeconsultants.co.uk/docs/bee-client/latest/…)。
Rick-777

这个lib是否仍然维护?到源存储库的链接是无效的,并且似乎没有2.11之后的任何版本的scala的构建。
Martin Gladdish

9

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.Futurescalaz.concurrent.Taskmonix.eval.Task,和cats.effect.IO-所有主要斯卡拉IO单子库。

另外,它还有其他一些技巧:

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的可靠人员维护,并且具有大量文档


5

除了调度外,那里没有太多东西。scalaz尝试构建功能正常的http客户端。但是它已经过时了一段时间,在scalaz7分支中不存在任何版本。此外,在播放框架中还提供了ning async-http-client的有用包装。在那里您可以拨打电话,例如:

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

如果您不使用游戏,则可以将此API用作灵感!在您的项目中,并且不喜欢Dispatch API。


4

喷雾

您确实应该考虑使用Spray。我认为它的语法有些棘手,但是如果您打算构建高性能的HTTP客户端,它仍然非常有用。使用Spray的主要优点是它基于akka actor库,它具有极好的可扩展性和强大的功能。您只需更改conf文件即可将http客户端扩展到多台计算机。

此外,几个月前Spray加入Typesafe,据我了解,它将成为基本Akka发行版的一部分。证明

播放2

另一个选择是Play2 WS lib用法(doc)。据我所知,它仍然没有从Play发行版中分离出来,但是由于其极其简单,值得花一些时间附加整个Play框架来获得这一部分。为它提供配置存在一些问题,因此这对于拖放使用情况而言并不是很好。但是,我们在少数非基于Play的项目中使用了它,一切都很好。



1

感到惊讶的是,没有人提到这里。使用起来超级简单:

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


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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.