duct

erwinrooijakkers 2020-04-08T16:19:26.021300Z

What is a proper way to provide a different implementation of a boundary in dev versus prod?

erwinrooijakkers 2020-04-08T16:19:31.021500Z

Cannot find an example

erwinrooijakkers 2020-04-08T16:19:58.021900Z

So I want a component to depend on an abstraction

2020-04-08T16:20:08.022200Z

You give the prod and dev implementations different keywords, deriving from the same base.

erwinrooijakkers 2020-04-08T16:20:12.022500Z

And then provide in config what implementation of the abstraction I use

erwinrooijakkers 2020-04-08T16:20:33.022600Z

Is there an example somewhere?

erwinrooijakkers 2020-04-08T16:20:35.022800Z

Thanks 🙂

2020-04-08T16:21:21.023Z

I can’t think of one off the top of my head. Let me sketch one out for you.

erwinrooijakkers 2020-04-08T16:21:40.023200Z

Great I basically have a defprotocol with two implementations

erwinrooijakkers 2020-04-08T16:21:45.023400Z

Two deftypes

2020-04-08T16:23:03.023600Z

Okay, so you’d write init-key methods for both of them:

(defmethod ig/init-key ::dev [_ opts]
  (->DevType opts))

(defmethod ig/init-key ::prod [_ opts]
  (->ProdType opts))

2020-04-08T16:24:11.023800Z

And then in your duct_hierarchy.edn you’d put something like:

{:app.foo/dev [:app/foo]
 :app.foo/prod [:app/foo]}

2020-04-08T16:24:24.024Z

So they derive from the same parent.

2020-04-08T16:24:45.024200Z

Then you put the dev one in your dev profile, and the prod one in your prod profile.

2020-04-08T16:25:03.024400Z

And refer to it using the parent keyword, e.g. #ig/ref :app/foo.

2020-04-08T16:25:46.024600Z

That way the reference will choose whichever key (dev or prod) is in your configuration.

erwinrooijakkers 2020-04-08T19:39:41.024800Z

Thanks took some time to digest and implement, but works like a charm now