git clone 'https://github.com/r0man/cljs-http.git'

(ql:quickload :r0man.cljs-http)

[[https://clojars.org/cljs-http][https://img.shields.io/clojars/v/cljs-http.svg]] [[https://travis-ci.org/r0man/cljs-http][https://travis-ci.org/r0man/cljs-http.svg]] [[http://jarkeeper.com/r0man/cljs-http][http://jarkeeper.com/r0man/cljs-http/status.svg]] [[http://jarkeeper.com/r0man/cljs-http][https://jarkeeper.com/r0man/cljs-http/downloads.svg]]

A HTTP library for [[https://github.com/clojure/clojurescript][ClojureScript]].


** Usage

* Imports

/cljs-http/ returns [[https://github.com/clojure/core.async][core.async]] channels, so you need to import the
=go= macro and the =<!= function.

#+BEGIN_SRC clojure
  (ns example.core
    (:require-macros [cljs.core.async.macros :refer [go]])
    (:require [cljs-http.client :as http]
              [cljs.core.async :refer [<!]]))

* Async response handling

All HTTP functions in /cljs-http/ return a [[https://github.com/clojure/core.async][core.async]]
channel. When a request has completed or failed it is put on that
channel. You can take the response from that channel with the =<!=
function *within* a =go= block.

#+BEGIN_SRC clojure
  (go (let [response (<! (http/get "https://api.github.com/users"
                                   {:with-credentials? false
                                    :query-params {"since" 135}}))]
        (prn (:status response))
        (prn (map :login (:body response)))))

You can pass your own response channel. This is useful when using
a transducers.

#+BEGIN_SRC clojure
  (http/get "http://example.com" {:channel (chan 1 (map :body))})

* Content type

/cljs-http/ can serializes the body of a request and set the
/Content-Type/ header accordingly. You can send the body params in
mutiple formats:

#+BEGIN_SRC clojure
  (http/post "http://example.com" {:edn-params {:foo :bar}})

  (http/post "http://example.com" {:json-params {:foo :bar}})
  ;;(JSON is auto-converted via `cljs.core/clj->js`)

  (http/post "http://example.com" {:transit-params {:key1 "value1" :key2 "value2"}})

  (http/post "http://example.com" {:form-params {:key1 "value1" :key2 "value2"}})

To send form parameters (an array of values):

#+BEGIN_SRC clojure
(http/post "http://example.com" {:form-params {:key1 [1 2 3] :key2 "value2"}})

To upload a file using Multipart parameters:

#+BEGIN_SRC clojure
(http/post "http://example.com" {:multipart-params [["key1" "value1"] ["my-file" my-file]]})

Where =my-file= can be a JavaScript [[https://developer.mozilla.org/en/docs/Web/API/Blob][Blob]] instance

#+BEGIN_SRC clojure
  (def my-file (js/Blob. #js ["<h1>Hello</h1>"] #js {:type "text/html"}))

or a HTML file input field.

#+BEGIN_SRC html
  <input id="my-file" type="file">

#+BEGIN_SRC clojure
  (def my-file
    (-> (.getElementById js/document "my-file")
        .-files first))

If you want to set the name of the file use a vector as =my-file=.

#+BEGIN_SRC clojure
  (def my-file ["myfile" [value filename]])

See [[https://developer.mozilla.org/en-US/docs/Web/API/FormData/append#Syntax][https://developer.mozilla.org/en-US/docs/Web/API/FormData/append#Syntax]] for more details.

* HTTP Basic Authentication

#+BEGIN_SRC clojure
  (http/get "http://example.com" {:basic-auth {:username "hello" :password "world"}})

* OAuth 2.0 Bearer Token

#+BEGIN_SRC clojure
  (http/get "http://example.com" {:with-credentials? false
                                  :oauth-token "SecretBearerToken"})

* Custom Headers (Authorization)

#+BEGIN_SRC clojure
(http/post "https://example.com"
           {:with-credentials? false
            :headers {"Authorization" "SuperSecretToken"}})

* Upload/Download progress monitoring

#+BEGIN_SRC clojure
(let [progress-channel (async/chan)]
  (http/post "http://example.com" {:multipart-params [["key1" "value1"] ["my-file" my-file]] :progress progress-chan}))

The progress-channel will receive progress events: {:directon dir :loaded uploaded_or_downloaded :total size}
- :direction is :upload or :download
- in some cases :total can be missing


#+BEGIN_SRC clojure
  (http/jsonp "http://example.com" {:callback-name "callback" :timeout 3000})

Where =callback-name= is used to specify /JSONP/ callback param
name.  Defaults to "callback". =timeout= is the length of time, in
milliseconds. This channel is prepared to wait for for a request
to complete. If the call is not competed within the set time span,
it is assumed to have failed.

** License

Copyright (C) 2012-2016 r0man

Distributed under the Eclipse Public License, the same as Clojure.