/docs/01-concepts.md

https://github.com/eed3si9n/gigahorse · Markdown · 125 lines · 92 code · 33 blank · 0 comment · 0 complexity · e90527a4480ac0cf617c8dff90bc65a2 MD5 · raw file

  1. ---
  2. out: concepts.html
  3. ---
  4. [Future]: http://docs.scala-lang.org/overviews/core/futures.html
  5. Basic concepts
  6. --------------
  7. ### Gigahorse
  8. `Gigahorse` is a helper object to create many useful things.
  9. - For OkHttp backend, use `gigahorse.support.okhttp.Gigahorse`.
  10. - For AHC backend, use `gigahorse.support.asynchttpclient.Gigahorse`.
  11. - For Akka HTTP backend, `gigahorse.support.akkahttp.Gigahorse`.
  12. ### HttpClient
  13. The `HttpClient` represents an HTTP client that's able to handle multiple requests.
  14. When it's used it will spawn many threads, so the lifetime of an `HttpClient`
  15. must be managed with care. Otherwise your program will run out of resources.
  16. There are two ways of creating an `HttpClient`.
  17. First is creating using `Gigahorse.http(Gigahourse.config)`.
  18. If you use this with AHC, **you must close** the client yourself:
  19. ```console
  20. scala> import gigahorse._, support.okhttp.Gigahorse
  21. scala> val http = Gigahorse.http(Gigahorse.config)
  22. scala> http.close() // must call close()
  23. ```
  24. Second way is using the loan pattern `Gigahorse.withHttp(config) { ... }`:
  25. ```scala
  26. import gigahorse._, support.okhttp.Gigahorse
  27. Gigahorse.withHttp(Gigahorse.config) { http =>
  28. // do something
  29. }
  30. ```
  31. This will guarantee to close the `HttpClient`, but the drawback
  32. is that it could close prematurely before HTTP process is done,
  33. so you would have to block inside to wait for all the futures.
  34. ### Config
  35. To create an `HttpClient` you need to pass in a `Config`.
  36. `Gigahorse.config` will read from `application.conf` to configure
  37. the settings if it exists. Otherwise, it will pick the default values.
  38. ```console
  39. scala> Gigahorse.config
  40. ```
  41. ### Request
  42. The `Request` is an immutable datatype that represents a single HTTP request.
  43. Unlike `HttpClient` this is relativey cheap to create and keep around.
  44. To construct a request, call `Gigahorse.url(...)` function:
  45. ```console
  46. scala> val r = Gigahorse.url("https://api.duckduckgo.com").get.
  47. addQueryString(
  48. "q" -> "1 + 1",
  49. "format" -> "json"
  50. )
  51. ```
  52. You can chain calls like the above, which keeps returning a new request value.
  53. ### http.run(r, f)
  54. There are many methods on `HttpClient`, but probably the most useful one is
  55. `http.run(r, f)` method:
  56. ```scala
  57. abstract class HttpClient extends AutoCloseable {
  58. /** Runs the request and return a Future of A. Errors on non-OK response. */
  59. def run[A](request: Request, f: FullResponse => A): Future[A]
  60. ....
  61. }
  62. ```
  63. The first parameter take a `Request`, and the second parameter takes a function
  64. from `FullResponse` to `A`. There's a built-in function called `Gigahorse.asString`
  65. that returns the body content as a `String`.
  66. Since this is a plain function, you can compose it with some other function
  67. using `andThen`:
  68. ```console
  69. scala> import gigahorse._, support.okhttp.Gigahorse
  70. scala> import scala.concurrent._, duration._
  71. scala> val http = Gigahorse.http(Gigahorse.config)
  72. scala> val r = Gigahorse.url("https://api.duckduckgo.com").get.
  73. addQueryString(
  74. "q" -> "1 + 1"
  75. )
  76. scala> val f = http.run(r, Gigahorse.asString andThen {_.take(60)})
  77. scala> Await.result(f, 120.seconds)
  78. scala> http.close()
  79. ```
  80. **Note**: Using OkHttp or Akka HTTP, if you don't consume the response body,
  81. you must call `close()` method on the `FullResponse` to let go of the resource.
  82. ### Future
  83. Because `run` executes a request in a non-blocking fashion, it returns a `Future`.
  84. Normally, you want to keep the `Future` value as long as you can,
  85. but here, we will block it to see the value.
  86. One motivation for keeping the `Future` value as long as you can
  87. is working with multiple Futures (HTTP requests) in parallel.
  88. See [Futures and Promises][Future] to learn more about Futures.
  89. ### http.runStream(r, f)
  90. Instead of running on the full reponse,
  91. Gigahorse can also treat the incoming response as a Reactive Stream,
  92. and process them by chunk, for example line by line.