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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="rhcarvalho" data-post="9" data-topic="73845">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/rhcarvalho/48/32243_2.png" class="avatar"> rhcarvalho:</div>
<blockquote>
<p>This difference between the two technologies is not only the cause of different pipelines in Phoenix (plugs vs on_mount)</p>
</blockquote>
</aside>
<p>I agree with your overall point, but I don’t think this part is correct. As hinted by the name, <code>on_mount</code> runs when the connection is mounted. There is little conceptual difference between securing a stateless HTTP request and securing the mount of a socket. In both cases the connection is checked at the beginning and then everything else is authorized by whatever metadata you set on said connection.</p>
<p>The split is a pretty blatant case of accidental complexity, where a new abstraction had to be layered on top of an old one because OG Phoenix/Plug were not designed for LiveView. Phoenix had to maintain backwards compatibility so I’m not saying they made the wrong decision, but the outcome is clearly not what you would choose with a clean slate.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381261" 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/should-there-be-a-client-server-interaction-adapter-api-in-elixir/73845/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-381261" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381261"
                     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="381276" data-post-id="381276">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="GrammAcc" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/GrammAcc/120/40380_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  GrammAcc
                    <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>Interestingly, there actually isn’t any technical difference between securing a websocket connection and securing a stateless HTTP request either. Authentication on a websocket connection has to happen during the initial handshake, and according to the <a href="https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3" rel="noopener nofollow ugc">RFC</a>, the handshake is not required to be performed over HTTP, but since that’s what everything runs, that’s how it’s handled in practice on every server ever. The server can reject the connection before responding with the 101 to switch to the websocket connection, in which case everything stays HTTP.</p>
<p>In practice, handling auth on a websocket connection is a bit different from a regular HTTP request since the browser APIs don’t allow passing arbitrary headers on a websocket handshake (even though the RFC says they are supposed to), but it’s still just a stateless HTTP request until the 101 has been received by the client.</p>
<p>The <code>on_mount/3</code> callback is a <a href="https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/" rel="noopener nofollow ugc">leaky abstraction</a> of the websocket handshake. I actually think that <code>on_mount/3</code> should be named <code>before_connect/3</code> and only run once in the disconnected state. <code>handle_params/3</code> always gets called after the socket is connected anyway, so it makes more sense to load state in that callback and leave <code>on_mount/3</code> for establishing the connection itself. Worst case scenario, there could be a separate <code>on_connect/3</code> callback that gets called after the connection is accepted (<code>{:cont, socket}</code> returned from  <code>before_connect/3</code>) but before the first call to <code>handle_params/3</code>. I think it probably wouldn’t get used much in practice though since the URL params should hold the state of the page, so “initialization” is just whatever data gets loaded when the params map is empty.</p>
<p>Thinking about this, since we have the <code>connected?/1</code> helper function, this connection pattern could actually be implemented in LiveView as-is by simply putting an <code>if !connected?(socket) do </code> at the top of the <code>on_mount/3</code> implementation with no else block. I might try that 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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381276" 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/should-there-be-a-client-server-interaction-adapter-api-in-elixir/73845/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-381276" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381276"
                     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="381278" data-post-id="381278">
  <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="GrammAcc" data-post="13" data-topic="73845">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/grammacc/48/40380_2.png" class="avatar"> GrammAcc:</div>
<blockquote>
<p>The <code>on_mount/3</code> callback is a <a href="https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/" rel="nofollow">leaky abstraction</a> of the websocket handshake. I actually think that <code>on_mount/3</code> should be named <code>before_connect/3</code> and only run once in the disconnected state.</p>
</blockquote>
</aside>
<p>That‘s wrong. LiveViews are mounted many times within a single websocket connection. Each time live navigation happens a LiveView is mounted and on_mount callbacks execute.</p>
<aside class="quote no-group" data-username="GrammAcc" data-post="13" data-topic="73845">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/grammacc/48/40380_2.png" class="avatar"> GrammAcc:</div>
<blockquote>
<p>Interestingly, there actually isn’t any technical difference between securing a websocket connection and securing a stateless HTTP request <a href="https://github.com/phoenixframework/phoenix/pull/6142" rel="nofollow">either.</a></p>
</blockquote>
</aside>
<p>This one is true though. There‘s indeed some history and accidental complexity here. Phoenix‘s <code>socket</code> macro was created when cowboy was the only supported webserver and phoenix integrated channels directly with it. Websocket connections for a long time were not routable on the plug pipeline, but completely separate and only for channels. Once Bandit came along the WebSock abstraction was added to allow for exactly that, but the <code>socket</code> macro was not yet updated to make use of that additional flexibility (see <a href="https://github.com/phoenixframework/phoenix/pull/6142" class="inline-onebox" rel="nofollow">Phoenix.Router based socket routing by LostKobrakai · Pull Request #6142 · phoenixframework/phoenix · GitHub</a>).</p>
<p>So yes there is some opportunity to improve things, but no <code>on_mount</code> is not comparable with the websocket handshake.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381278" 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/should-there-be-a-client-server-interaction-adapter-api-in-elixir/73845/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-381278" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381278"
                     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="381290" data-post-id="381290">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="garrison" src="/assets/icons/user-9f439610.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  garrison
                  </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="14" data-topic="73845">
<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>That‘s wrong. LiveViews are mounted many times within a single websocket connection.</p>
</blockquote>
</aside>
<p>This is true, and ironically it’s what supports the OP’s original point. Navigation over the socket is essentially emulating stateless routing over the stateful connection. Live navigation <em>is</em> a unification of stateful and stateless paradigms.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381290" 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/should-there-be-a-client-server-interaction-adapter-api-in-elixir/73845/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-381290" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381290"
                     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="381307" data-post-id="381307">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="GrammAcc" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/GrammAcc/120/40380_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  GrammAcc
                    <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>Very interesting. I assumed that a navigate event would reconnect the websocket, but I must have misread or simply missed that detail in the docs. Thanks for the correction!</p>
<p>I guess that makes sense though since nested LiveViews have an <code>on_mount/3</code> as well.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="381307" 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/should-there-be-a-client-server-interaction-adapter-api-in-elixir/73845/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-381307" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="381307"
                     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>