/cljs-http

A ClojureScript HTTP library.

Primary LanguageClojure

cljs-http

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

A HTTP library for ClojureScript.

http://imgs.xkcd.com/comics/server_attention_span.png

Usage

Imports

cljs-http returns core.async channels, so you need to import the go macro and the <! function.

(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 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.

(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.

(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:

(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):

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

To upload a file using Multipart parameters:

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

Where my-file can be a JavaScript Blob instance

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

or a HTML file input field.

<input id="my-file" type="file">
(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.

(def my-file ["myfile" [value filename]])

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

HTTP Basic Authentication

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

OAuth 2.0 Bearer Token

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

Custom Headers (Authorization)

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

Upload/Download progress monitoring

(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

JSONP

(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.