# Using dry-system and dry-transaction in a gem extensibly

**URL:** https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370
**Category:** Support
**Created:** [October 23, 2017, 11:52am UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370 "2017-10-23T11:52:28Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![rickenharp](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/rickenharp/32/12_2.png) [@rickenharp](https://discourse.dry-rb.org/u/rickenharp)
#### Post date: [October 23, 2017, 11:52am UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/1 "2017-10-23T11:52:28Z")

</div>

We’re using dry-system and dry-transaction as the basis for a few of our data transforming microservices. The overall architecture is the same for every service:

1. listen to a pubsub queue for a message
2. take the payload of the message, which is a path, and retrieve the file at that path
3. convert the file from JSON to a data structure
4. validate that data structure
5. instantiate a Google Datastore Entity from the data structure
6. persist the entity
7. go back to listening

Now our idea was to extract a gem that implements everything except steps 4 and 5 so that new services only have to implement validation and entity instantiation themselves.

How would one best go about and structure the gem so that users of the gem can easily inject the relevant steps without too much effort?

---

<div class="post-metadata">

### Author: ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)
#### Post date: [October 23, 2017, 2:39pm UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/2 "2017-10-23T14:39:19Z")

</div>

I recently added support for component providers. It _seems_ like this is what you could use. The feature is [described right here](http://dry-rb.org/gems/dry-system/component-providers/). This means you can simply create a gem, which registers itself as a component provider, then define whatever you need and that’s it. In your microservices you add this gem as a dependency, require it, and use your container to boot dependencies provided by your gem. We have support for configuration too, so each component can describe its settings (keys + types + optional default values), and you can configure your components from within your app.

Let me know if this makes sense 🙂

---

<div class="post-metadata">

### Author: ![rickenharp](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/rickenharp/32/12_2.png) [@rickenharp](https://discourse.dry-rb.org/u/rickenharp)
#### Post date: [October 24, 2017, 8:26am UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/3 "2017-10-24T08:26:26Z")

</div>

This component thing looks interesting, though I am not sure that this is quite what I need. But maybe I’ve been thinking in the wrong direction, I am slowly getting used to the dry.rb way 😉

I’ve set up a simplified example of how the gem code is structured currently [here](https://github.com/rickenharp/transformer), and a sample client that overrides two steps [here](https://github.com/rickenharp/transformer-client). It works, but it feels too… manual compared to the gem code.

Ideally, there would be a way to either overwrite parts of the registered components, or use some sort of symbolic link, like Application[‘validate’] points to either ‘transformer.validate’ or ‘myapp.validate’

---

<div class="post-metadata">

### Author: ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)
#### Post date: [October 24, 2017, 10:55am UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/4 "2017-10-24T10:55:39Z")

</div>

You can nest systems by importing one into another. ie `MyApp::Container.import(core: Core::Container)`. In the future we’ll provide a way to cherry-pick which parts should be imported. Maybe that’s closer to what you need.

---

<div class="post-metadata">

### Author: ![rickenharp](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/rickenharp/32/12_2.png) [@rickenharp](https://discourse.dry-rb.org/u/rickenharp)
#### Post date: [October 24, 2017, 2:49pm UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/5 "2017-10-24T14:49:08Z")

</div>

Okay, in case anyone else runs into the same problem, I have updated the demo repositories with a working solution that seems to work fine. I just had to remember that you can also manually register components, and make the transaction refer to those instead of the auto-registered ones. Now the client just has to make sure to register the missing components themselves.

---

<div class="post-metadata">

### Author: ![modellurgist](https://avatars.discourse-cdn.com/v4/letter/m/97f17d/32.png) [@modellurgist](https://discourse.dry-rb.org/u/modellurgist)
#### Post date: [October 24, 2017, 7:18pm UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/6 "2017-10-24T19:18:57Z")

</div>

Thanks for this component/container providing and nested imports feature ( and the question that prompted the answer ) ! It’s something I needed today to solve a problem. dry-rb keeps on giving, and I’m working on something cool to give back by year’s end.

---

<div class="post-metadata">

### Author: ![gottfrois](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/gottfrois/32/190_2.png) [@gottfrois](https://discourse.dry-rb.org/u/gottfrois)
#### Post date: [January 4, 2018, 3:11pm UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/7 "2018-01-04T15:11:17Z")

</div>

@solnic it would be awesome if you could share some code samples on how a gem would register itself as a component provider using dry-system?

This is what I came with so far [https://gist.github.com/gottfrois/5e8edd540910c3ee8276eb2c76d8ff1a](https://gist.github.com/gottfrois/5e8edd540910c3ee8276eb2c76d8ff1a)

---

<div class="post-metadata">

### Author: ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)
#### Post date: [January 9, 2018, 7:21pm UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/8 "2018-01-09T19:21:24Z")

</div>

OK I’ll put together an example and let you know here

---

<div class="post-metadata">

### Author: ![wilsonsilva](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/wilsonsilva/32/37_2.png) [@wilsonsilva](https://discourse.dry-rb.org/u/wilsonsilva)
#### Post date: [February 23, 2018, 1:21pm UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/9 "2018-02-23T13:21:50Z")

</div>

Is there an example available somewhere?

---

<div class="post-metadata">

### Author: ![solnic](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/solnic/32/779_2.png) [@solnic](https://discourse.dry-rb.org/u/solnic)
#### Post date: [February 23, 2018, 5:32pm UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/10 "2018-02-23T17:32:34Z")

</div>

Not yet, didn’t have time to do it. I’ll get to it eventually.

---

<div class="post-metadata">

### Author: ![mbigras](https://yyz1.discourse-cdn.com/flex031/user_avatar/discourse.dry-rb.org/mbigras/32/241_2.png) [@mbigras](https://discourse.dry-rb.org/u/mbigras)
#### Post date: [March 24, 2018, 6:53pm UTC](https://discourse.dry-rb.org/t/using-dry-system-and-dry-transaction-in-a-gem-extensibly/370/11 "2018-03-24T18:53:55Z")

</div>

Came here after checking out:

> <https://github.com/dry-rb/dry-system/issues/71>

@solnic

Sending you encouragement!  
I’d like to see an example using dry-system in the context of creating a gem.

It would be helpful because learning the way a Ruby gem is structured can be tricky, and involves understanding concepts like [require](https://medium.com/@connorstack/understanding-ruby-load-require-gems-bundler-and-rails-autoloading-from-the-bottom-up-3b422902ca0) and [$LOAD\_PATH](https://stackoverflow.com/questions/837123/adding-a-directory-to-load-path-ruby). Both those concepts are related to dry-system, so an example illustrating using dry-system in the context of a gem would make a nice bridge for people who took the time to figure out how a Ruby gem works, which is probably a lot of people 🙂

Your time is precious, but wanted to express interest in this 👍
