Part of the Lasagna Pattern toolbox.
Remote protocol for pattern-based APIs (GraphQL-like) over HTTP.
Building APIs typically requires defining schemas, writing resolvers, and maintaining separate query languages. This library lets you send patterns directly over HTTP:
;; deps.edn
{:deps {sg.flybot/lasagna-remote {:mvn/version "0.1.0"}}}
;; Leiningen
[sg.flybot/lasagna-remote "0.1.0"]
(require '[sg.flybot.pullable.remote :as remote])
;; Define API function: ring-request → {:data :schema :errors :sample}
(defn my-api [ring-request]
{:data {:posts posts-collection
:users users-collection}
:schema {:posts [:vector Post]
:users [:vector User]}
:errors {:detect :error
:codes {:forbidden 403
:not-found 404}}})
;; Create Ring handler
(def handler (remote/make-handler my-api))
;; Or use as middleware on existing handler
(def app (-> other-handler
(remote/wrap-api my-api {:path "/api"})))
(require '[sg.flybot.pullable.remote.client :as client])
(def api (client/connect "http://localhost:8080/api"))
;; Pull patterns over HTTP
(api '{:posts ?all})
(api '{:posts {{:id 1} ?post}})
(api {:posts {nil {:title "New Post"}}}) ; mutations
;; Introspect schema
(client/schema api)
The function passed to make-handler/wrap-api receives a Ring request and returns:
{:data {...} ; Map of collections/data (required)
:schema {...} ; Malli schema for validation (optional)
:errors {...} ; Error handling config (optional)
:sample {...}} ; Sample data for GET /_schema (optional)
Collections return errors as data: {:error {:type :forbidden :message "..."}}
The :errors config tells the handler how to detect and translate these:
{:detect :error ; keyword: (get result :error)
; or fn: (fn [result] error-map-or-nil)
:codes {:forbidden 403 ; Map error :type to HTTP status
:not-found 404
:invalid 422}}
Example from flybot-site:
(def error-config
{:detect :error
:codes {:forbidden 403
:not-found 404
:invalid-mutation 422}})
Endpoints:
POST /api - Execute pull patternGET /api/_schema - Schema introspectionContent negotiation via Accept/Content-Type:
application/transit+json (default)application/transit+msgpackapplication/ednRequest format:
{:pattern '{:posts ?all}
:params {:user-id 123}} ; optional, replaces $user-id in pattern
Response format:
;; Success: just the bindings
{'all [{:id 1 :title "Hello"}]}
;; Error
{:errors [{:code :forbidden :reason "You don't own this post"}]}
Same as pattern DSL, sent over the wire:
'{:posts ?all} ; List
'{:posts {{:id 1} ?post}} ; Read by key
{:posts {nil {:title "New"}}} ; Create
{:posts {{:id 1} {:title "Updated"}}} ; Update
{:posts {{:id 1} nil}} ; Delete
sg.flybot.pullable.remote)| Function | Signature | Description |
|---|---|---|
make-handler | [api-fn] or [api-fn opts] | Create Ring handler for pull API |
wrap-api | [handler api-fn] or [handler api-fn opts] | Ring middleware that adds pull API |
encode | [value format] | Encode to bytes (for custom clients) |
decode | [bytes format] | Decode from bytes (for custom clients) |
Options: {:path "/api"} (default path)
sg.flybot.pullable.remote.client)| Function | Signature | Description |
|---|---|---|
connect | [url] or [url opts] | Create client function for endpoint |
schema | [api-fn] | Fetch schema from connected API |
url | [api-fn] | Get URL of connected API |
Options: {:format :transit-json, :client http-client}
All commands are run from the repository root (see root README for full task list):
bb rct remote # Run RCT tests only
bb test remote # Run full Kaocha test suite (RCT + integration)
bb dev remote # Start REPL
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |