Проста та стисла бібліотека клієнта HTTP для Scala


76

Мені потрібна зріла бібліотека клієнта HTTP, яка є ідіоматичною для масштабування, стислою у використанні, простою семантикою. Я розглянув Apache HTTP та Scala Dispatch та численні нові бібліотеки, які обіцяють ідіоматичне обгортання Scala. Клієнт Apache HTTP, безсумнівно, вимагає багатослів'я, тоді як Dispatch легко заплутав.

Що є підходящим HTTP-клієнтом для використання Scala?


1
Я пропоную дотримуватися Dispatch. Звичайно, його експлуатаційна здатність не до смаку кожному (не до мого), але насправді це не так погано, як здається спочатку, і я гадаю, що це буде на деякий час найпопулярнішим варіантом Scala.
Тревіс Браун,

4
Це може бути трохи не в темі, але я думаю, що у нас повинна бути вилка відправки з простими англійськими назвами методів. Це не складно зробити і підтримати
Кім Стебель

3
@KimStebel Dispatch 0.9.x можна використовувати лише з простими англійськими методами.
Daniel C. Sobral

1
Подібне питання - stackoverflow.com/questions/11719373/…
Rick-777,

Відповіді:


29

Нещодавно я почав використовувати Dispatch , трохи загадковий (чудове загальне вступне слово, серйозна відсутність детальних документів на основі сценаріїв / випадків використання). Dispatch 0.9.1 - це обгортка Scala навколо Async Http-клієнта Ning ; щоб повністю зрозуміти, що відбувається, потрібно познайомитись із цією бібліотекою. На практиці єдине, на що мені справді довелося подивитися, це RequestBuilder - все інше добре впадає в моє розуміння HTTP.

Я даю випуску 0.9 тверді пальці вгору (поки що!) Про те, щоб зробити роботу дуже просто .. як тільки ви пройдете цю початкову криву навчання.

"Конструктор" Http диспетчера є незмінним і, здається, добре працює в потоковому середовищі. Хоча я не можу знайти нічого в документах, щоб стверджувати, що він безпечний для потоків; загальне прочитання джерела свідчить про те, що воно є.

Слід пам’ятати, що RequestBuilder можна змінювати , і тому НЕ є потокобезпечним.

Ось кілька додаткових посилань, які я знайшов корисними:


2
Зверніть увагу, що періодична система операторів посилається на попереднє втілення диспетчеризації, і більшість із них відрізано від 0.9.x і, ймовірно, не повернеться.
Daniel C. Sobral

Дякую за це роз'яснення. Те, що я використав, працювало чудово: ярлики для
побудови

Так, запит DSL є - це відповідь, яка була скинута, окрім таких речей, як as.Stringі as.xml.Elem, які не є символами.
Даніель К. Собрал,

Будь ласка , допоможіть мені з моїм новим питанням stackoverflow.com/questions/12342062 / ...
Jesvin Хосе

12
Чому так багато людей рекомендують це? DSL важко зрозуміти, документ поганий, прикладів небагато, я не можу зробити з ним найпростішу робочу демонстрацію.
Freewind

29

Я зробив порівняння більшості основних доступних бібліотек HTTP-клієнтів

Dispatch та деякі інші бібліотеки більше не підтримуються . На сьогодні єдиними серйозними є спрей-клієнт та Play! Зн .

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
Диспетчер перезавантажився: github.com/dispatch/reboot Отже, це знову життєздатний кандидат. Якщо ви зможете здолати загадкові функції "імена", це дуже приємна бібліотека.
mvherweg

Play WS не залежить від Akka?
cdmckay

"spray-client - трохи загадковий" - я особисто копаю загадковий синтаксис, але це може призвести до деяких збоїв в IDE. Тим не менш, я коли-небудь стикався з одним синтаксичним збоєм при IntelliJ IDEA та spray-canтестуванні специфікацій.
Джонатан Нойфельд,

21

Трохи запізнився на вечірку тут, але мене вразив спрей-клієнт .

Він має приємний DSL для побудови запитів, підтримує як синхронізацію, так і виконання асинхронізації, а також різноманітні типи (не) маршалінгу (JSON, XML, форми). Це дуже добре грає і з Аккою .


4
Клієнт спрею, на жаль, заявляє, що фрагментовані запити та відповіді не підтримуються. Отже, як можна завантажувати або завантажувати дуже великі файли в систему з обмеженою пам’яттю? (тобто андроїд і скала)
Джордж Плігоропулос

3
spray-clientзалежить spray-can, spray-http, spray-httpx, spray-util. Добре, що немає зовнішніх залежностей, чому мені потрібен весь стек спреїв. Також у мене були проблеми з розгортанням його в контейнері OSGi.
Андрій Немченко

2
Спрей тепер залежить від Акки.
праворуч

14

Через два шість років після первинної відповіді на цю публікацію я мав би іншу відповідь.

Я використовую akka-http , співпрацю між бригадами спрею та akka. Він підтримується Lightbend, щільно узгоджується з асинхронним середовищем akka ... це правильний інструмент для цієї роботи.


1
На жаль, сьогодні документація клієнта Api все ще порожня doc.akka.io/docs/akka-stream-and-http-experimental/1.0-M2/scala/…
Вальдемар Восінський

ось офіційний документ з боку клієнта для akka-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 року: implicitdef.com/2015/11/19/…
Джессі Чісхольм,

11

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 монади бібліотеки.

Плюс у нього є кілька додаткових хитрощів:

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

  • Він підтримує кодери / декодери для тіл запитів / відповідей, наприклад, JSON через Circe:

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

Нарешті, це підтримується надійними людьми з softwaremill, і у нього є чудова документація .


10

Отримавши кілька нещасних випадків із клієнтом Apache, я взявся за написання власного. Вбудований HttpURLConnection широко затверджується як глючний. Але це не мій досвід цього. Насправді все було навпаки, клієнт Apache мав дещо проблематичну модель різьблення. Починаючи з Java6 (або 5?), HttpURLConnection забезпечував ефективні з'єднання HTTP1.1 з такими важливими речами, як вбудована підтримка "живого", і він без зайвих зусиль обробляє одночасне використання.

Отже, щоб компенсувати незручний API, запропонований HttpURLConnection, я взявся написати новий API у Scala як проект з відкритим кодом. Це просто обгортка для HttpURLConnection, але на відміну від HttpURLConnection, вона прагне бути простою у використанні. На відміну від клієнта Apache, він повинен легко вписуватися в існуючий проект. На відміну від Dispatch, це повинно бути легким для вивчення.

Це називається Bee Client

Прошу вибачення за безсоромну пробку. :)


Я намагаюся додати це як залежність від Maven, не пощастило. Може, я повинен спочатку додати інше сховище?
Відображуване ім’я

З цікавості ви змогли використати HttpUrlConnectionфункцію підтримання життя на основі кожного підключення, чи насправді немає іншого способу, окрім властивості глобальної системи?
Ніколас Рінаудо

ConfigОб'єкт має keepAliveлогічне значення: він контролює з'єднання , повинні бути закриті або зберігатися активності на основі кожного з'єднання ( bigbeeconsultants.co.uk/docs/bee-client/latest / ... ).
Rick-777

Ця бібліотека все ще зберігається? Посилання на джерело репо перестає бути, і, схоже, не існує збірки для будь-яких версій Scala пізніше 2.11.
Мартін Гладіш

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

Спрей

Ви дійсно повинні розглянути можливість використання спрею . На мій погляд, у нього трохи хитрий синтаксис, але він все ще досить корисний, якщо ви прагнете створити високопродуктивний http-клієнт. Головною перевагою використання Spray є те, що він базується на бібліотеці акторів akka , яка надзвичайно масштабована та потужна. Ви можете масштабувати свій клієнт http на кілька машин, лише змінюючи confфайли.

Більше того, кілька місяців тому Spray приєднуйтесь до Typesafe, і, наскільки я розумію, він стане частиною базового розповсюдження akka. доказ

Грати2

Іншим варіантом є використання бібліотеки Play2 WS ( 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 ... Жоден з них не був просто використаний або налаштований. Тож я створив простішу бібліотеку 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.