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


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="arjan" data-post="31" data-topic="2050">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/arjan/48/2737_2.png" class="avatar"> arjan:</div>
<blockquote>
<p>Any suggestion on how to address this?</p>
</blockquote>
</aside>
<p>Let me get back to you in a day 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="22172" 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/nicest-way-to-emulate-function-decorators/2050/32">Post #31</a>
	                </div>
	            </div>
              <div id="likers-container-22172" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="22172"
                     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 #31"></div>
  </section>
</div>
    <div class="postbit" id="22182" data-post-id="22182">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Only supporting decorators for public functions would be an acceptable restriction.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="22182" 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/nicest-way-to-emulate-function-decorators/2050/33">Post #32</a>
	                </div>
	            </div>
              <div id="likers-container-22182" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="22182"
                     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 #32"></div>
  </section>
</div>
    <div class="postbit" id="22202" data-post-id="22202">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="josevalim" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/josevalim/120/1787_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  josevalim
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Creator of Elixir</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>We have removed the warning on the v1.4 branch. On the upcoming v1.4.1, private functions will be once again overridable without warnings.</p>
<p>On master we have cleaned up the implementation and we also allow private macros to be overridable (something that was never supported).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="22202" 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/nicest-way-to-emulate-function-decorators/2050/34">Post #33</a>
	                </div>
	            </div>
              <div id="likers-container-22202" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="22202"
                     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 #33"></div>
  </section>
</div>
    <div class="postbit" id="32868" data-post-id="32868">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Reviving this one because I’m really excited about <a class="mention" href="/u/arjan" rel="nofollow">@arjan</a>’s decorator lib, and yet <a class="mention" href="/u/josevalim" rel="nofollow">@josevalim</a> <a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a> and <a class="mention" href="/u/benwilson512" rel="nofollow">@benwilson512</a> all expressing discontent over this pattern.</p>
<p>We want to use decorators to perform validation on controller actions and channel functions; we are using elixir/phoenix strictly as a realtime data api that has a mixed surface of both REST and websockets (no forms, js, templates, assets, etc). We need to validate passed-in params for data integrity, example: an <code>AuthController</code> has <code>register</code> action that passes in name, username, password. We need to make sure all are non-null strings, username is unique, and password is 8 chars or more.</p>
<p>As recommended in <a href="http://pages.plataformatec.com.br/ebook-whats-new-in-ecto-2-0" rel="noopener nofollow ugc">What’s New in Ecto 2.0</a>, a good way to validate incoming data is with Ecto.Schema with <code>embedded_schema</code>. We’re using <a class="mention" href="/u/vic" rel="nofollow">@vic</a>’s excellent <a href="https://github.com/vic/params" rel="noopener nofollow ugc">vic/params</a> to reduce boilerplate, but there is still the matter of invoking the changeset, checking if it is valid, then returning error responses that are properly structured per our requirements. Why make this call in every action? Isn’t it cleaner to have a decorator:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defparams register_params %{ name!: :string, username!: :string, password!: :string }

@validate register_params
def register(conn, payload) do
...
</code></pre>
<p>Our first inclination was do something like <code>plug :validate</code> which is invoked before every action, but it’s harder (and less explicit) to associate the right schema+changeset with corresponding action.</p>
<p>Like others, the consensus of negativity from the core team tends to preclude others from using this pattern, even though otherwise it seems like a great fit. So I ask, what exactly are you recommending for something like our scenario, if not decorators?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="32868" 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/nicest-way-to-emulate-function-decorators/2050/35">Post #34</a>
	                </div>
	            </div>
              <div id="likers-container-32868" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="32868"
                     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 #34"></div>
  </section>
</div>
    <div class="postbit" id="32870" data-post-id="32870">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Create a function which does your thing and use 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="32870" data-batch-url="/posts/batch_likers">
                        5
                      </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/nicest-way-to-emulate-function-decorators/2050/36">Post #35</a>
	                </div>
	            </div>
              <div id="likers-container-32870" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="32870"
                     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 #35"></div>
  </section>
</div>
    <div class="postbit" id="32878" data-post-id="32878">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="arjan" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/arjan/120/2737_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  arjan
                    <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>I actually agree with <a class="mention" href="/u/nobbz" rel="nofollow">@NobbZ</a> here, in my opinion the use of function decorators should be limited to things that are not critical to the function that is being decorated.</p>
<p>The reason why I wrote the function decorator lib is for the AppSignal Elixir integration, to easily annotate a function that should be measured. So in my opinion decorators should be used mostly for logging, instrumentation and debugging, and not for performing “business-critical” things like branching etc.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="32878" 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/nicest-way-to-emulate-function-decorators/2050/37">Post #36</a>
	                </div>
	            </div>
              <div id="likers-container-32878" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="32878"
                     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 #36"></div>
  </section>
</div>
    <div class="postbit" id="33037" data-post-id="33037">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/nobbz" rel="nofollow">@NobbZ</a> <a class="mention" href="/u/arjan" rel="nofollow">@arjan</a> this is really confusing to me, for a couple of reasons. The first is that many other languages &amp; frameworks handle validation with decorators (<a href="https://www.playframework.com/documentation/1.4.x/validation-builtin" rel="noopener nofollow ugc">Scala with PlayFramework</a>, <a href="https://docs.microsoft.com/en-us/aspnet/mvc/overview/getting-started/introduction/adding-validation" rel="noopener nofollow ugc">C# with asp.net mvc</a>, and <a href="https://github.com/serhiisol/node-decorators" rel="noopener nofollow ugc">even node with express</a> to name a few). Why would elixir be so different that a technique like this would be advised against so strongly?</p>
<p>Secondly, the essence of Phoenix middleware with Plug architecture is doing nearly the same thing, it’s just a bit more cumbersome. Are you also recommending against the Plug approach too?</p>
<p>I know it’s really easy to just say “Create a function … and use it”, but saying something like that is not really welcoming to new members of the community that are trying to figure out best practices, especially coming from other popular languages.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="33037" 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/nicest-way-to-emulate-function-decorators/2050/38">Post #37</a>
	                </div>
	            </div>
              <div id="likers-container-33037" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="33037"
                     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 #37"></div>
  </section>
</div>
    <div class="postbit" id="34122" data-post-id="34122">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I just read this article by on medium about elixir validation with ecto and plug: <a href="https://medium.com/@feymartynov/validating-controller-params-with-ecto-and-plug-in-phoenix-5fe2cf77a224" rel="noopener nofollow ugc">https://medium.com/@feymartynov/validating-controller-params-with-ecto-and-plug-in-phoenix-5fe2cf77a224</a></p>
<p>The tl;dr of the approach is to use plug to tie an ecto changeset to a single action using the filtering syntax:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">plug MyApp.Params.Pagination, :pagination when action in [:index]
</code></pre>
<p>Then later on there’s some macro magic to perform the validation logic, detect issues, and set the appropriate api response.</p>
<p>This is very very similar to what we are doing with <span class="mention">@decorators</span>, with ours reading a bit more explicitly:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defparams register_params %{ name!: :string, username!: :string, avatar: [field: :string, default: ""]}
@decorate validate(&amp;register_params/1)
def register(conn, params) do
...
</code></pre>
<p>The argument in the article is the same that I have:</p>
<blockquote>
<p><em>Params validation and error response logic is abstracted out from controller actions so they don’t have redundant code and are more readable.</em></p>
</blockquote>
<p>My questions still remain – why is the <span class="mention">@decorator</span> pattern not recommended for validation? And does the same go for <code>plug ... when action in [...]</code> to achieve similar functionality?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="34122" 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/nicest-way-to-emulate-function-decorators/2050/39">Post #38</a>
	                </div>
	            </div>
              <div id="likers-container-34122" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="34122"
                     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 #38"></div>
  </section>
</div>
    <div class="postbit" id="34125" data-post-id="34125">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><a class="mention" href="/u/arjan" rel="nofollow">@arjan</a>: How about add also ’<span class="mention">@decorate_all</span>’ and ’<span class="mention">@decorate_multi</span>’?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="34125" 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/nicest-way-to-emulate-function-decorators/2050/40">Post #39</a>
	                </div>
	            </div>
              <div id="likers-container-34125" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="34125"
                     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 #39"></div>
  </section>
</div>
    <div class="postbit" id="34193" data-post-id="34193">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="arjan" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/arjan/120/2737_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  arjan
                    <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>PR’s welcome <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> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="34193" 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/nicest-way-to-emulate-function-decorators/2050/41">Post #40</a>
	                </div>
	            </div>
              <div id="likers-container-34193" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="34193"
                     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 #40"></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/2050/load_more?page=5">Load more posts (5 remaining)</a>
</div></template></turbo-stream>