• This repository has been archived on 20/Apr/2018
  • Stars
    star
    69
  • Rank 452,630 (Top 9 %)
  • Language
    Clojure
  • License
    The Unlicense
  • Created almost 9 years ago
  • Updated almost 7 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Multi-target Clojure/script HTTP client

Hail Satan Build Status

Attempts to present a uniform, asychronous client interface for HTTP across JVM / Node / browsers.

Latest documentation / examples

Clojars Project

Features

  • Supports Clojure/JVM, Clojurescript/Node and Clojurescript/Browser
  • Individual deferred values are exposed via promises (kvlt.core), or asynchronous channels (kvlt.chan)
  • core.async-based support for Websockets and Server-sent Events
  • Raw responses available as Javascript typed arrays (on Node, and in browsers with XHR Level 2 support)
  • Ring-like API

Requirements

  • Clojure use requires JDK8

Todo / Notes

  • Automated/CI testing is currently limited to JVM, Node and recent Chrome & Firefox builds
  • No support for streamed requests/responses. Open to suggestions about how this might be handled across platforms
  • Young project, etc. - please file issues

Examples

kvlt.core/request! returns a promesa promise, which can be manipulated using promise-specific (e.g. promesa/then) operations, or treated as a monad using the primitives from cats. Below, we're working with something like:

(ns kvlt.examples
  (:require [kvlt.core :as kvlt]
            [promesa.core :as p]))

The default :method is :get:

(p/alet [{:keys [status]} (p/await (kvlt/request! {:url url}))]
  (is (= status 200)))

Explicit Callback

(p/then
 (kvlt/request! {:url url})
 (fn [{:keys [status]}]
   (is (= status 200))))

core.async

The kvlt.chan namespace parallels the promise-driven kvlt.core, using asynchronous channels to communicate deferred values.

(go
  (let [{:keys [status]} (<! (kvlt.chan/request! {:url url}))]
    (is (= status 200))))

Writing Data

In addition to Ring-style :form-params/:type, metadata may be applied to :body, indicating the desired content-type and body serialization:

(p/alet [{:keys [body]}
         (p/await
          (kvlt/request!
           {:url    url
            :method :post
            :body   ^:kvlt.body/edn {:hello "world"}
            :as     :auto}))]
  (is (= (body :hello) "world")))

:as :auto causes the :body key in the response to be processed in accord with the response's content-type. :as :edn, in this case, would have the same effect.

Errors

(p/catch
 (kvlt/request! {:url (str url "/404")})
 (fn [e]
   (is (= :not-found ((ex-data e) :type)))))

All requests resulting in exceptional response codes, or more fundamental (e.g. transport) errors will cause the returned promise's error branch to be followed with an ExceptionInfo instance - i.e. an Exception/Error with an associated response map retrievable via ex-data.

Example Map

{:headers {:content-type "text/plain" ...}
 :type   :not-found
 :reason :not-found
 :status 404
 ...}

More request/response examples

(def events (kvlt.core/event-source! url))

events is a core.async channel (rather, something a lot like a core.async channel, which'll terminate the SSE connection when async/close!'d).

Assuming no event types or identifiers are supplied by the server, a value on events looks something like:

{:type :message
 :data "String\nfrom\nthe server"}

More SSE examples

Websockets

kvlt.core/websocket! takes a URL, and returns a promise which'll resolve to a core.async channel:

(p/alet [ws (p/await (kvlt/websocket! "http://localhost:5000/ws" {:format :edn}))]
  (go
    (>! ws {:climate :good, :bribery :tolerated})
    (let [instructions (<! ws)]
      (is (instructions :proceed?)))))

Closing the ws channel will terminate the websocket connection.

More Websocket examples

License

kvlt is free and unencumbered public domain software. For more information, see http://unlicense.org/ or the accompanying UNLICENSE file.

More Repositories

1

cljs-lambda

Utilities around deploying Clojurescript functions to AWS Lambda
Clojure
311
star
2

ffmpeg-opengl

Filter for applying GLSL shaders to movies via ffmpeg
C
124
star
3

sputter

Ethereum Virtual Machine (EVM) implementation
Clojure
120
star
4

eulalie

Asynchronous AWS client for Clojure & Clojurescript/Node
Clojure
86
star
5

serverless-cljs-plugin

Serverless plugin for Clojurescript deployment w/ cljs-lambda
JavaScript
73
star
6

hildebrand

Asynchronous DynamoDB client for Clojure & Clojurescript/Node
Clojure
66
star
7

fink-nottle

Asynchronous Clojure/Clojurescript client for Amazon's SNS & SQS services
Clojure
48
star
8

java-unsigned-integers

Optimized, immutable Java implementations of fixed-width, unsigned integers.
Java
31
star
9

chemtrack-example

Clojurescript/Node/Reagent/Lambda Example Application
Clojure
17
star
10

cljs-nodejs-externs

Packaged externs for the Node.js standard library + utilities
Clojure
12
star
11

balonius

Clojure/script Poloniex (cryptocurrency exchange) client
Clojure
11
star
12

cljs-rollbar

Clojurescript/Node-friendly Rollbar client
Clojure
10
star
13

youtube-eliza

Answering the hard questions w/ Clojurescript, AWS Lambda & Slack
Clojure
8
star
14

sns-beanstalk-chat

Clojure
7
star
15

iris-examples

Clojure Iris examples
Clojure
5
star
16

shapeshiftr

Clojure/script shapeshift.io client
Clojure
5
star
17

promesa-check

Utilities for running asynchronous test.check trials
Clojure
4
star
18

cljs-lambda-slack-command

Clojure
2
star
19

aws-polling-task-scheduler

Clojure
2
star
20

glossop

Clojure
1
star
21

fink-nottle-demo

Clojure
1
star
22

thelema

Clojurescript/AWS Mixtape-creating application
Clojure
1
star