<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="180166" data-post-id="180166">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Apemb" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Apemb/120/18264_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Apemb
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Oh well, that one was not easy…</p>
<p>The way we did it was to use a DDD tactical design pattern : the aggregate. Long story short, it is (as the name suggests) an aggregate of multiple structs, that actually “change as one”. There is quite a bit to the story, but I feel it is not the space to discuss that, and I am not really an expert on DDD. I could find links for you to look into DDD - I wrote down two books at the end.</p>
<p>The interesting part is that this big struct, the aggregate, is part of the domain, and is designed to represent one business transaction that is either fully successful or a complete failure. A business transaction is one aggregate change. When given to save to the aggregateRepository module, that aggregate is transformed into a changeset spawning multiple tables. That is the way we made it work. No Ecto leakage outside the Infra module, the transaction is that changeset.</p>
<p>So the problem in the infrastructure is solved by a more complex design of the domain struct, and as they are quite complex and do not look much like what is the database, have adapters that do have a bit of logic - transforming the tables into the aggregate is easy, transforming the aggregate into a changeset that is not fun.. I think we would do a different and much simpler database schema if we had to do it again.<br>
Those aggregates are also the reason why the query part of the application came to life, as manipulating those big aggregates for a small read was increasingly painful performance wise. (Some of our aggregates needed a join query of more than 10 different tables…)</p>
<p>Yet again, I think it was worth it, because following the DDD teachings is about more than technicalities, and more about a better way to communicate with the business persons the team works with. The aggregate reacts like the concept the stakeholder say its business concept does. It has the same name, works the same way. The price you have to pay is plumbing, and in our case a read part of the application.</p>
<p>I encourage you to read Eric Evans’ “Domain-Driven Design: Tackling Complexity in the Heart of Software” Book or the shorter “Domain Driven Design Distilled” by Vaughn Vernon. (I read the short one, and I should do it again because I feel I missed some parts). Either one will help you understand the philosophy behind the aggregate <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>Sorry to answer your question by a concept that takes a book to understand, if I knew how to explain it better I would, but really I am not yet able to summarise DDD in one blog post ^^. Maybe in a year or two.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180166" data-batch-url="/posts/batch_likers">
                        6
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-180166" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180166"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #21"></div>
  </section>
</div>
    <div class="postbit" id="180203" data-post-id="180203">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Quite interesting all of that. <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>I was about to suggest you use <code>Ecto.Multi</code> creating functions to actually have an Ecto-backed business transactions but then I saw you wanted them to have module/function names that correspond to what the business stakeholders call these business operations so I guess that wouldn’t be a good suggestion.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180203" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-180203" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180203"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #22"></div>
  </section>
</div>
    <div class="postbit" id="180209" data-post-id="180209">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="LostKobrakai" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/LostKobrakai/120/3072_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  LostKobrakai
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="anthonator" data-post="21" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/anthonator/48/14467_2.png" class="avatar"> anthonator:</div>
<blockquote>
<p>In more recent hexagonal-ish builds I opted to use Ecto directly in the core and deal with the testing/coupling consequences.</p>
</blockquote>
</aside>
<p>To be fair it depends on what you don’t want to be coupled to. If it’s “the DB” then <code>MyApp.Repo</code> is an implementation of the <code>Ecto.Repo</code> behaviour already and therefore decoupled. You can implement non db based/mocked repos. The biggest complexity with that approach are likely the functions arguments you need to handle – especially anything <code>Ecto.Query</code>. They can’t be well inspected and be acted upon without having a proper db (sql) to handle them. Thankfully almost all functions a repo has to deal with need <code>Ecto.Queryable</code>s and not <code>Ecto.Query</code>s. So your core could build domain specific structs, which are queryables, which are expectable/testable, and only the protocol implementation deals with converting those structs into actual <code>Ecto.Query</code>s, which db based Repos use.</p>
<aside class="quote no-group" data-username="anthonator" data-post="21" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/anthonator/48/14467_2.png" class="avatar"> anthonator:</div>
<blockquote>
<p>We also never really figured out a good way to handle transactions.</p>
</blockquote>
</aside>
<p>This is where <code>Ecto.Multi</code> becomes useful. It allows you to wrap business operations into a structure you can combine for transactional consistancy.</p>
<p>All in all it should be possible to build a project, which applies the ideas of hexagonal architecture, where the db and querying it is not part of the core, but you can code the core using most of ecto’s api.</p>
<p>It becomes a whole lot more work if you want do be decoupled from ecto though.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180209" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-180209" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180209"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #23"></div>
  </section>
</div>
    <div class="postbit" id="180213" data-post-id="180213">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="LostKobrakai" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/LostKobrakai/120/3072_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  LostKobrakai
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I just tried that out and tbh I don’t even think it’s that bad:</p>
<p><a href="https://github.com/LostKobrakai/testing_ecto" class="onebox" target="_blank" rel="noopener nofollow">https://github.com/LostKobrakai/testing_ecto</a></p>
<p>I mean I’m not sure how bad the mocking might become in a more complex setting, but the sql stuff is cleanly separated from the business logic. Might do this more often from now on.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180213" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-180213" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180213"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #24"></div>
  </section>
</div>
    <div class="postbit" id="180216" data-post-id="180216">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="anthonator" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/anthonator/120/14467_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  anthonator
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="LostKobrakai" data-post="24" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>It becomes a whole lot more work if you want do be decoupled from ecto though.</p>
</blockquote>
</aside>
<p>Yes, this is where it gets tricky. <a class="mention" href="/u/apemb" rel="nofollow">@Apemb</a> above mentioned no Ecto leakage outside of the infrastructure portion of the application. This is similar to what we did. We never found a good way to take advantage of the power of Ecto’s API in this situation (e.g. <code>Ecto.Multi</code>).</p>
<p>What you described is more or less how I’ve been doing it recently. At a certain application/team size I think abstracting out the database can be a fool’s errand. I always create a nice public interface with domain structs that are used to communicate with the outside world (e.g. Phoenix) but I don’t shy away from using Ecto in the application core. I just haven’t found it to be worth it. I do abstract out calls to 3rd party API’s using a port/adapter pattern.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180216" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-180216" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180216"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #25"></div>
  </section>
</div>
    <div class="postbit" id="180217" data-post-id="180217">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="LostKobrakai" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/LostKobrakai/120/3072_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  LostKobrakai
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="anthonator" data-post="26" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/anthonator/48/14467_2.png" class="avatar"> anthonator:</div>
<blockquote>
<p>Yes, this is where it gets tricky. <a class="mention" href="/u/apemb" rel="nofollow">@Apemb</a> above mentioned no Ecto leakage outside of the infrastructure portion of the application. This is similar to what we did. We never found a good way to take advantage of the power of Ecto’s API in this situation (e.g. <code>Ecto.Multi</code> ).</p>
</blockquote>
</aside>
<p>“no Ecto leakage outside of the infrastructure” and “We never found a good way to take advantage of the power of Ecto’s API” sound like a contradition. How would you expect to use ecto api, but not “leak ecto”?</p>
<aside class="quote no-group" data-username="anthonator" data-post="26" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/anthonator/48/14467_2.png" class="avatar"> anthonator:</div>
<blockquote>
<p>At a certain application/team size I think abstracting out the database can be a fool’s errand.</p>
</blockquote>
</aside>
<p>Abstracting the actual database integration away is a good thing. Abstracting knowledge about persistance away I’d say is a fool’s errand. Especially for all those webapps, which are essentially just glorious excel sheets. It makes no sense to have the core of an application be unaware of persistance, when all it does is manage data going in/out of it.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180217" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-180217" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180217"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #26"></div>
  </section>
</div>
    <div class="postbit" id="180219" data-post-id="180219">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="anthonator" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/anthonator/120/14467_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  anthonator
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="LostKobrakai" data-post="27" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>“no Ecto leakage outside of the infrastructure” and “We never found a good way to take advantage of the power of Ecto’s API” sound like a contradition. How would you expect to use ecto api, but not “leak ecto”?</p>
</blockquote>
</aside>
<p>Right, siloing Ecto into the infrastructure portion of your application makes it difficult to take advantage of Ecto’s powerful API.</p>
<aside class="quote no-group" data-username="LostKobrakai" data-post="27" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>Abstracting knowledge about persistance away I’d say is a fool’s errand.</p>
</blockquote>
</aside>
<p>Yes, this is what I meant.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180219" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-180219" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180219"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #27"></div>
  </section>
</div>
    <div class="postbit" id="180223" data-post-id="180223">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="al2o3cr" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/al2o3cr/120/3457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  al2o3cr
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="LostKobrakai" data-post="27" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>“no Ecto leakage outside of the infrastructure” and “We never found a good way to take advantage of the power of Ecto’s API” sound like a contradition. How would you expect to use ecto api, but not “leak ecto”?</p>
</blockquote>
</aside>
<p>I’ve seen those goals accomplished simultaneously in Ruby before - it led to a base layer of ActiveRecord models (with a scorching case of <a href="https://www.martinfowler.com/bliki/AnemicDomainModel.html" rel="nofollow">AnemicDomainModel</a> because the classes were glorified DTOs), an intermediate layer that mostly just copied ActiveRecord data into plain Ruby objects because Abstraction, and then an ever-widening layer of module functions on top that used AR functions to get results and then translate them to POROs.</p>
<p>The phrase “in case we want to swap out ActiveRecord” was said at <em>least</em> five times a day. <img src="https://forum.elixirforum.com/images/emoji/apple/upside_down_face.png?v=15" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20"></p>
<p>IMO there are two overlapping reasons to not worry so much about “wrapping Ecto”: if the application controls the database (via migrations etc) it’s not really the same thing as the “external dependencies” that need decoupling against unexpected changes, and Ecto is <em>already</em> essentially an “adapter pattern” on top of the raw database layer.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180223" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-180223" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180223"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #28"></div>
  </section>
</div>
    <div class="postbit" id="180286" data-post-id="180286">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dimitarvp" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/120/38664_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dimitarvp
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Reading <a class="mention" href="/u/al2o3cr" rel="nofollow">@al2o3cr</a> and <a class="mention" href="/u/lostkobrakai" rel="nofollow">@LostKobrakai</a> made me think that in the rare cases where I care about isolation I just try and make sure that I don’t depend on stuff provided by <code>ecto_sql</code> (and even that can be very hard as <a class="mention" href="/u/lostkobrakai" rel="nofollow">@LostKobrakai</a> pointed out). Depending on <code>ecto</code> itself is completely fine – because it does not deal with a specific database.</p>
<p>Leak-less isolation is IMO a pipe dream. Sure it might accelerate your tests but at what cost? Eventually you’ll fail accounting for something that only a live database does and then your tests become more or less worthless. Which is what a lot of unit tests out there are anyway – just a wishful thinking of the dev.</p>
<p>As for the so-called business transactions… meh. Just use <code>Ecto.Multi</code> and stop sweating about it. Ecto is a fantastic and well-tested library. If you go to such levels of paranoia you might as well ditch the interpreted language and VM concepts altogether and go lower-level: to C++, D, Rust, OCaml, Nim, Haskell etc.</p>
<aside class="quote no-group" data-username="al2o3cr" data-post="29" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/al2o3cr/48/3457_2.png" class="avatar"> al2o3cr:</div>
<blockquote>
<p>The phrase “in case we want to swap out ActiveRecord” was said at <em>least</em> five times a day. <img src="https://forum.elixirforum.com/images/emoji/apple/upside_down_face.png?v=15" title=":upside_down_face:" class="emoji" alt=":upside_down_face:" loading="lazy" width="20" height="20"></p>
</blockquote>
</aside>
<p>LOL, hits too close to home for the teams I’ve worked with in my six years of Rails work. People just love to pretend that they can swap any part of their app anytime they want – including when this part is a hugely important piece without which most of their app wouldn’t be anything more than a student exercise (since, you know, real-world apps want to persist data).</p>
<p>I get the motivation but IMO a lot of teams get carried away and forget where to draw the line.</p>
<aside class="quote no-group" data-username="LostKobrakai" data-post="27" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/lostkobrakai/48/3072_2.png" class="avatar"> LostKobrakai:</div>
<blockquote>
<p>Especially for all those webapps, which are essentially just glorious excel sheets.</p>
</blockquote>
</aside>
<p>Now that’s a <strong><em>fact</em></strong> (it’s “glorified” btw, not “glorious”). I’d bet a few beers that a lot of apps out there can be rewritten in any language with an Airtable connector library and that they might work even better compared to the originals (and I include Phoenix app in this category as well).</p>
<p>Web frameworks are in general supposed to bring additional value over the basic “HTTP router to controller code with some views and templates sprinkled in” but many people stop at that point which turns into an epic fight that boils down to “how do we put this square peg into the round hole”.</p>
<p>As I get older I start finding myself thinking how do I make web apps with almost no code and just clever integration between several services. It’s possible, actually.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180286" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-180286" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180286"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #29"></div>
  </section>
</div>
    <div class="postbit" id="180289" data-post-id="180289">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="LostKobrakai" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/LostKobrakai/120/3072_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  LostKobrakai
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group quote-modified" data-username="dimitarvp" data-post="30" data-topic="32225">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dimitarvp/48/38664_2.png" class="avatar"> dimitarvp:</div>
<blockquote>
<p>Web frameworks are in general supposed to bring additional value over the basic “HTTP router to controller code with some views and templates sprinkled in” …</p>
</blockquote>
</aside>
<p>To be fair this wasn’t actually meant as a bashing of simple web applications. Web applications can bring business value just by presenting data in a more practical way than a bunch of tabular sheets and without any fancy stuff on the backend. What I wanted to say is that in such cases people need to acknowledge the fact that their core business domain is moving data in and out of some database (airtable is just another db tbh) and there’s no sense in trying to abstract away the fact one is dealing with some kind of persistance.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="180289" data-batch-url="/posts/batch_likers">
                        2
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/hexagonal-architecture-in-elixir/32225/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-180289" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="180289"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #30"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/32225/load_more?page=4">Load more posts (5 remaining)</a>
</div></template></turbo-stream>