Fork me on GitHub
vemv16:02:53 's implement allows you to: * Use metadata-based protocol extension (for a flawless Reloaded workflow) in a less error-prone manner * accordingly, use Sierra's Component library without defrecord (an usual perceived source of verbosity) * also accordingly, use spec-backed, plain, reusable defns whereas one would otherwise use defrecord and friends, which aren't as tight. There's a handful of similar functions in the lib. Hope some find it useful!


The idea of metadata-based Reloaded comes from an answer I got in Clojurians a year ago for the described problem. Thanks! Has been a smooth trip. It's been satisfying to use older libs (like Component) with newer techniques, as opposed to replacing the libs altogether. As a possibly interesting observation, when something seems flawed maybe it just needs some incremental work, instead of rework.


Hi, there! I just published a library for unified responses for the Clojure and ClojureScript. The practice of using this approach in several projects has proven to be very convenient and flexible.


This is pretty neat, do you have included keyword sets that are supported? Eg cognitect anomalies?


@ In my projects I used keyword sets (from @’s talk about bias decisions), but for the shared library I decided not to restrict users


This is really clever. Thanks for sharing.


Looking at the code, this seems like it could be a general replacement for exceptions. It reminds me of the Result type in Rust.


@ it would be pretty handy for users to include some. Not as a restriction, but to reduce boilerplate in applications. You already have a bunch of keys you can use that way.


@ Thank you for your feedback. I want to add thread macro like a some-> and some->> for pipelines. And I can add something like this:


common response types


(def success-types
  "Unified common `success` types."
  [:success :ok :created :accepted])

(def error-types
  "Unified common `error` types."
  [:error :unavailable :interrupted :incorrect :forbidden :unsupported :not-found :conflict :fault :busy])


and http status types


(def informational-status-codes
  "HTTP `informational` 1xx status codes."
  {:continue            100
   :switching-protocols 101
   :processing          102
   :early-hints         103})

(def success-status-codes
  "HTTP `success` 2xx status codes."
  {:ok                            200
   :created                       201
   :accepted                      202
   :non-authoritative-information 203
   :no-content                    204
   :reset-content                 205
   :partial-content               206})

(def redirection-status-codes
  "HTTP `redirection` 3xx status codes."
  {:multiple-choices   300
   :moved-permanently  301
   :found              302
   :see-other          303
   :not-modified       304
   :use-proxy          305
   :switch-proxy       306
   :temporary-redirect 307
   :permanent-redirect 308})

(def client-error-status-codes
  "HTTP `client error` 4xx status codes."
  {:bad-request                     400
   :unauthorized                    401
   :payment-required                402
   :forbidden                       403
   :not-found                       404
   :method-not-allowed              405
   :not-acceptable                  406
   :proxy-authentication-required   407
   :request-timeout                 408
   :conflict                        409
   :gone                            410
   :length-required                 411
   :precondition-failed             412
   :request-entity-too-large        413
   :request-uri-too-long            414
   :unsupported-media-type          415
   :requested-range-not-satisfiable 416
   :expectation-failed              417})

(def server-error-status-codes
  "HTTP `server error` 5xx status codes."
  {:internal-server-error      500
   :not-implemented            501
   :bad-gateway                502
   :service-unavailable        503
   :gateway-timeout            504
   :http-version-not-supported 505})

(def response-type->http-status
  "HTTP status codes."
  (merge informational-status-codes

(def http-status->response-type
  "Mapping http status to response type."
  (set/map-invert response-type->http-status))

(defn to-status
  "Returns a http status by the given response type."
  (get response-type->http-status response-type))

(defn to-type
  "Returns a response type by the given http status."
  (get http-status->response-type http-status))

(def default-success-type
  "Default unified http `success` type."

(def default-client-error-type
  "Default unified http `client error` type."

(def default-server-error-type
  "Default unified http `server error` type."


@ Will it be convenient for you? For me, yes :)


I think that would be handy yeah :). Do you usually write your keywords in a http style?


No, I have a mapper for business logic keywords with HTTP keywords. And this transformation takes place in one single place. Very comfortably


E.g. :incorrect -> :bad-request


I have one pubic API for my business logic with general response types and several mappers, e.g. for HTTP and WebSocket.


I want to add a similar example to the README


I added -> “thread-first” and ->> “thread-last” macros in the latest release (v0.0.5)