Fork me on GitHub
#announcements
<
2020-02-09
>
vemv16:02:53

https://github.com/nedap/utils.modular '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!

vemv16:02:48

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.

just.sultanov19:02:18

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. https://github.com/just-sultanov/clj-unifier

dominicm20:02:45

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

just.sultanov20:02:48

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

cjsauer02:02:03

This is really clever. Thanks for sharing.

cjsauer03:02:40

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

dominicm08:02:27

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

just.sultanov08:02:37

@ 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:

just.sultanov08:02:50

common response types

just.sultanov08:02:55

(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])

just.sultanov08:02:11

and http status types

just.sultanov08:02:58

(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
         success-status-codes
         redirection-status-codes
         client-error-status-codes
         server-error-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."
  [response-type]
  (get response-type->http-status response-type))


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


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


(def default-client-error-type
  "Default unified http `client error` type."
  :bad-request)


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

just.sultanov08:02:34

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

dominicm08:02:48

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

just.sultanov08:02:28

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

just.sultanov08:02:43

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

just.sultanov08:02:45

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

just.sultanov08:02:42

I want to add a similar example to the README

just.sultanov15:02:21

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