title: Ring Middleware for the Client Side?
body: <p>Usually Ring middleware is associated with the use on the server side. 
  In the post I'll discuss how the concept of ring middleware can be applied to http clients.</p>
  
  <p>A very typical server side example might look like this:</p>
  
  <pre><code>(def server
    (-&gt; server-handler
        wrap-transit-params
        wrap-transit-response))
  </code></pre>
  
  <p>Desugared:</p>
  
  <pre><code>(def server (wrap-transit-response (wrap-transit-params handler)))
  </code></pre>
  
  <p><code>server</code> is a function now, which accepts a request hash-map. Middleware can operate on this data before its send to the handler. It can also operate on the response hash-map that the handler returns. Or on both. It can even manipulate the execution of the handler.</p>
  
  <p><strong>Server</strong></p>
  
  <p>The above middleware could look like this in a very simplified way:</p>
  
  <p>(1.) This operates on data before it gets to the actual handler (request, incoming data), parsing the body and providing the result as value to the :params key. It's called pre-wrap.</p>
  
  <pre><code>(defn wrap-transit-params [handler]
    (fn [req]
      (handler (assoc req :params (from-transit-str (req :body))))))
  </code></pre>
  
  <p>(2.) This one manipulates the outgoing data, the response of the server, outgoing data. - It's a post-wrap.</p>
  
  <pre><code>(defn wrap-tranist-response [handler]
    (fn [req]
      (let [resp (handler req)]
        (update resp :body to-transit-str))))
  </code></pre>
  
  <p>With this a server can receive and respond data as transit. </p>
  
  <p><strong>Client</strong></p>
  
  <p>The same behavior could be desirable for an http-client.</p>
  
  <pre><code>(def client
    (-&gt; client-handler
        wrap-transit-params
        wrap-transit-response))
  </code></pre>
  
  <p>It turns out that the above middleware cannot easily be reused as client middleware, even though there is some symmetry.</p>
  
  <p>For the client-side they should be implemented like this:</p>
  
  <pre><code>(defn wrap-transit-params [handler]
    (fn [req]
      (handler (assoc req :body (to-transit-str (req :params))))))
  
  (defn wrap-transit-response [handler]
    (fn [req]
      (let [resp (handler req)]
         (update resp :body from-transit-str)))) 
  </code></pre>
  
  <p>Now it could be used like this:</p>
  
  <pre><code>(client {:url "http://..."
           :params {:one #{1 2 3}}})
  </code></pre>
  
  <p>Since in reality there would be much more things invloved, so I think having reusable middleware for both server and client side is utopian.</p>
  
  <p>Though it remains up to discussion if the concept generally makes sense for clients. I could not find any client side middleware on the net.</p>
  
  <p>The server side middleware is usually under the namespace <code>ring.middleware...</code> My concrete question here is if a library providing client side middleware should use this namespace or not. </p>