Liking cljdoc? Tell your friends :D


A Clojure(Script) library and DSL for building client to remote service APIs.


Add the following dependency to your project.clj file:

Clojars Project

[com.outpace/remote "0.3.1"] is the last version that uses cljx instead of Clojure 1.7's reader conditionals. If you are on Clojure < 1.7 you'll need to use this version.


Endpoint definitions

;; The url-template specifies that a map containing the key :id must
;; be passed to render the url.
(defendpoint find-user-by-id "/users/:id"
  ;; You *must* specify the HTTP request method for each endpoint. Remote
  ;; does not make assumptions or choose so-called "sane"
  ;; defaults.
  (method :get)

  ;; Set the default headers for each HTTP request made by this endpoint
  ;; function.
  (headers {"X-Foo" "bar"})

  ;; The on-request clause creates the function to be called upon each
  ;; request allowing you to transform it before it is sent. The arity
  ;; of this function must be at least 1 and the first argument will
  ;; always be the request map. Any additional arities in this signature
  ;; are the arguments following the template parameters argument (the
  ;; first) for the returned endpoint function.
  (on-request [req query-params]
    (assoc req :query-params query-params))

  ;; The on-status clause allows you to configure per-status response
  ;; handlers for each HTTP status code.
    ;; Here we transform the response value before placing it on the
    ;; output channel returned by making a request to this endpoint.
    (200 [{:keys [body] :as resp}]
    ;; Returning nil will automatically close the output channel.
    (500 [_] nil)))

This endpoint function can now be called with:

;; The first argument is the template parameters for the url
;; template. The second argument is the query-params argument from the
;; on-request handler we created.
(find-user-by-id {:id 1} {:keys "name,email"})
;; => cljs.core.async.impl.channels.ManyToManyChannel

Service definitions

(defservice user-service
  (headers {"X-Foo" "bar"})

  ;; The on-status clause allows you to configure per-status response
  ;; handlers for each endpoint.
    ;; Always put the data we recieved on the output channel to avoid
    ;; repetitous code.
    (200 [{:keys [body]}]
    (403 [_]

  ;; The endpoint clause allows you to configure service endpoints.
  (endpoint :all "/users"
    (method :get))

  (endpoint :search "/users/search"
    (method :get)
    ;; headers, on-request, and on-status work exactly like they do in
    ;; defendpoint. Here they are scoped to the :search endpoint. Map
    ;; values such as the ones given by headers and on-status are merged
    ;; with the default values specified in the root scope of the
    ;; defservice block.
    (headers {"X-Foo" nil ;; Remove the X-Foo header.
              "X-Bar" "baz"}) ;; Add the X-Bar header.
    (on-request [req query-params]
      (assoc req :query-params query-params))))

This service can now be called with:

;; Like the endpoint function except we pass the endpoint name as the
;; first argument.
(user-service :search {} {:name "bill"})
;; => cljs.core.async.impl.channels.ManyToManyChannel


  • Add message to under top #NEXT section describing change.
  • PRs with tests have a better chance of being accepted.


  1. Set vesion number in project.clj to be version you want released with a -SNAPSHOT suffix.
  2. Run bin/release.

Contributors (alphabetical)


Copyright © Outpace

Released under the Apache License, Version 2.0.

Can you improve this documentation? These fine people already did:
Jake McCrary & Tim Gilbert
Edit on GitHub

cljdoc is a website building & hosting documentation for Clojure/Script libraries

× close