Hacer una solicitud HTTP en Scala
scalaz (7)
¿Por qué no utilizar Apache HttpComponents ? Aquí está la aplicación de preguntas frecuentes , que cubre una amplia gama de escenarios.
Estoy tratando de emitir una solicitud POST simple a un servicio web que devuelve algo de XML en Scala.
Parece que Dispatch es la biblioteca estándar utilizada para esta tarea, pero no puedo encontrar documentación para ella. El sitio principal, que vinculo arriba, explica extensamente qué es una promesa y cómo hacer una programación asíncrona, pero en realidad no documenta la API. Hay una tabla periódica , que parece un poco aterradora, pero solo parece útil para las personas que ya saben qué hacer y solo necesitan un recordatorio para la sintaxis críptica.
También parece que Scalaz tiene alguna facilidad para HTTP , pero tampoco puedo encontrar ninguna documentación para él.
Estoy usando dispatch: Dispatch
Acaban de lanzar una nueva versión (0.9.0) con una API nueva que realmente me gusta. Y es asincrónico.
Ejemplo de la página del proyecto:
import dispatch._
val svc = url("http://api.hostip.info/country.php")
val country = Http(svc OK as.String)
for (c <- country)
println(c)
editar: Esto podría ayudarlo https://github.com/dispatch/reboot/blob/master/core/src/main/scala/requests.scala
Otra opción es play-ws de TypeSafe, que es la biblioteca Play Framework WS desglosada como lib independiente:
http://blog.devalias.net/post/89810672067/play-framework-seperated-ws-library
No necesariamente ofrecería esto como la mejor opción, pero vale la pena mencionarlo.
Podría usar spray-client . Falta la documentación (me llevó un poco de investigación para averiguar cómo hacer solicitudes GET con parámetros de consulta ), pero es una gran opción si ya está utilizando el rociado. Y la documentación es mejor que el envío.
Lo estamos utilizando en AI2 por Dispatch porque los operadores son menos simbólicos y ya estamos usando rociadores / actores.
import spray.client.pipelining._
val url = "http://youruri.com/yo"
val pipeline: HttpRequest => Future[HttpResponse] = sendReceive
// Post with header and parameters
val responseFuture1: Future[String] = pipeline(Post(Uri(url) withParams ("param" -> paramValue), yourPostData) map (_.entity.asString)
// Post with header
val responseFuture2: Future[String] = pipeline(Post(url, yourPostData)) map (_.entity.asString)
Si puedo hacer un plug desvergonzado, tengo una API llamada Bee-Client que es simplemente un contenedor en HttpUrlConnection de Scala para Java.
Tuve que hacer lo mismo para probar un punto final (en la prueba de integración). Así que siguiente es el código para obtener respuesta de la solicitud GET en Scala. Estoy haciendo uso de scala.io.Source para leer desde el punto final y ObjectMapper para json para objetar la conversión.
private def buildStockMasterUrl(url:String, stockStatus:Option[String]) = {
stockStatus match {
case Some(stockStatus) => s"$url?stockStatus=${stockStatus}"
case _ => url
}
}
private def fetchBooksMasterData(stockStatus:Option[String]): util.ArrayList[BooksMasterData] = {
val url: String = buildBooksMasterUrl("http://localhost:8090/books/rest/catalogue/booksMasterData",stockStatus)
val booksMasterJson : String = scala.io.Source.fromURL(url).mkString
val mapper = new ObjectMapper()
apper.readValue(booksMasterJson,classOf[util.ArrayList[BooksMasterData]])
}
case class BooksMasterData(id:String,description: String,category: String)
Y aquí está mi método de prueba para el mismo
test("validate booksMasterData resource") {
val booksMasterData = fetchBooksMasterData(Option(null))
booksMasterData.size should be (740)
}
Uso lo siguiente: https://github.com/scalaj/scalaj-http .
Aquí hay una simple solicitud GET:
import scalaj.http.Http
Http("http://foo.com/search").param("q", "monkeys").asString
y un ejemplo de un POST:
val result = Http("http://example.com/url").postData("""{"id":"12","json":"data"}""")
.header("Content-Type", "application/json")
.header("Charset", "UTF-8")
.option(HttpOptions.readTimeout(10000)).asString
Scalaj HTTP está disponible a través de SBT:
libraryDependencies += "org.scalaj" % "scalaj-http_2.11" % "2.3.0"