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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Qqwy" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Qqwy/120/1349_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Qqwy
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>TypeCheck Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/dsignr" rel="nofollow">@dsignr</a></p>
<p>So, to give an example. Say you have a ticket-selling service.</p>
<h4><a name="p-32986-features-1" class="anchor" href="#p-32986-features-1" aria-label="Heading link" rel="nofollow"></a>Features:</h4>
<ul>
<li>Guest must be able to create a User account.</li>
<li>Guest must be able to be authenticated as a certain User.</li>
<li>User must be able to see upcoming shows.</li>
<li>User must be able to buy a ticket, iff the tickets for a certain show are not sold out and the show’s deadline is not yet passed.</li>
<li>The Admin must be able to create new shows with a certain limited number of tickets, the price per ticket, etc. (and some other settings).</li>
</ul>
<p>Now, it might make sense to split this up as follows:</p>
<h3><a name="p-32986-authentication-domain-2" class="anchor" href="#p-32986-authentication-domain-2" aria-label="Heading link" rel="nofollow"></a>Authentication Domain</h3>
<p>This part is used to check if a certain guest can convince the application that they are a certain User. It uses some kind of underwater dispatching (which is an implementation detail and might be changed at any time!) to check:</p>
<ul>
<li>If a user with the given name exists</li>
<li>If this user can be authenticated with the given passprase</li>
</ul>
<p>(possibility to enhance for multi-factor authentication, etc).</p>
<p>When successfull, it returns the symbolic User reference to the outside world, which other domains might use to know that certain actions are (attempted to be) taken by a certain user.</p>
<p>The Authentication Domain asks other parts of the application for certain information. For instance, the User Domain will be asked if the given hashed password matches the one in the user domain user’s hashed password field.</p>
<p>The Authentication Domain does not care about what users actually are or where/how they are stored. (and has no idea about what tickets are at all).</p>
<h3><a name="p-32986-authorization-domain-3" class="anchor" href="#p-32986-authorization-domain-3" aria-label="Heading link" rel="nofollow"></a>Authorization Domain</h3>
<p>This part is used to check if a certain entity can perform a certain action. <em>Some</em> other parts of your application will ask the Authorization domain if the current entity is allowed to do a certain action. The only thing the Authorization Domain knows, is what entities (referenced with some kind of symbolic identifier) are and aren’t allowed to do certain things.</p>
<p>The Authorization Domain consists of some bridges between some of the other domains. To check if a user might alter some user details, we might check if these are details of the current user, or if the current user is an administrator, for instance.</p>
<p>The Authorization Domain does not care what users or tickets actually are.</p>
<h3><a name="p-32986-user-domain-4" class="anchor" href="#p-32986-user-domain-4" aria-label="Heading link" rel="nofollow"></a>User Domain</h3>
<p>Keeps track of general settings of a user, like their e-mail address, name, phone number, etc. A user can alter this information, but only for their own account.</p>
<p>The User Domain uses ‘some form of persistence’ to store user information for later retrieval.</p>
<h3><a name="p-32986-ticket-domain-5" class="anchor" href="#p-32986-ticket-domain-5" aria-label="Heading link" rel="nofollow"></a>Ticket Domain</h3>
<p>The Ticket Domain stores information about shows and the tickets that might still be available. The Ticket Domain knows all about tickets, but not about the rest of the world. The outside world can ask to buy a ticket, which is then linked to a user. The Administration Domain can ask the Ticket Domain to create a new show.</p>
<p>The Ticket Domain doesn’t know what a user is (other than that a user has zero or more tickets that can be returned given the user’s symbolic identifier).</p>
<p>The Ticket Domain uses ‘some form of persistence’ to store shows, and what tickets have already been bought.</p>
<h3><a name="p-32986-administration-domain-6" class="anchor" href="#p-32986-administration-domain-6" aria-label="Heading link" rel="nofollow"></a>Administration Domain</h3>
<p>The Administration Domain wraps the Ticket Domain and the User Domain to show and alter information that only the administrator(s) have access to. Access checking happens using the Authorization Domain, of course.</p>
<h3><a name="p-32986-phoenix-7" class="anchor" href="#p-32986-phoenix-7" aria-label="Heading link" rel="nofollow"></a>Phoenix</h3>
<p>Enter Phoenix. This is just the web representation. All your controller (and channel) actions should do simple ‘flow redirection’, and call one (maybe two) functions inside a domain application, whose result(s) are then forwarded to the view+template layer (or channel broadcasts).</p>
<p>To allow users to authenticate over the internet, a technology like JSON Web Tokens could be used. A separate domain could be set up that handles the wrapping/unwrapping of these tokens that are passed to/from the user session, after which the Authentication and/or Authorization domains are used to find the unwrapped symbolic user reference.</p>
<p>There is no need to make the other domains care about authentication (how a browser session maps to a user).</p>
<h3><a name="p-32986-persistence-8" class="anchor" href="#p-32986-persistence-8" aria-label="Heading link" rel="nofollow"></a>Persistence</h3>
<p>You might have noticed that I wrote ‘some form of persistence’ in multiple places. Because of the separation of these different concerns/domains, it is completely possible to store the list of users in one kind of persistence, and the list of tickets in a completely different kind. Everything will continue to work, regardless of if you use Ecto, MongoDB, ElasticSearch, Erlang Term Storage, a flat serialized file, or an in-memory ephemeral GenServer or Agent for this, because the persistence layers are only implementation details.</p>
<p>If you want to make the persistence layer as swappable as possible, you can go one step further, and use the (functional variant of) the Dependency Inversion Principle; specifying (for each domain/context/application) a persistence-behaviour that a persistence-layer-provider should implement.</p>
<h3><a name="p-32986-consuming-external-apis-9" class="anchor" href="#p-32986-consuming-external-apis-9" aria-label="Heading link" rel="nofollow"></a>Consuming External APIs</h3>
<p>Maybe it is a requirement that we facilitate payments using Stripe, PayPal, iDeal, etc. The only domain that would be hit by this is the Ticket Domain. We could block new tickets from being bought until a pending transaction becomes either successful or failed. The nice thing is that all other parts of the application do not need any changes.</p>
<h3><a name="p-32986-providing-a-public-api-10" class="anchor" href="#p-32986-providing-a-public-api-10" aria-label="Heading link" rel="nofollow"></a>Providing a public API</h3>
<p>Because we have a nice separation of concerns, we already have a good definition of how a public API could look like, and most public Domain functions could be wrapped 1:1 by an API call (for the domains we want to expose, of course).</p>
<h3><a name="p-32986-symbolic-user-reference-11" class="anchor" href="#p-32986-symbolic-user-reference-11" aria-label="Heading link" rel="nofollow"></a>‘Symbolic user reference’</h3>
<p>This could be anything, as long as the different sections of your app agree about what it is. The Authentication Domain uses it to authenticate a user, the User Domain to keep user details up-to-date, the Ticket Domain to associate zero or more tickets with it. This might be a database Identifier, an Unique Universal Identifier, a simple struct, or something else that’s up to you.</p>
<hr>
<p>Something like 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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="32986" data-batch-url="/posts/batch_likers">
                        24
                      </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/understanding-contexts-web-and-ddd/4995/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-32986" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="32986"
                     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 #11"></div>
  </section>
</div>
    <div class="postbit" id="32997" data-post-id="32997">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/qqwy" rel="nofollow">@Qqwy</a> That’s an awesome example of what I was trying to describe, thanks!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="32997" 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/understanding-contexts-web-and-ddd/4995/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-32997" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="32997"
                     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 #12"></div>
  </section>
</div>
    <div class="postbit" id="33535" data-post-id="33535">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dsignr" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/120/5311_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dsignr
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/mjadczak" rel="nofollow">@mjadczak</a> <a class="mention" href="/u/qqwy" rel="nofollow">@Qqwy</a> Thank you both of you for your excellent detailed responses. Loving the community support.</p>
<p>Sorry for my delayed response, was busy traveling. I wanted to patiently craft a detailed response otherwise it would do no justice to both of your time spent helping me out <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 have actually taken the approach you said. So, I have a travel website called ABC.</p>
<p>ABC has the following business domains:</p>
<ol>
<li>The actual users themselves.</li>
<li>Flights, which users can browse / compare.</li>
<li>Hotels where users can stay.</li>
<li>E-Commerce where users can purchase 2 &amp; 3.</li>
<li>Backoffice - Admin for all the above.</li>
</ol>
<p>So, method 1:<br>
I classified my business problem into following domain models:</p>
<ol>
<li>The user domain - Handles auth, user related stuff. (Note: auth is a sub-domain)</li>
<li>Travel - Handles browsing of flights / hotels. (Note: Flight / Hotel is a separate sub-domain)</li>
<li>E-Commerce - Handles Payment, Order management, etc.</li>
<li>CMS - Handles static pages (About, Contact, Blog, etc.)</li>
<li>Dashboard - Backoffice.</li>
</ol>
<p><strong>The routes:</strong><br>
The part where I hit a snag was when I had to maintain authentication across all different domains.<br>
First challenge was handling the routes (which is me recent question posted while I was working on). How do you maintain authenticated and non authenticated routes within each domain?<br>
Because, take flights/hotels for example, I want the users to be able to look at only certain of them. If the price is too low, I would require them to login to view the price. Should I put the routes inside the auth module where it belongs? Or into each individual domain??<br>
So, it quickly became complex to even mentally keep track of what belonged where.</p>
<p><strong>Authentication</strong><br>
Next, the false sense of separation. I really took a weekend off, broke down my application into pieces, drew everything on pen and paper. And it quickly became apparent to me that authentication isn’t really isolated. Why? Because, in reality, session information isn’t isolated - It is persisted through cookies across domains. Whether you’re in CMS, backoffice, flights, hotels, you NEED to be checked for your identity at every point. So, this was also quite challenging.</p>
<p><strong>Cross-domain queries</strong><br>
Another problem I faced is maintaining referential integrity. For example, if I put all the user information into a separate database, now I need to painstakingly write extra code to maintain the referential integrity of the relationship. Because, my other resource (say pages, from CMS) will have a foreign key called <code>user_id</code> and I need to make a query across two databases to make sure this user with <code>user_id</code> exists. I am not sure how you guys are handling this, though. But, I have started working on other domains for now to focus on this one later.</p>
<p>More context:</p><aside class="onebox stackexchange" data-onebox-src="https://stackoverflow.com/questions/4452132/add-foreign-key-relationship-between-two-databases">
  <header class="source">

      <a href="https://stackoverflow.com/questions/4452132/add-foreign-key-relationship-between-two-databases" target="_blank" rel="noopener nofollow ugc">stackoverflow.com</a>
  </header>

  <article class="onebox-body">
      <a href="https://stackoverflow.com/users/538266/sam" target="_blank" rel="noopener nofollow ugc">
    <img alt="Sam" src="https://www.gravatar.com/avatar/9d333a8cf919d26e20a855c968026130?s=256&amp;d=identicon&amp;r=PG" class="thumbnail onebox-avatar" width="256" height="256">
  </a>

<h4>
  <a href="https://stackoverflow.com/questions/4452132/add-foreign-key-relationship-between-two-databases" target="_blank" rel="noopener nofollow ugc">Add Foreign Key relationship between two Databases</a>
</h4>

<div class="tags">
  <strong>sql, sql-server, t-sql, foreign-keys</strong>
</div>

<div class="date">
  asked by
  
  <a href="https://stackoverflow.com/users/538266/sam" target="_blank" rel="noopener nofollow ugc">
    Sam
  </a>
  on <a href="https://stackoverflow.com/questions/4452132/add-foreign-key-relationship-between-two-databases" target="_blank" rel="noopener nofollow ugc">04:12PM - 15 Dec 10 UTC</a>
</div>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>How I’ve built things for now:<br>
In my current setup, every domain is a phoenix app. It has its own database, it has its own controllers inside of that app and every domain has its own views and routes. I love this setup even though it breaks DDD rules because it gives me complete isolation from a business perspective.</p>
<p>I’ve come across threads here where people even separate Ecto into a separate domain. Their views (as you’ve also suggested) into a separate domain. But, to me, it doesn’t sit well because each business entity:</p>
<ol>
<li>is unique.</li>
<li>should be responsible for its own actions.</li>
<li>may have different performance requirements.</li>
</ol>
<p><strong>Uniqueness</strong><br>
Each business domain is unique. For example, my CMS has a live preview feature and uses lot of JS libraries to make that happen, whereas for my ecommerce domain, I don’t need them. That’s why I love my current per-app-phoenix approach. I can afford to install brunch with different requirements <em>in the default</em> folders without having to modify much. IF I had a single application handle all my view level requirements, then it becomes a total pain. Sure, I could still install brunch with different requirements, but now, I need to create ten other namespaced public folders, etc.</p>
<p><strong>Responsibility</strong><br>
Every app should be responsible for its own actions. This means, CMS should know how to get all its pages, Ecommerce should know how to get all its pages and render it to the users. IF there is instead a single app handling all this, then I think it would be vastly difficult to maintain the controllers, glue code to talk to the other apps from a single application when all my business domains in the real world are separated.</p>
<p><strong>Different performance requirements</strong><br>
For example, in my current application (which is based off of an existing application), flights and hotels have extremely high loads, especially during holiday seasons. But, if I put everything into one domain responsible for handling controllers, generating views, it becomes a single point of failure.</p>
<p>If users are searching for a lot of flights during Christmas, then performance degradations are cascaded across all other entities when it shouldn’t have to. For example, if CMS goes down, ecommerce also goes down because view rendering is handled by a single application (the Phoenix app from your example). So, currently, I decided each business unit will take care of rendering it’s own pages, to an extent where duplication is not enforced. So, instead of the wordpress approach where everything is a “page” and stuff is built on top of it, in my application, an ecommerce “product” is totally different from a page, although, they have the same fields (title, content, description, permalink, etc).</p>
<p>So, I’m not singing a “this is the best approach” tune, but this is what I have chosen for now, and I’m still too early in the stages to conclude anything meaningful other than, this definitely seems to work well for me, alas, at the cost of breaking DDD.</p>
<p>Would be interesting to know your thoughts around this.</p>
<p>Thanks for your time.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="33535" 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/understanding-contexts-web-and-ddd/4995/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-33535" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="33535"
                     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 #13"></div>
  </section>
</div>
    <div class="postbit" id="33744" data-post-id="33744">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>You’ve written quite a detailed post, so forgive me if I skip over anything, but here are my impressions on the scenario you’ve proposed.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>I have actually taken the approach you said. So, I have a travel website called ABC.</p>
<p>ABC has the following business domains:</p>
<ol>
<li>The actual users themselves.</li>
<li>Flights, which users can browse / compare.</li>
<li>Hotels where users can stay.</li>
<li>E-Commerce where users can purchase 2 &amp; 3.</li>
<li>Backoffice - Admin for all the above.</li>
</ol>
<p>So, method 1:<br>
I classified my business problem into following domain models:</p>
<p>The user domain - Handles auth, user related stuff. (Note: auth is a sub-domain)<br>
Travel - Handles browsing of flights / hotels. (Note: Flight / Hotel is a separate sub-domain)<br>
E-Commerce - Handles Payment, Order management, etc.<br>
CMS - Handles static pages (About, Contact, Blog, etc.)<br>
Dashboard - Backoffice.</p>
</blockquote>
</aside>
<p>I don’t think that an admin panel / back office is a separate domain here. A domain isn’t a subsection of your website. A domain is a “subsection” of your system or business. This relates to what you said:</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>First challenge was handling the routes (which is me recent question posted while I was working on). How do you maintain authenticated and non authenticated routes within each domain?</p>
</blockquote>
</aside>
<p>Routes don’t belong in a domain. Routes belong in your web interface, and your other domains shouldn’t really care about them. Your core business logic domains shouldn’t care if they are being accessed through a web interface, the command line, or a touchscreen kiosk somewhere. I think the separation of your actual application from the web interface is something you’re still missing in your mental model. <a href="https://youtu.be/lDKCSheBc-8" rel="noopener nofollow ugc">This talk</a> may be useful.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>Should I put the routes inside the auth module where it belongs? Or into each individual domain??</p>
</blockquote>
</aside>
<p>Neither. The routes belong in a web interface layer, built e.g. with Phoenix, which merely interfaces with the system using its API boundaries. All of the other domains shouldn’t know or care that they are being accessed through the web, and hence they will have no concept of routes.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>in reality, session information isn’t isolated - It is persisted through cookies across domains. Whether you’re in CMS, backoffice, flights, hotels, you NEED to be checked for your identity at every point. So, this was also quite challenging.</p>
</blockquote>
</aside>
<p>This ties in with the previous point a bit. Something which I feel many people mistakenly believe about the type of model that is being advocated here is the notion that domains must be completely separate systems that share no data. That is not true. What they should not share is internal implementation details—instead they should communicate through their public interface.</p>
<p>It is true that in the web interface context, the different domains will need access to different types of information about the user. It is true that this information needs to be stored into a session or cookies or some other state by the module that interfaces with the web browser (e.g. Phoenix). However, this does not mean that Phoenix needs to be coupled to these domains.</p>
<p>Instead, it is ok for these domains to return things to be treated as opaque, to be stored and given back later. An example of this might be a User ID. It’s ok for the Phoenix layer to store a User ID somewhere in a session, and provide it to domain modules where needed. It is likewise ok for the Flight Booking domain to hold on to a User ID within its own internal flight booking data. The key here is that these domains never take that ID and directly interface with the database to get user data—instead, they use that ID to ask the Users domain to perform any operations.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>Because, take flights/hotels for example, I want the users to be able to look at only certain of them. If the price is too low, I would require them to login to view the price.</p>
</blockquote>
</aside>
<p>Let’s take this particular example. We’re going have three “Domains” here, Authentication, Authorization and Flights, as well as the web interface, Web.</p>
<p>First, if a user logs in, we handle that at the Web layer by passing their credentials to Authentication and obtaining a <code>user_id</code>, which we store in session. Note that the way we get a <code>User</code> struct is by calling the Users domain—we don’t query the database ourselves.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def login(conn, %{"user" =&gt; username, "pass" =&gt; pass}) do
  case Authentication.auth_with_credentials(username, pass) do
    {:ok, user_id} -&gt;
      conn = put_session(conn, :user_id, user_id)
      user = Users.get_user(user_id)
      render conn, "login_success.html", user: user
    {:error, reason} -&gt;
      render conn, "login_failure.html", reason: reason
  end
end
</code></pre>
<p>Now suppose that a request has come in to the Web interface, and we are inside a Phoenix controller, wanting to handle it. The request is for a “view flights” page.  To render that page, we obviously need to obtain the flight information. As you said, this information will be different for logged in and non-logged in users, but we don’t care about this at the Web layer, as long as we can render a “hidden” flight (e.g. by showing “sign up now to see this deal!”)</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def show_flights(conn, params) do
    # extract the fields we care about, in a format which `Flights` is expecting
    flight_params = sanitize_flight_params(params)

    # we stored user_id in our session if logged in, if not, we use the anonymous user
    user_id = get_session(conn, :user_id) || Authentication.anonymous_user_id()
    flights = Flights.get_flights(params, user_id)
    render conn, "flights.html", flights: flights
end
</code></pre>
<p>Note that we don’t care at this layer even whether we are logged in or not. Even if we are, we simply pass the <code>user_id</code> that we were given from <code>Authentication</code> through to <code>Flights</code>. Note that at no point we’ve assumed what <code>user_id</code> actually is—it could be an integer, an atom, a string, and we don’t need to know!</p>
<p>Now, let’s take a look at the <code>Flights</code> domain itself. Its job is to return flights matching certain parameters. But, if a certain user (for example the anonymous user) is not allowed to see premium flights, they should be marked as hidden.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def get_flights(params, user_id) do
  params
  |&gt; fetch_flight_data() # local helper function
  |&gt; Enum.map(fn flight -&gt;
    if premium_flight?(flight) &amp;&amp; Authorization.cannot?(user_id, :see_premium_flights) do
      %{flight | hidden: true}
    else
      flight
    end
 end)
end
</code></pre>
<p>Again, the <code>Flights</code> domain doesn’t have to care what users actually are or how they work. All it needs is some token for the user that we are returning flights for (<code>user_id</code>) so that it can ask the <code>Authorization</code> domain whether this user is allowed to see premium flights. Likewise, <code>Authorization</code> doesn’t need to know what the <code>:see_premium_flights</code> permission actually means—its only job is to store whether a particular user has that permission or not.</p>
<p>Hopefully that example illustrates what I mean. Also, notice that no domain apart from the web interface actually knows anything about sessions or request. You could easily execute the code inside that controller inside <code>iex</code> and obtain the same results.</p>
<p>Finally, this is only one way to split up the responsibilities across the domains. You may decide that actually <code>Flights</code> shouldn’t know about the fact that some users are not allowed to see premium flights, and instead move that code to the controller itself.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>Another problem I faced is maintaining referential integrity. For example, if I put all the user information into a separate database, now I need to painstakingly write extra code to maintain the referential integrity of the relationship.</p>
</blockquote>
</aside>
<p>Indeed, if you spread data across two databases, you do have to solve that hard problem. I’m not sure why you would though or what it achieves here. It is ok to add referential integrity checks at the database layer, without coding them into the software layer. Suppose that your <code>Authorization</code> permissions lived in a separate table to main user data, and your user profiles were in a separate domain <code>Users</code>. It’s fine to have a foreign key in the auth table to users, because without a user, their authorizations are meaningless. However, at the software layer, you’ll likely model that field in an Ecto schema as <code>field :user_id, :id</code> instead of <code>belongs_to, :user, Users.User</code>, because the second violates your domain at that layer. As I explained before, it is absolutely fine for domains to be passing around and storing opaque tokens belonging to other domains, as long as they don’t peek inside.</p>
<p>This entire thing is a spectrum and as is often the case, extremes have many problems.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>How I’ve built things for now:<br>
In my current setup, every domain is a phoenix app. It has its own database, it has its own controllers inside of that app and every domain has its own views and routes. I love this setup even though it breaks DDD rules because it gives me complete isolation from a business perspective.</p>
</blockquote>
</aside>
<p>You don’t have one system. You have multiple systems, and you’re trying to integrate them as external systems and wondering why you aren’t getting the benefits of having one system. As I said, usually the web layer is just an interface to the system—it is not a separate domain.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>For example, my CMS has a live preview feature and uses lot of JS libraries to make that happen, whereas for my ecommerce domain, I don’t need them</p>
</blockquote>
</aside>
<p>Your CMS and ECommerce domains do not care whether they are being displayed with a live preview or JS libraries. For all they know, they could be called from the command line.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>That’s why I love my current per-app-phoenix approach. I can afford to install brunch with different requirements in the default folders without having to modify much. IF I had a single application handle all my view level requirements, then it becomes a total pain. Sure, I could still install brunch with different requirements, but now, I need to create ten other namespaced public folders, etc.</p>
</blockquote>
</aside>
<p>You can achieve different resources being loaded for different sections of the site in other ways, but the beauty of the model we are explaining is that you can make these decisions after the fact. Because your application is completely separate from your web interface, you can have all of the modules be accessible through one huge website, or run a few smaller websites as separate Phoenix apps, all calling into the appropriate domains. You can even have multiple Phoenix “apps” being handled by one Cowboy server with a properly-written plug.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>This means, CMS should know how to get all its pages</p>
</blockquote>
</aside>
<p>Yes it should.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>Ecommerce should know how to get all its pages and render it to the users.</p>
</blockquote>
</aside>
<p>No, it shouldn’t. It should be able to return a list of products or store pages or categories as a bunch of Elixir data. It’s the job of the web interface to turn that data into HTML that users can see.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>F there is instead a single app handling all this, then I think it would be vastly difficult to maintain the controllers, glue code to talk to the other apps from a single application when all my business domains in the real world are separated.</p>
</blockquote>
</aside>
<p>Indeed it would be difficult, this is the way that people tend to write apps in Rails and this is exactly what we are arguing against <img src="https://forum.elixirforum.com/images/emoji/apple/wink.png?v=15" title=":wink:" class="emoji" alt=":wink:" loading="lazy" width="20" height="20"></p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>For example, in my current application (which is based off of an existing application), flights and hotels have extremely high loads, especially during holiday seasons. But, if I put everything into one domain responsible for handling controllers, generating views, it becomes a single point of failure.</p>
<p>If users are searching for a lot of flights during Christmas, then performance degradations are cascaded across all other entities when it shouldn’t have to. For example, if CMS goes down, ecommerce also goes down because view rendering is handled by a single application (the Phoenix app from your example). So, currently, I decided each business unit will take care of rendering it’s own pages, to an extent where duplication is not enforced. So, instead of the wordpress approach where everything is a “page” and stuff is built on top of it, in my application, an ecommerce “product” is totally different from a page, although, they have the same fields (title, content, description, permalink, etc).</p>
</blockquote>
</aside>
<p>Separating your application into domains is again the solution here. If lots of people are searching for flights, the bottleneck could be at your web interface (in which case spin up more nodes with the web interface running), or the bottleneck could be with your flights backend (sorting through and processing all those flights).</p>
<p>Suppose that to date your whole application has been running on a single server, and suddenly you find that it can’t handle the load of processing all those flights. Because <strong>all</strong> of Flight-related functionality is within a single domain, you can change its internal implementation to actually work with a cluster of nodes behind the scenes to spread out all the work, and as long as you keep the same public interface to <code>Flights</code>, you should be able to get away with little to no code changes anywhere else in your entire application.</p>
<p>The entire point here is decoupling where it makes sense. This includes decoupling access (web) from the system itself.</p>
<aside class="quote no-group" data-username="dsignr" data-post="14" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>at the cost of breaking DDD</p>
</blockquote>
</aside>
<p>The default model “encouraged” by Phoenix 1.3 is not strict DDD. It may adopt some concepts, but the main point is <strong>Phoenix is not your app.</strong>. Build your applications as a bunch of modules and <strong>then</strong> add a web interface on top. Keep the modules self-contained where practical and feasible. You <em>could</em> do proper DDD in Phoenix, but just following these guidelines gets you really far without the overhead that applying a strict model entails.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="33744" data-batch-url="/posts/batch_likers">
                        9
                      </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/understanding-contexts-web-and-ddd/4995/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-33744" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="33744"
                     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 #14"></div>
  </section>
</div>
    <div class="postbit" id="132565" data-post-id="132565">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Gracias !!</p>
<p>Your comment resumes a whole pile of books and web literature about 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="132565" 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/understanding-contexts-web-and-ddd/4995/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-132565" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="132565"
                     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 #15"></div>
  </section>
</div>
    <div class="postbit" id="132646" data-post-id="132646">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dsignr" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/120/5311_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dsignr
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Since you just revived a 2 year old thread, let me just update here that I no longer use umbrella apps anymore as it simply adds a lot of unwanted complexity. I’m saying this after trying out various patterns, many architectures, including micro-services and what not since the last 2 years and I’m absolutely convinced that starting with a single huge monolith app and breaking it as needed (which is rarely needed) is the best way to go. If you’re a small team, umbrella isn’t for you. I still use DDD within the monolith app though.</p>
<p>If umbrella works out for you, then good for you, but it didn’t for me and hence my comment <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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="132646" 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/understanding-contexts-web-and-ddd/4995/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-132646" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="132646"
                     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 #16"></div>
  </section>
</div>
    <div class="postbit" id="132707" data-post-id="132707">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’ve definitely experienced the same thing. Trying to use umbrella’s to break up domain concerns tends to lead towards increased complexity without any real gain. If you’re not using umbrellas for operational reasons (deploying different apps to different nodes, etc.) then your app is all one monolith anyway. Its just a monolith with extra steps and complexity.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="132707" data-batch-url="/posts/batch_likers">
                        4
                      </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/understanding-contexts-web-and-ddd/4995/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-132707" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="132707"
                     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 #18"></div>
  </section>
</div>
    <div class="postbit" id="132743" data-post-id="132743">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="dsignr" data-post="17" data-topic="4995">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/48/5311_2.png" class="avatar"> dsignr:</div>
<blockquote>
<p>I’m absolutely convinced that starting with a single huge monolith app and breaking it as needed (which is rarely needed) is the best way to go.</p>
</blockquote>
</aside>
<p>(2015)</p><aside class="onebox allowlistedgeneric" data-onebox-src="https://martinfowler.com/bliki/MonolithFirst.html">
  <header class="source">

      <a href="https://martinfowler.com/bliki/MonolithFirst.html" target="_blank" rel="noopener nofollow ugc">martinfowler.com</a>
  </header>

  <article class="onebox-body">
    <div class="aspect-image" style="--aspect-ratio:690/388;"><img src="https://martinfowler.com/bliki/images/microservice-verdict/path.png" class="thumbnail" alt="" width="690" height="388"></div>

<h3><a href="https://martinfowler.com/bliki/MonolithFirst.html" target="_blank" rel="noopener nofollow ugc">bliki: Monolith First</a></h3>

  <p>Going directly to a microservices architecture is risky, so consider building a monolithic system first. Split to microservices when, and if, you need it.</p>


  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>That being said discovering optimal bounded contexts inside a monolith isn’t easy (though poorly bounded micro-services are no better) and maintaining the boundaries requires a lot of discipline often challenging whether the “additional effort” is worth it - though the “can I replace this completely in two weeks” heuristic may be a good starting point for choosing initial boundaries.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="132743" data-batch-url="/posts/batch_likers">
                        4
                      </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/understanding-contexts-web-and-ddd/4995/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-132743" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="132743"
                     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 #19"></div>
  </section>
</div>
    <div class="postbit" id="132932" data-post-id="132932">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="dsignr" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/dsignr/120/5311_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  dsignr
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Absolutely. I came across this fowler article too late in my 2 year journey. But let me make this clear - investment of time reading into DDD is not wasted at all, for DDD != Micro services. DDD will help architect your application with sensible logic. There are many good books on DDD, but almost all of them are too verbose and over 300+ pages to even get started, the one book that I personally found useful was this. I tried almost all books on DDD and this is my personal recommendation.</p>
<aside class="onebox amazon" data-onebox-src="https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software-ebook/dp/B00794TAUG">
  <header class="source">

      <a href="https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software-ebook/dp/B00794TAUG" target="_blank" rel="noopener nofollow ugc">amazon.com</a>
  </header>

  <article class="onebox-body">
    <div class="aspect-image" style="--aspect-ratio:690/925;"><img src="https://m.media-amazon.com/images/I/819YH7N-4WL._SL1500_.jpg" class="thumbnail" width="690" height="925"></div>

<h3><a href="https://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software-ebook/dp/B00794TAUG" target="_blank" rel="noopener nofollow ugc">Amazon.com: Domain-Driven Design: Tackling Complexity in the Heart of Software...</a></h3>



<p>Amazon.com: Domain-Driven Design: Tackling Complexity in the Heart of Software eBook : Eric, Evans: Kindle Store</p>

<p>
  
  
  
  
  <strong></strong>
</p>

  </article>

  <div class="onebox-metadata">
    
    
  </div>

  <div style="clear: both"></div>
</aside>

<p>I use <a href="http://www.draw.io" rel="noopener nofollow ugc">www.draw.io</a> to do all my DDD work. Not sure if there are better tools out there specifically for DDD. At least on Mac.</p>
<p>Cheers.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="132932" 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/understanding-contexts-web-and-ddd/4995/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-132932" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="132932"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>