Liking cljdoc? Tell your friends :D

com.fulcrologic.fulcro.headless.loopback-remotes

Loopback remote implementations for headless Fulcro applications.

Provides synchronous remote implementations that execute locally (loopback) instead of making network requests:

  • sync-remote - Calls a handler function directly
  • pathom-remote - Integrates with Pathom parsers
  • ring-remote - Simple Ring handler integration
  • fulcro-ring-remote - Full Ring middleware integration with Fulcro's transit encoding
  • mock-remote - Returns canned responses for testing
Loopback remote implementations for headless Fulcro applications.

Provides synchronous remote implementations that execute locally (loopback)
instead of making network requests:

- `sync-remote` - Calls a handler function directly
- `pathom-remote` - Integrates with Pathom parsers
- `ring-remote` - Simple Ring handler integration
- `fulcro-ring-remote` - Full Ring middleware integration with Fulcro's transit encoding
- `mock-remote` - Returns canned responses for testing
raw docstring

delayed-remoteclj

(delayed-remote delegate)

Create a remote that simulates a delayed response.

Useful for testing loading states and timeouts.

Options:

  • :delegate - Remote to delegate to (required)

Example:

(def remote (delayed-remote  (sync-remote handler))
;; do network ops with fulcro
(loopback-remotes/deliver-results! remote)
Create a remote that simulates a delayed response.

Useful for testing loading states and timeouts.

Options:
- :delegate - Remote to delegate to (required)

Example:
```clojure
(def remote (delayed-remote  (sync-remote handler))
;; do network ops with fulcro
(loopback-remotes/deliver-results! remote)
```
sourceraw docstring

deliver-results!clj

(deliver-results! delayed-remote)

Delivers all of the delayed results on a delayed remote synchronously and immediately. In order of original submission.

Delivers all of the delayed results on a delayed remote synchronously and immediately. In order of original submission.
sourceraw docstring

failing-remoteclj

(failing-remote &
                {:keys [status-code error-message body fail-after delegate]
                 :or {status-code 500 body {} fail-after 0}})

Create a remote that always fails with the given status code.

Useful for testing error handling.

Options:

  • :status-code - HTTP status code to return (default: 500)
  • :error-message - Error message to include
  • :body - Response body (default: {})
  • :fail-after - Number of successful requests before failing (default: 0)
  • :delegate - Remote to use for successful requests

Example:

;; Always fail
(failing-remote :status-code 500 :error-message "Server error")

;; Fail after 2 successful requests
(failing-remote
  :fail-after 2
  :delegate (sync-remote handler))
Create a remote that always fails with the given status code.

Useful for testing error handling.

Options:
- :status-code - HTTP status code to return (default: 500)
- :error-message - Error message to include
- :body - Response body (default: {})
- :fail-after - Number of successful requests before failing (default: 0)
- :delegate - Remote to use for successful requests

Example:
```clojure
;; Always fail
(failing-remote :status-code 500 :error-message "Server error")

;; Fail after 2 successful requests
(failing-remote
  :fail-after 2
  :delegate (sync-remote handler))
```
sourceraw docstring

fulcro-ring-remoteclj

(fulcro-ring-remote ring-handler
                    &
                    {:keys [uri request-middleware response-middleware cookies
                            session transit-write-handlers
                            transit-read-handlers]
                     :or {uri "/api"}})

Create a remote that simulates a full Fulcro HTTP remote through a Ring handler.

This provides the same middleware pipeline as the CLJS fulcro-http-remote, but calls a Ring handler directly instead of making HTTP requests.

ring-handler: A Ring handler function (fn [request] response)

Options:

  • :uri - API endpoint URI (default "/api")
  • :request-middleware - Client request middleware chain (fn [handler] wrapped-handler) Defaults to wrap-fulcro-request. Build chains like: (-> (wrap-fulcro-request) (wrap-csrf-token token) (wrap-custom-headers))
  • :response-middleware - Client response middleware chain (fn [handler] wrapped-handler) Defaults to wrap-fulcro-response. Build chains like: (-> (wrap-fulcro-response) (wrap-error-handling) (wrap-logging))
  • :cookies - Initial cookies map to include in requests
  • :session - Session data to include in requests
  • :transit-write-handlers - Additional transit handlers for encoding
  • :transit-read-handlers - Additional transit handlers for decoding

Example with middleware:

(defn wrap-auth-header [handler token]
  (fn [request]
    (handler (update request :headers assoc "Authorization" (str "Bearer " token)))))

(fulcro-ring-remote my-ring-app
  :uri "/api"
  :request-middleware (-> (wrap-fulcro-request)
                          (wrap-auth-header "my-token"))
  :response-middleware (-> (wrap-fulcro-response)
                           (wrap-error-logging)))

Example simulating cookies:

(fulcro-ring-remote my-ring-app
  :cookies {"session" {:value "abc123"}}
  :session {:user/id 1})
Create a remote that simulates a full Fulcro HTTP remote through a Ring handler.

This provides the same middleware pipeline as the CLJS `fulcro-http-remote`,
but calls a Ring handler directly instead of making HTTP requests.

ring-handler: A Ring handler function (fn [request] response)

Options:
- :uri - API endpoint URI (default "/api")
- :request-middleware - Client request middleware chain (fn [handler] wrapped-handler)
                       Defaults to `wrap-fulcro-request`. Build chains like:
                       (-> (wrap-fulcro-request)
                           (wrap-csrf-token token)
                           (wrap-custom-headers))
- :response-middleware - Client response middleware chain (fn [handler] wrapped-handler)
                        Defaults to `wrap-fulcro-response`. Build chains like:
                        (-> (wrap-fulcro-response)
                            (wrap-error-handling)
                            (wrap-logging))
- :cookies - Initial cookies map to include in requests
- :session - Session data to include in requests
- :transit-write-handlers - Additional transit handlers for encoding
- :transit-read-handlers - Additional transit handlers for decoding

Example with middleware:
```clojure
(defn wrap-auth-header [handler token]
  (fn [request]
    (handler (update request :headers assoc "Authorization" (str "Bearer " token)))))

(fulcro-ring-remote my-ring-app
  :uri "/api"
  :request-middleware (-> (wrap-fulcro-request)
                          (wrap-auth-header "my-token"))
  :response-middleware (-> (wrap-fulcro-response)
                           (wrap-error-logging)))
```

Example simulating cookies:
```clojure
(fulcro-ring-remote my-ring-app
  :cookies {"session" {:value "abc123"}}
  :session {:user/id 1})
```
sourceraw docstring

mock-remoteclj

(mock-remote responses
             &
             {:keys [default-response simulate-latency-ms on-unmatched]
              :or {default-response {}}})

Create a remote that returns canned responses.

responses: A map from EQL patterns to response bodies, or a function.

When responses is a map, keys can be:

  • A complete EQL query/mutation (exact match)
  • A mutation symbol (matches any mutation with that symbol)
  • :default - Fallback for unmatched requests

When responses is a function:

  • (fn [eql] response-body-or-nil)
  • Return nil to use default behavior

Options:

  • :default-response - Response for unmatched requests (default: {})
  • :simulate-latency-ms - Add artificial delay
  • :on-unmatched - (fn [eql] response) called for unmatched when no default

Example:

(mock-remote
  {`my-mutation {:result :success}
   [{:users [:user/id :user/name]}] [{:user/id 1 :user/name "John"}]
   :default {}})
Create a remote that returns canned responses.

responses: A map from EQL patterns to response bodies, or a function.

When responses is a map, keys can be:
- A complete EQL query/mutation (exact match)
- A mutation symbol (matches any mutation with that symbol)
- :default - Fallback for unmatched requests

When responses is a function:
- (fn [eql] response-body-or-nil)
- Return nil to use default behavior

Options:
- :default-response - Response for unmatched requests (default: {})
- :simulate-latency-ms - Add artificial delay
- :on-unmatched - (fn [eql] response) called for unmatched when no default

Example:
```clojure
(mock-remote
  {`my-mutation {:result :success}
   [{:users [:user/id :user/name]}] [{:user/id 1 :user/name "John"}]
   :default {}})
```
sourceraw docstring

pathom-remoteclj

(pathom-remote parser & {:keys [env-fn async?]})

Create a remote backed by a Pathom parser.

parser: A Pathom parser function with signature: (fn [env eql] result) OR (fn [eql] result) if env-fn is not provided

Options:

  • :env-fn - (fn [] env) creates parser environment per request. Called fresh for each request to support request-scoped data.
  • :async? - If true, parser returns a core.async channel; blocks via <!!

Example with Pathom 3:

(pathom-remote
  (p/parser {...})
  :env-fn (fn [] {:db (get-db-connection)}))

Example with Pathom 2:

(pathom-remote
  my-pathom2-parser
  :env-fn (fn [] {:request {:session {...}}}))
Create a remote backed by a Pathom parser.

parser: A Pathom parser function with signature:
        (fn [env eql] result)
        OR (fn [eql] result) if env-fn is not provided

Options:
- :env-fn - (fn [] env) creates parser environment per request.
            Called fresh for each request to support request-scoped data.
- :async? - If true, parser returns a core.async channel; blocks via <!!

Example with Pathom 3:
```clojure
(pathom-remote
  (p/parser {...})
  :env-fn (fn [] {:db (get-db-connection)}))
```

Example with Pathom 2:
```clojure
(pathom-remote
  my-pathom2-parser
  :env-fn (fn [] {:request {:session {...}}}))
```
sourceraw docstring

recording-remoteclj

(recording-remote & {:keys [delegate record-atom] :or {record-atom (atom [])}})

Create a remote that records all requests and delegates to another remote.

Useful for verifying what requests were sent during a test.

Options:

  • :delegate - Remote to delegate actual handling to (required)
  • :record-atom - Atom to store recordings (default: creates new atom)

Returns: {:remote the-remote :recordings atom-with-recordings}

Each recording is a map with:

  • :eql - The EQL query/mutation
  • :timestamp - When the request was made
  • :response - The response returned

Example:

(let [{:keys [remote recordings]} (recording-remote
                                    :delegate (sync-remote handler))]
  (set-remote! app :remote remote)
  (comp/transact! app [(my-mutation)])
  (is (= 1 (count @recordings)))
  (is (= 'my-mutation (ffirst (:eql (first @recordings))))))
Create a remote that records all requests and delegates to another remote.

Useful for verifying what requests were sent during a test.

Options:
- :delegate - Remote to delegate actual handling to (required)
- :record-atom - Atom to store recordings (default: creates new atom)

Returns: {:remote the-remote :recordings atom-with-recordings}

Each recording is a map with:
- :eql - The EQL query/mutation
- :timestamp - When the request was made
- :response - The response returned

Example:
```clojure
(let [{:keys [remote recordings]} (recording-remote
                                    :delegate (sync-remote handler))]
  (set-remote! app :remote remote)
  (comp/transact! app [(my-mutation)])
  (is (= 1 (count @recordings)))
  (is (= 'my-mutation (ffirst (:eql (first @recordings))))))
```
sourceraw docstring

ring-remoteclj

(ring-remote ring-handler
             &
             {:keys [uri method content-type headers session encode-fn
                     decode-fn]
              :or {uri "/api"
                   method :post
                   content-type "application/edn"
                   encode-fn pr-str
                   decode-fn read-string}})

Create a remote that invokes a Ring handler.

Simulates a full HTTP round-trip through the Ring middleware stack, which is useful for testing authentication, authorization, and other middleware behavior.

ring-handler: A Ring handler function (fn [request] response)

Options:

  • :uri - API endpoint URI (default "/api")
  • :method - HTTP method (default :post)
  • :content-type - Request content type (default "application/transit+json")
  • :headers - Additional headers to include
  • :session - Session data to include in request
  • :encode-fn - (fn [eql] encoded-body) - defaults to pr-str
  • :decode-fn - (fn [response-body] data) - defaults to read-string

Example:

(ring-remote my-ring-app
  :uri "/api/graphql"
  :session {:user/id 1}
  :headers {"Authorization" "Bearer token"})
Create a remote that invokes a Ring handler.

Simulates a full HTTP round-trip through the Ring middleware stack,
which is useful for testing authentication, authorization, and other
middleware behavior.

ring-handler: A Ring handler function (fn [request] response)

Options:
- :uri - API endpoint URI (default "/api")
- :method - HTTP method (default :post)
- :content-type - Request content type (default "application/transit+json")
- :headers - Additional headers to include
- :session - Session data to include in request
- :encode-fn - (fn [eql] encoded-body) - defaults to pr-str
- :decode-fn - (fn [response-body] data) - defaults to read-string

Example:
```clojure
(ring-remote my-ring-app
  :uri "/api/graphql"
  :session {:user/id 1}
  :headers {"Authorization" "Bearer token"})
```
sourceraw docstring

sync-remoteclj

(sync-remote handler-fn
             &
             {:keys [simulate-latency-ms transform-request transform-response
                     on-error]})

Create a synchronous remote that calls handler-fn directly.

handler-fn: (fn [eql-request] response-body) OR returns a core.async channel that will contain the response

The handler receives the EQL query/mutation as data and should return the response body (the data to merge into app state).

Options:

  • :simulate-latency-ms - Add artificial delay (for testing loading states)
  • :transform-request - (fn [eql] transformed-eql) before calling handler
  • :transform-response - (fn [response] transformed-response) after handler
  • :on-error - (fn [error eql] {:status-code :body}) custom error handling

Example:

(sync-remote
  (fn [eql]
    {:user/id 1 :user/name "John"}))
Create a synchronous remote that calls handler-fn directly.

handler-fn: (fn [eql-request] response-body)
            OR returns a core.async channel that will contain the response

The handler receives the EQL query/mutation as data and should return
the response body (the data to merge into app state).

Options:
- :simulate-latency-ms - Add artificial delay (for testing loading states)
- :transform-request - (fn [eql] transformed-eql) before calling handler
- :transform-response - (fn [response] transformed-response) after handler
- :on-error - (fn [error eql] {:status-code :body}) custom error handling

Example:
```clojure
(sync-remote
  (fn [eql]
    {:user/id 1 :user/name "John"}))
```
sourceraw docstring

wrap-fulcro-requestclj

(wrap-fulcro-request)
(wrap-fulcro-request handler)
(wrap-fulcro-request handler transit-handlers)

CLJ port of the CLJS wrap-fulcro-request middleware. Encodes the request body as transit+json and sets appropriate headers.

Options:

  • :transit-handlers - Additional transit write handlers (map of type to handler)
CLJ port of the CLJS wrap-fulcro-request middleware.
Encodes the request body as transit+json and sets appropriate headers.

Options:
- :transit-handlers - Additional transit write handlers (map of type to handler)
sourceraw docstring

wrap-fulcro-responseclj

(wrap-fulcro-response)
(wrap-fulcro-response handler)
(wrap-fulcro-response handler transit-handlers)

CLJ port of the CLJS wrap-fulcro-response middleware. Decodes transit+json response body back to EDN.

Options:

  • :transit-handlers - Additional transit read handlers (map of tag to handler)
CLJ port of the CLJS wrap-fulcro-response middleware.
Decodes transit+json response body back to EDN.

Options:
- :transit-handlers - Additional transit read handlers (map of tag to handler)
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
Move to previous article
Move to next article
Ctrl+/Jump to the search field
× close