Skip to content
jhowarth edited this page Feb 13, 2012 · 10 revisions

Remoting

The file src/lib/cljs/one/browser/remote.cljs contains the one.browser.remote namespace which provides a single function, request, for making HTTP requests to remote servers.

At a minimum, the request function takes id and url arguments. The id must be unique for active requests. That is, you may reuse a request's ID, but only once the request has ended. The url parameter is the URL to connect to. By default, the GET method will be used but the method can be specified by using the :method keyword argument.

The request function simply wraps the send function form Google Closure's goog.net.XhrManager object which has the following description:

"Registers the given request to be sent. Throws an error if a request already exists with the given ID. NOTE: It is not sent immediately. It is queued and will be sent when an goog.net.XhrIo object becomes available, taking into account the request's priority."

Several Valid calls to request are shown below.

(request :my-id "http://localhost/api?a=1")
(request :my-id "http://localhost/api"
         :method "POST"
         :content "a=1")
(request :my-id "http://localhost/api"
         :method "POST"
         :content "a=1"
         :on-success #(js/alert (pr-str %)))

If you have a running ClojureScript REPL connected to the sample application, you can try this out:

(in-ns 'one.browser.remote)
(request :add-name "http://localhost:8080/remote"
         :method "POST"
         :on-success #(js/alert (:body %))
         :content (str "data=" (pr-str {:fn :add-name :args "James"})))

The first time you evaluate this function, you should see the map {:exists false} in the alert box, after that you will see {:exists true}. The add-name service on the server will add a name to a set and return {:exists false} if the name was not already in the set and {:exists true} if it was.

Other optional parameters

Other than the parameters described above, you may also use :headers, :priority and :retries as keyword parameters.

:headers is a map of HTTP request headers to use for this request. For example:

{"Content-Type" "text/html"}

:priority is the priority of this request.

:retries is the maximum number of times the request should be retried.

Callbacks

Two callbacks can be provided which will allow you to process the results of a request asynchronously: :on-success and :on-error.

The :on-success callback will be called if the response code is 200 and the :on-error callback will be called otherwise. This behavior is not technically correct - for example, 201 (Created) is a success code, but will trigger the :on-error callback. This has been fixed in Google Closure, but ClojureScript is currently using a version of Google Closure that does not include the fix. ClojureScript will be updated in the future to include this fix.

The data which is passed to the callback functions contains the keys :id, :body, :status and :event. :id is the ID that was passed to the request function. :body is the result that was sent back from the server, :status is the HTTP response status and :event is the JavaScript event object which contains more information about this response. From the event object you can get the goog.net.XhrIo object and then call any of the functions defined on it.

The example below shows how to get the "Content-Type" header from the response.

(defn show-content-type [{e :event}]
  (js/alert (.getResponseHeader (.xhrIo e) "Content-Type")))
(request :add-name "http://localhost:8080/remote"
         :method "POST"
         :on-success show-content-type
         :content (str "data=" (pr-str {:fn :add-name :args "James"})))

See the documentation for goog.net.XhrManager for more information.

Other examples

See the Controller documentation for an example of how this is used in the sample application.