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!

parrot 8
👀 4

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.

❤️ 4

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.

👍 20

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

👍 4

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


This is really clever. Thanks for sharing.

👍 4

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


@U1EQNSHL4 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.

👍 4

@U09LZR36F 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."


@U09LZR36F 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)