component

martinklepsch 2016-07-13T09:34:28.000091Z

For testing I want to provide different implementations of a component but that component does not actually have any kind of lifecycle and instead just implements a simple protocol:

(defrecord StripeApi [token]
  IStripe
  (-request [_ method resource params]
    (let [verb (case method
                 :get http/get
                 :post http/post
                 :delete http/delete)]
      (-> (verb (build-uri resource)
                {:query-params params
                 :basic-auth [token]
                 :as :json})
          (d/catch #(throw (ex-info "Error after calling Stripe API"
                                    {:body (-> % ex-data :body bs/to-string json/decode)
                                     :status (:status %)
                                     :method method :params params}))))))
  component/Lifecycle
  (start [component] component)
  (stop [component] component))
Is there anything wrong with this approach? My thinking is that this will make it easier to swap with a different thing (e.g. an atom that stores requests made). If there are other approaches that serve the same purpose I'd be curious to hear about them as well

stuartsierra 2016-07-13T15:24:23.000092Z

@martinklepsch: That's an intended use case for component. You do not have to implement Lifecycle — there is a default no-op implementation for Object.

stuartsierra 2016-07-13T15:25:04.000093Z

If the component has any dependencies, it must be a record or map.

martinklepsch 2016-07-13T15:27:42.000094Z

@stuartsierra: thanks!

stuartsierra 2016-07-13T15:28:04.000095Z

You're welcome.