Fork me on GitHub
#component
<
2016-07-13
>
martinklepsch09:07:28

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

stuartsierra15:07:23

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

stuartsierra15:07:04

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

stuartsierra15:07:04

You're welcome.