<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.5">Jekyll</generator><link href="https://softonsofa.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://softonsofa.com/" rel="alternate" type="text/html" /><updated>2024-05-06T01:20:48+00:00</updated><id>https://softonsofa.com/feed.xml</id><title type="html">SoftOnSofa</title><subtitle>Writing codes for OSS and Aspire FT in Singapore. Contributor to open-source frameworks and packages, father, a close friend with barbell.</subtitle><entry><title type="html">OAuth authorisation basics</title><link href="https://softonsofa.com/oauth-authorisation-basics/" rel="alternate" type="text/html" title="OAuth authorisation basics" /><published>2020-06-30T04:01:01+00:00</published><updated>2020-06-30T04:01:01+00:00</updated><id>https://softonsofa.com/oauth-authorisation-basics</id><content type="html" xml:base="https://softonsofa.com/oauth-authorisation-basics/"><![CDATA[<h1 id="oauath---how-to-grant-access-to-my-data-to-another-app">OAuath - how to grant access to my data to another app</h1>

<p>Something for the eyes:</p>

<p><img src="https://user-images.githubusercontent.com/6928818/86093470-96e1a680-bae1-11ea-8ada-88b9238ba489.png" alt="image" /></p>

<p>Imagine you need to connect your application with another one to exchange some data for your users.</p>

<h2 id="real-world-almost-scenario">Real-world (almost) scenario</h2>

<p>Let’s talk about sligthly naive example of an app which facilitates budgeting and reminders for the payouts and receivables.
On the other hand, your users use <a href="https://www.xero.com">Xero</a> for the accounting purposes.
The scenario here will be that we need to get particular data about invoices from Xero in order to run our logic.</p>

<p>Here comes the <a href="https://oauth.net/2/">OAuth</a> protocol - it will make it super easy for the user to connect your app with Xero in 3 simple steps:</p>

<ol>
  <li>User click <em>connect with Xero</em> in your app</li>
  <li>User is redirected to the Xero authorisation page, where they choose which organisation to allow be accessed by your app</li>
  <li>User gets back to your app and it’s done</li>
</ol>

<p>Under the hood there will be likely more than just that, but it’s the implementation detail, which user’s don’t have to be bothered with.</p>

<h2 id="how-can-i-use-it">How can I use it?</h2>

<ul>
  <li>From now on you can access all resources in Xero on behalf of your User as per <code class="language-plaintext highlighter-rouge">scope</code> requested during step 2 above (which you define for your needs in your implementation)</li>
  <li>Anytime you can <em>disconnect</em> the Organisation you are using in your app OR disconnect whole Xero integration</li>
</ul>

<h2 id="caveats">Caveats</h2>

<p>If you happen to have multiple use-cases for Xero in your application, you may want to ask User to connect Xero again for different purpose.
Now, let’s assume you allow user to disconnect it for each use-case separately - here you want to be careful and make sure you don’t actually <em>disconnect</em> Organisation or whole Xero integration, for you’d end up with all use-cases broken, not just one of them.</p>]]></content><author><name></name></author><category term="business" /><category term="oauth" /><category term="grant" /><category term="xero" /><category term="authorisation" /><category term="authentication" /><summary type="html"><![CDATA[OAuath - how to grant access to my data to another app]]></summary></entry><entry><title type="html">Interface HowTo</title><link href="https://softonsofa.com/interface-howto/" rel="alternate" type="text/html" title="Interface HowTo" /><published>2020-05-15T04:01:01+00:00</published><updated>2020-05-15T04:01:01+00:00</updated><id>https://softonsofa.com/interface-howto</id><content type="html" xml:base="https://softonsofa.com/interface-howto/"><![CDATA[<h1 id="interface-howto">Interface HowTo</h1>

<p><a href="https://stackoverflow.com/a/14244705/784588">A great intro to refresh the basics</a></p>

<p>In short: an interface defines what functionality you need in a class you depend on (while not caring about the implementation).
It helps in designing the code and allows deferring implementation details, so they don’t get in the way.</p>

<p><strong>TLDR;</strong></p>

<ol>
  <li><a href="#why-not-setters--fluent-api">define functional methods, you <strong>MUST NEVER</strong> define implementation details as part of the interface</a>
    <ul>
      <li>you <strong>MUST NEVER</strong> define setters on an interface - they are ALWAYS implementation detail</li>
      <li>you <strong>MUST NEVER</strong> define an interface for so-called <em>fluent api/interface</em> (object returning itself) - <em>fluent api</em> is ALWAYS implementation detail</li>
    </ul>
  </li>
  <li><a href="#why-types-rather-than-associative-arrays">you <strong>SHOULD</strong> avoid using associative arrays in both input &amp; output - prefer VOs/POPOs/DTOs and Entities</a></li>
</ol>

<hr />

<p>Let’s think of an example feature request <em>Integrate 3rd party API to allow our users to make transfers</em></p>

<h3 id="usual-approach---dont">Usual approach - DON’T:</h3>
<ol>
  <li>review API documentation</li>
  <li>pull or write SDK for it</li>
  <li>write the configuration for the API connection</li>
  <li>write the actual functionality that serves the users</li>
</ol>

<h3 id="much-better-way">Much Better way:</h3>
<ol>
  <li>write the actual functionality that serves the users (based on mockups &amp; specs)</li>
  <li>write implementation to support that functionality</li>
  <li>pull or write SDK that will be necessary for the implementation</li>
  <li>write the configuration for the API connection</li>
</ol>

<hr />

<p>Why is the usual approach not what you want?</p>

<ul>
  <li>Because the most important thing (value for the user) comes last. By the time we had a chance to actually design how it works, we already put a lot of constraints on ourselves by whole implementation.</li>
  <li>If we discover at that point that we made wrong assumptions, it is hard and takes time to make changes.</li>
  <li>We may spend a significant amount of time implementing things that we don’t actually need</li>
</ul>

<p>The right might not feel natural initially, and so requires a bit different approach.
Let’s see an example of the code in the order we would write it:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 1 entry point for user's input</span>
<span class="kd">class</span> <span class="nc">TransferController</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="n">makeTransfer</span><span class="p">(</span><span class="kt">TransferRequest</span> <span class="nv">$request</span><span class="p">,</span> <span class="kt">TransferService</span> <span class="nv">$transferService</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">try</span> <span class="p">{</span>
            <span class="nv">$transferService</span><span class="o">-&gt;</span><span class="nf">send</span><span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">getTransfer</span><span class="p">());</span>

            <span class="k">return</span> <span class="k">new</span> <span class="nc">OkResponse</span><span class="p">;</span> <span class="c1">// 200 OK</span>
        <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">ClientTransferException</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// API validation error caused by the Client (balance, invalid bank account number etc)</span>
            <span class="k">return</span> <span class="k">new</span> <span class="nc">ClientErrorResponse</span><span class="p">(</span><span class="nv">$e</span><span class="o">-&gt;</span><span class="nf">getMessage</span><span class="p">());</span> <span class="c1">// 400 Bad Request</span>
        <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">ServerTransferException</span><span class="o">|</span><span class="nc">Throwable</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
            <span class="c1">// API validation error caused by Server implementation (bug, runtime error etc)</span>
            <span class="k">return</span> <span class="k">new</span> <span class="nc">ServerErrorResponse</span><span class="p">(</span><span class="nv">$e</span><span class="o">-&gt;</span><span class="nf">getMessage</span><span class="p">());</span> <span class="c1">// 500 Internal Server Error</span>
        <span class="p">}</span>
    <span class="p">}</span> 
<span class="p">}</span>

<span class="c1">// 2 input validation, parsing, sanitizing and turning it into domain-specific objects</span>
<span class="kd">class</span> <span class="nc">TransferRequest</span> <span class="kd">extends</span> <span class="nc">ApiRequest</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="n">rules</span><span class="p">():</span> <span class="kt">array</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span>
            <span class="s1">'amount'</span> <span class="o">=&gt;</span> <span class="s1">'required|int'</span><span class="p">,</span>
            <span class="s1">'holder_name'</span> <span class="o">=&gt;</span> <span class="s1">'required|string'</span><span class="p">,</span>
            <span class="s1">'currency_code'</span> <span class="o">=&gt;</span> <span class="k">new</span> <span class="nc">ValidCurrencyRule</span><span class="p">(</span><span class="nv">$this</span><span class="p">),</span>
            <span class="s1">'account_number'</span> <span class="o">=&gt;</span> <span class="k">new</span> <span class="nc">ValidAccountNumberRule</span><span class="p">(</span><span class="nv">$this</span><span class="p">),</span>
        <span class="p">];</span>
    <span class="p">}</span>

    <span class="k">function</span> <span class="n">getTransfer</span><span class="p">():</span> <span class="kt">TransferEntity</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="k">new</span> <span class="nc">TransferEntity</span><span class="p">(</span>
            <span class="nc">Money</span><span class="o">::</span><span class="nf">make</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">input</span><span class="p">(</span><span class="s1">'amount'</span><span class="p">),</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">input</span><span class="p">(</span><span class="s1">'currency_code'</span><span class="p">)),</span>
            <span class="nc">TransactionParty</span><span class="o">::</span><span class="nf">make</span><span class="p">(</span><span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">input</span><span class="p">(</span><span class="s1">'account_number'</span><span class="p">,</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">input</span><span class="p">(</span><span class="s1">'holder_name'</span><span class="p">)))</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="c1">// 3 expected low-level functionality that we will need</span>
<span class="kd">interface</span> <span class="nc">TransferService</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="n">send</span><span class="p">(</span><span class="kt">TransferEntity</span> <span class="nv">$transfer</span><span class="p">):</span> <span class="kt">void</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>At this point we:</p>
<ol>
  <li>are done with <em>write the actual functionality that serves the users</em></li>
  <li>don’t have to get back to this part of the code again</li>
  <li>can easily write automated tests (we may already have them - TDD comes naturally with such code)</li>
  <li>know exactly what <strong>the next step</strong> is</li>
</ol>

<p>The next step is driven by the interface here: <code class="language-plaintext highlighter-rouge">$transferService-&gt;send(TransferEntity $transfer)</code> - let’s write the implementation then!</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 1</span>
<span class="kd">class</span> <span class="nc">Transferwise</span> <span class="kd">implements</span> <span class="nc">TransferService</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="n">send</span><span class="p">(</span><span class="kt">TransferEntity</span> <span class="nv">$transfer</span><span class="p">):</span> <span class="kt">void</span>
    <span class="p">{</span>
        <span class="c1">// we need to call API somehow - let's assume there's SDK that we will use</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 2</span>
<span class="kd">class</span> <span class="nc">Transferwise</span> <span class="kd">implements</span> <span class="nc">TransferService</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">TransferWise</span><span class="err">\</span><span class="nc">Client</span> <span class="nv">$client</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">client</span> <span class="o">=</span> <span class="nv">$client</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">function</span> <span class="n">send</span><span class="p">(</span><span class="kt">TransferEntity</span> <span class="nv">$transfer</span><span class="p">):</span> <span class="kt">void</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">client</span><span class="o">-&gt;</span><span class="nf">sendTransfer</span><span class="p">(</span>
            <span class="c1">// 1 pass data from the $transfer</span>
            <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="nf">getAmount</span><span class="p">()</span> <span class="o">/</span> <span class="mi">100</span><span class="p">,</span>
            <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="nf">getCurrencyCode</span><span class="p">(),</span>
            <span class="mf">...</span>
            <span class="c1">// 2 let's assume we need more than just that, eg. some configuration</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 3</span>
<span class="kd">class</span> <span class="nc">Transferwise</span> <span class="kd">implements</span> <span class="nc">TransferService</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">TransferWise</span><span class="err">\</span><span class="nc">Client</span> <span class="nv">$client</span><span class="p">,</span> <span class="nc">Transferwise\Config</span> <span class="nv">$config</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">client</span> <span class="o">=</span> <span class="nv">$client</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">config</span> <span class="o">=</span> <span class="nv">$config</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">function</span> <span class="n">send</span><span class="p">(</span><span class="kt">TransferEntity</span> <span class="nv">$transfer</span><span class="p">):</span> <span class="kt">void</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">client</span><span class="o">-&gt;</span><span class="nf">sendTransfer</span><span class="p">(</span>
            <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="nf">getAmount</span><span class="p">()</span> <span class="o">/</span> <span class="mi">100</span><span class="p">,</span>
            <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="nf">getCurrencyCode</span><span class="p">(),</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">config</span><span class="o">-&gt;</span><span class="n">default_transfer_type</span><span class="p">,</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">config</span><span class="o">-&gt;</span><span class="n">markup_amount</span><span class="p">,</span>
        <span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>This pretty much covers <a href="#the-right-way">points 2 &amp; 3</a>. Last thing would be to sprinkle the class with standard things like LOGGING, ERROR HANDLING etc - those should come last, as it’s low level stuff that should never get in the way of functionality/value that we provide to the user.</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// 4</span>
<span class="kd">class</span> <span class="nc">Transferwise</span> <span class="kd">implements</span> <span class="nc">TransferService</span>
<span class="p">{</span>
    <span class="k">function</span> <span class="n">__construct</span><span class="p">(</span><span class="kt">TransferWise</span><span class="err">\</span><span class="nc">Client</span> <span class="nv">$client</span><span class="p">,</span> <span class="nc">Transferwise\Config</span> <span class="nv">$config</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">client</span> <span class="o">=</span> <span class="nv">$client</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">config</span> <span class="o">=</span> <span class="nv">$config</span><span class="p">;</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">logger</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">NullLogger</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">function</span> <span class="n">setLogger</span><span class="p">(</span><span class="kt">LoggerInterface</span> <span class="nv">$logger</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">logger</span> <span class="o">=</span> <span class="nv">$logger</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">function</span> <span class="n">send</span><span class="p">(</span><span class="kt">TransferEntity</span> <span class="nv">$transfer</span><span class="p">):</span> <span class="kt">void</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">logger</span><span class="o">-&gt;</span><span class="nf">info</span><span class="p">(</span><span class="s1">'useful log'</span><span class="p">);</span>

        <span class="k">try</span> <span class="p">{</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">client</span><span class="o">-&gt;</span><span class="nf">sendTransfer</span><span class="p">(</span>
                <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="nf">getAmount</span><span class="p">()</span> <span class="o">/</span> <span class="mi">100</span><span class="p">,</span>
                <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="nf">getCurrencyCode</span><span class="p">(),</span>
                <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">config</span><span class="o">-&gt;</span><span class="n">default_transfer_type</span><span class="p">,</span>
                <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">config</span><span class="o">-&gt;</span><span class="n">markup_amount</span><span class="p">,</span>
            <span class="p">);</span>
        <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">Transferwise\SomeError</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">logger</span><span class="o">-&gt;</span><span class="nf">info</span><span class="p">(</span><span class="s1">'useful log'</span><span class="p">);</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nc">ClientTransferException</span><span class="p">(</span><span class="s1">'Transfer Failed'</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">$e</span><span class="p">);</span>
        <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nc">Throwable</span> <span class="nv">$e</span><span class="p">)</span> <span class="p">{</span>
            <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">logger</span><span class="o">-&gt;</span><span class="nf">info</span><span class="p">(</span><span class="s1">'useful log'</span><span class="p">);</span>
            <span class="k">throw</span> <span class="k">new</span> <span class="nc">ServerTransferException</span><span class="p">(</span><span class="s1">'Transfer Failed'</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="nv">$e</span><span class="p">);</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And finally we <em>write configuration for the API connection</em>:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">TransferwiseServiceProvider</span> <span class="kd">extends</span> <span class="nc">ServiceProvider</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">register</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">app</span><span class="o">-&gt;</span><span class="nf">bind</span><span class="p">(</span><span class="nc">Transferwise\Config</span><span class="o">::</span><span class="n">class</span><span class="p">,</span> <span class="k">fn</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="nc">Config</span><span class="o">::</span><span class="nf">fromArray</span><span class="p">([</span>
            <span class="s1">'default_transfer_type'</span> <span class="o">=&gt;</span> <span class="nf">config</span><span class="p">(</span><span class="s1">'...'</span><span class="p">),</span> <span class="c1">// or env(...) if different in dev/prod env</span>
            <span class="s1">'markup_amount'</span> <span class="o">=&gt;</span> <span class="nf">config</span><span class="p">(</span><span class="s1">'...'</span><span class="p">),</span> <span class="c1">// or env(...) if different in dev/prod env</span>
        <span class="p">]));</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<hr />

<h3 id="why-not-setters--fluent-api">Why not setters &amp; fluent api?</h3>

<p><strong>It might be tempting</strong> to define methods for fluent interface:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">interface</span> <span class="nc">TransferService</span>
<span class="p">{</span>
    <span class="c1">// NEVER DO THIS:</span>
    <span class="k">function</span> <span class="n">setSomething</span><span class="p">(</span><span class="kt">SomeGenericType</span> <span class="nv">$something</span><span class="p">):</span> <span class="kt">self</span><span class="p">;</span>
    <span class="k">function</span> <span class="n">setAmount</span><span class="p">(</span><span class="kt">Money</span> <span class="nv">$amount</span><span class="p">):</span> <span class="kt">self</span><span class="p">;</span>
    <span class="k">function</span> <span class="n">setTransfer</span><span class="p">(</span><span class="kt">TransferEntity</span> <span class="nv">$transfer</span><span class="p">):</span> <span class="kt">self</span><span class="p">;</span>
    <span class="k">function</span> <span class="n">send</span><span class="p">():</span> <span class="kt">void</span>
<span class="p">}</span>

<span class="c1">// NEVER DO THIS:</span>
<span class="nv">$transferService</span>
    <span class="o">-&gt;</span><span class="nf">setSomething</span><span class="p">(</span><span class="nv">$something</span><span class="p">)</span>
    <span class="o">-&gt;</span><span class="nf">setAmount</span><span class="p">(</span><span class="nv">$amount</span><span class="p">)</span>
    <span class="o">-&gt;</span><span class="nf">setTransfer</span><span class="p">(</span><span class="nv">$transfer</span><span class="p">)</span>
    <span class="o">-&gt;</span><span class="nf">send</span><span class="p">();</span>
</code></pre></div></div>

<p>Such approach breaks rule 1 completely and creates very rigid structure.
That is because the ONLY thing we care about from user’s perspective is <code class="language-plaintext highlighter-rouge">send()</code> method, and having <em>fluent api</em> defined on the interface binds us to this approach for all implementations.</p>

<p>You can still use <em>fluent api</em> if this is your preferred way. It’s great for <strong>builder</strong> objects, but not for functional services.</p>

<p>An example of proper interface and fluent builder - both achieve exactly the same goal and are valid implementations from user’s perspective:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Standard approach</span>
<span class="nv">$transferService</span><span class="o">-&gt;</span><span class="nf">send</span><span class="p">(</span>
    <span class="k">new</span> <span class="nc">TransferEntity</span><span class="p">(</span><span class="nv">$amount</span><span class="p">,</span> <span class="nv">$recipient</span><span class="p">,</span> <span class="nv">$description</span><span class="p">)</span>
<span class="p">);</span>

<span class="c1">// Fluent api approach</span>
<span class="nv">$transferService</span><span class="o">-&gt;</span><span class="nf">send</span><span class="p">(</span>
    <span class="nc">TransferEntity</span><span class="o">::</span><span class="nf">builder</span><span class="p">()</span>
        <span class="o">-&gt;</span><span class="nf">setRecipient</span><span class="p">(</span><span class="nv">$recipient</span><span class="p">)</span>
        <span class="o">-&gt;</span><span class="nf">setAmount</span><span class="p">(</span><span class="nv">$amount</span><span class="p">)</span>
        <span class="o">-&gt;</span><span class="nf">setDescription</span><span class="p">(</span><span class="nv">$description</span><span class="p">)</span>
<span class="p">);</span>
</code></pre></div></div>

<h3 id="why-types-rather-than-associative-arrays">Why types rather than (associative) arrays?</h3>

<p>Associative arrays in general SHOULD only be used within private scope but in public api prefer types.
Standard arrays are perfectly fine, as long as they represent a simple list and we don’t depend on the keys.</p>

<p>Example:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">function</span> <span class="n">getTransfer</span><span class="p">():</span> <span class="kt">TransferEntity</span>
<span class="p">{</span>
    <span class="nv">$transfer</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">TransferEntity</span><span class="p">;</span>
    <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="n">property_a</span> <span class="o">=</span> <span class="s1">'value for a'</span><span class="p">;</span>
    <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="n">property_b</span> <span class="o">=</span> <span class="mi">12345</span><span class="p">;</span>
    <span class="nv">$transfer</span><span class="o">-&gt;</span><span class="n">property_c</span> <span class="o">=</span> <span class="s1">'value for c'</span><span class="p">;</span>
<span class="p">}</span>

<span class="c1">// VS</span>

<span class="k">public</span> <span class="k">function</span> <span class="n">getTransferData</span><span class="p">():</span> <span class="kt">array</span> 
<span class="p">{</span>
    <span class="k">return</span> <span class="p">[</span>
        <span class="s1">'property_a'</span> <span class="o">=&gt;</span> <span class="s1">'value for a'</span><span class="p">,</span>
        <span class="s1">'property_b'</span> <span class="o">=&gt;</span> <span class="mi">12345</span><span class="p">,</span>
        <span class="s1">'property_c'</span> <span class="o">=&gt;</span> <span class="s1">'value for c'</span><span class="p">,</span>
    <span class="p">];</span>
<span class="p">}</span>
</code></pre></div></div>

<h4 id="why-array-is-really-bad">Why array is really BAD</h4>

<ol>
  <li>consuming array as output from a class - you HAVE TO KNOW the keys inside -&gt; you need to waste time to find the definition and/or usage for the array. As array is just a primitive type, IDE won’t be able to offer FIND REFERENCES to help you.</li>
  <li>usually it requires <code class="language-plaintext highlighter-rouge">if</code> and <code class="language-plaintext highlighter-rouge">fallback</code> values: <code class="language-plaintext highlighter-rouge">$array['key'] ?? null</code> or <code class="language-plaintext highlighter-rouge">$array['key'] ?? 'default'</code></li>
  <li>it’s easy to make typo that goes unnoticed - you can easily ship code to production without spotting because of the point 2</li>
  <li>static analysis tools in CI won’t catch errors just like IDE</li>
  <li>if you need to change/add key to the array, you waste time finding where it is used - again, no FIND REFERENCES in IDE</li>
</ol>

<h4 id="why-object-is-helpful">Why object is helpful</h4>

<p>By implementing object, even simple POPO, you get rid of ALL of those problems:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">class</span> <span class="nc">TransferEntity</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="kt">?string</span> <span class="n">property_a</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
    <span class="k">public</span> <span class="kt">?int</span> <span class="n">property_b</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
    <span class="k">public</span> <span class="kt">?string</span> <span class="n">property_c</span> <span class="o">=</span> <span class="s1">'default'</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<ol>
  <li>consuming the object is fast and easy -&gt; IDE has your back and completes properties + their types</li>
  <li>no need for <code class="language-plaintext highlighter-rouge">if</code> / <code class="language-plaintext highlighter-rouge">isset</code> checks</li>
  <li>typos will be caught as early as in the IDE when you type</li>
  <li>if something still went unnoticed, static analysis will be able to catch it during a commit or later in the CI</li>
  <li>changing payload means that IDE helps you with FIND REFERENCES</li>
</ol>

<p>There is no downside to this approach:</p>

<ul>
  <li>performance-wise we don’t need to worry about primitives vs objects</li>
  <li>creating a class takes just a few seconds more that an array</li>
  <li>we can write fewer tests, having strict types on the objects</li>
</ul>]]></content><author><name></name></author><category term="coding" /><category term="solid" /><category term="php" /><summary type="html"><![CDATA[Interface HowTo]]></summary></entry><entry><title type="html">20 Eloquent tricks - more</title><link href="https://softonsofa.com/20-eloquent-tricks-more/" rel="alternate" type="text/html" title="20 Eloquent tricks - more" /><published>2018-04-14T04:00:00+00:00</published><updated>2018-04-14T04:00:00+00:00</updated><id>https://softonsofa.com/20-eloquent-tricks-more</id><content type="html" xml:base="https://softonsofa.com/20-eloquent-tricks-more/"><![CDATA[<p>Recently I stumbled upon interesting article by <a href="https://twitter.com/PovilasKorop">Povilas Korop</a> on laravel-news <a href="https://laravel-news.com/eloquent-tips-tricks">20 eloquent tips and tricks</a>. First of all thanks for sharing your knowledge Povilas – it helps many people out there, keep it up!</p>

<p>As you may know, I’ve worked with Eloquent for long and love its features, at the same time I’ve become very sensitive about some dangers lurking for inexperienced developers that come with all the magic of Eloquent :) 
Let’s use this opportunity to look at the tips from different perspective and learn even more by going through some of them in more details!</p>

<p>In order to make it valuable for you I’m keeping it as concise as possible:</p>

<ol>
  <li>
    <p><code class="language-plaintext highlighter-rouge">in/decrement</code>: <strong>GOOD</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">findOrFail</code>: <strong>GOOD</strong>, but there’s a catch in <code class="language-plaintext highlighter-rouge">findOrFail</code>. Laravel internally handles <code class="language-plaintext highlighter-rouge">ModelNotFoundException</code> <a href="https://github.com/laravel/framework/blob/5.6/src/Illuminate/Foundation/Exceptions/Handler.php#L198">here</a> and it means that any call that fails here, will trigger a <code class="language-plaintext highlighter-rouge">404 NOT FOUND</code> response from your app. This works fine when called for example for something like this:</p>

    <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nc">Route</span><span class="o">::</span><span class="nf">get</span><span class="p">(</span><span class="s1">'products/{id}'</span><span class="p">,</span> <span class="k">function</span> <span class="p">(</span><span class="nv">$id</span><span class="p">)</span> <span class="p">{</span>

  <span class="k">return</span> <span class="nc">Product</span><span class="o">::</span><span class="nf">findOrFail</span><span class="p">(</span><span class="nv">$id</span><span class="p">);</span>

 <span class="p">});</span>
</code></pre></div>    </div>

    <p>Laravel uses the same pattern for implicit route model binding described <a href="https://laravel.com/docs/5.6/routing#route-model-binding">here</a></p>

    <p>However, if you’re calling your query deeper in the code of your application, you do not want to automatically trigger <code class="language-plaintext highlighter-rouge">404</code> for any not-found record, as it might have nothing to do with the routing or even HTTP layer at all.<br />
 That being said, <code class="language-plaintext highlighter-rouge">findOrFail</code> is cool for top, HTTP layer. Other than that I recommend something between the lines of (yes, oldskool, even archaic, no magic involved… you get the idea):</p>

    <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nv">$model</span> <span class="o">=</span> <span class="nv">$someQuery</span><span class="o">-&gt;</span><span class="nf">find</span><span class="p">(</span><span class="nv">$id</span><span class="p">);</span>

 <span class="k">if</span> <span class="p">(</span><span class="nb">is_null</span><span class="p">(</span><span class="nv">$model</span><span class="p">))</span> <span class="p">{</span>
  <span class="c1">// handle logic when record is not found</span>
 <span class="p">}</span>
</code></pre></div>    </div>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">boot</code> <strong>GOOD</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">default ordering on relationships</code> – definitely no (unless the relationship itself explicitly states that):</p>

    <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="c1">// Organization</span>
 <span class="k">public</span> <span class="k">function</span> <span class="n">approvedUsers</span><span class="p">()</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">hasMany</span><span class="p">(</span><span class="s1">'App\\User'</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">where</span><span class="p">(</span><span class="s1">'approved'</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">orderBy</span><span class="p">(</span><span class="s1">'email'</span><span class="p">);</span>
 <span class="p">}</span>

 <span class="c1">// then somewhere you need this</span>
 <span class="nv">$organization</span><span class="o">-&gt;</span><span class="nf">approvedUsers</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">latest</span><span class="p">()</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">();</span>
</code></pre></div>    </div>

    <p>Now you’re scratching your head and trying to figure out why you don’t get <code class="language-plaintext highlighter-rouge">latest</code> users. After a while you notice that they are ordered by email, so you’re tracking it down – relationship is found, so the question arises – can I change the relationship? Not really, it would break some functionality, probably untested, so it is not the way to go. Eventually it seems that the only way is a NEW relationhsip. Not good at all.</p>

    <p>You could make it better, if you really need default ordering, by creating custom and explicit relation in the first place – just like <a href="https://twitter.com/SOFTonSOFA/status/966669189103599616">here</a></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">props</code>: <strong>GOOD</strong>. There’s one exception – I recommend not using <code class="language-plaintext highlighter-rouge">$appends</code> EVER as this one very easily leads to huge problems if abused. Imagine using accessor that does some heavy logic (which it should not), like querying relation and returning its value:</p>

    <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">public</span> <span class="k">function</span> <span class="n">getOrganizationNameAttribute</span><span class="p">()</span>
 <span class="p">{</span>
  <span class="k">return</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">organization</span><span class="o">-&gt;</span><span class="n">name</span><span class="p">;</span>
 <span class="p">}</span>
</code></pre></div>    </div>

    <p>this is evil as it is, trust me. Now, imagine you have an API endpoint that serves your model directly, and some time later your colleague needs to add <code class="language-plaintext highlighter-rouge">organization_name</code> to the JSON result. Easy does it, right? Just added to <code class="language-plaintext highlighter-rouge">$appends</code> and it is automagically in the JSON!</p>

    <p>Only now you realize that your endpoint serves data 20 times slower now and you have no idea why. Here it is – magic has its cost. You endpoint used, say, 5 queries before, but now it uses 5 + N queries, because accessor runs the query under the hood. Finding it out is not trivial and even noticing it might take long, which can hurt the business. Don’t go this path, <a href="https://softonsofa.com/a-story-about-laravel-resources">be like new Leo and save yourself some headache</a> 😉</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">findMany</code>: <strong>GOOD</strong>. I’d only add note about different return values <code class="language-plaintext highlighter-rouge">find(int|string 1) : ?Model</code> while <code class="language-plaintext highlighter-rouge">find(array|Arrayable $ids) : Collection</code>. Which means the first returns <code class="language-plaintext highlighter-rouge">Model</code> or <code class="language-plaintext highlighter-rouge">null</code>, but the latter returns <code class="language-plaintext highlighter-rouge">Collection</code> <strong>always</strong> (even if empty).</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">dynamic wheres</code>: <strong>NEVER do this</strong>. It is illogical, confusing, impossible to understand for anyone without decent knowledge about Eloquent.<br />
 Next thing is this: if you ever need to restructure your DB or just investigate usage and find all queries against a column, you’d find easily <code class="language-plaintext highlighter-rouge">where('some_column')</code>, <code class="language-plaintext highlighter-rouge">orderBy('some_column')</code> etc by simply grepping against <code class="language-plaintext highlighter-rouge">'some_column'</code>, but you won’t find <code class="language-plaintext highlighter-rouge">whereSomeColumn($value)</code>.<br />
 Another catch is this: you know already that Eloquent provides those magic calls (dynamic wheres), so when you see <code class="language-plaintext highlighter-rouge">whereDate</code> you can think it is the same. But wait, there’s no <code class="language-plaintext highlighter-rouge">date</code> column in the table, so WTF? Oh, sure, this is actually real method <code class="language-plaintext highlighter-rouge">whereDate($column, $value)</code>. You get the idea, trust me, you neighbor and their dog will hate you if you use it even once.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">order by relation</code>: Custom relation definitely <strong>GOOD</strong>, but ordering nope. While it is valid, it’s dangerous as well. You should <strong>NEVER depend on the collection ordering</strong> if you don’t know how many items collection has (and it must be rather small collection). Imagine this code when your page grows from 20 <code class="language-plaintext highlighter-rouge">Topics</code> to 20 thousands <code class="language-plaintext highlighter-rouge">Topics</code> – then every single pageload is looong seconds, sometimes memory exhausted errors occur etc. Databases are pretty good with ordering, use them.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">when</code>: I totally agree with the comment: <em>It may not feel shorter or more elegant</em> – True, it is not shorter, nor more elegant, nor better in any way for me. Here’s what I recommend:</p>

    <div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="k">if</span> <span class="p">(</span><span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">has</span><span class="p">(</span><span class="s1">'role'</span><span class="p">))</span> <span class="p">{</span> <span class="c1">// I know the intent already</span>
  <span class="nv">$query</span><span class="o">-&gt;</span><span class="nf">where</span><span class="p">(</span><span class="s1">'role_d'</span><span class="p">,</span> <span class="nv">$request</span><span class="o">-&gt;</span><span class="nf">get</span><span class="p">(</span><span class="s1">'role'</span><span class="p">));</span> <span class="c1">// then following action</span>
 <span class="p">}</span>

 <span class="c1">// vs</span>

 <span class="c1">// Reading this I am not sure what false means, no idea what $role will be</span>
 <span class="c1">// in the closure, I have to spend a few seconds analyzing it every time.</span>
 <span class="c1">// It adds up in big codebase and I love to avoid unnecessary overload</span>
 <span class="nv">$query</span><span class="o">-&gt;</span><span class="nf">when</span><span class="p">(</span><span class="nf">request</span><span class="p">(</span><span class="s1">'role'</span><span class="p">,</span> <span class="kc">false</span><span class="p">),</span> <span class="k">function</span> <span class="p">(</span><span class="nv">$q</span><span class="p">,</span> <span class="nv">$role</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">return</span> <span class="nv">$q</span><span class="o">-&gt;</span><span class="nf">where</span><span class="p">(</span><span class="s1">'role_d'</span><span class="p">,</span> <span class="nv">$role</span><span class="p">);</span>
 <span class="p">});</span>
</code></pre></div>    </div>

    <p>One may argue that you HAVE TO avoid <code class="language-plaintext highlighter-rouge">if</code> statements, but here’s the thing – removing them doesn’t make you functional programmer, using <code class="language-plaintext highlighter-rouge">function () {}</code> rather than <code class="language-plaintext highlighter-rouge">if</code> doesn’t make you functional programmer, it doesn’t add any value to the business either.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">withDefault</code>: <strong>OKAY</strong> in general. I prefer explicit code, so don’t use it myself, but it’s matter of preference. However using it strictly for presentation purpose as in the example – no like.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">accessor ordering</code>: <strong>Smart</strong> – as in No. 8 be careful in cases, where you cannot be sure bout collection size.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">global scope</code>: <strong>OKAY</strong>. Personally I wouldn’t do that in a global scope, as global scopes are good for only so many cases, and only to apply some <code class="language-plaintext highlighter-rouge">where</code> constraints (<code class="language-plaintext highlighter-rouge">SoftDeletes</code> is a good example, <code class="language-plaintext highlighter-rouge">Active</code> might be applicable in many cases etc).</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">raw</code>: <strong>GOOD</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">replicate</code>: <strong>GOOD</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">chunk</code>: VERY <strong>GOOD</strong>. I would add that you NEVER want to call <code class="language-plaintext highlighter-rouge">Model::all()</code> unless you have a dictionary-like model, say, a list of countries. A model that you can be sure will never grow (there won’t be more than 300 countries in our lifetime I guess).</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">generators</code>: <strong>GOOD</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">updated_at</code>: <strong>GOOD</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">update</code> return value: <strong>GOOD</strong></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">orWhere</code>: This one is actually incorrect, both in the code and logically. I believe it comes from the bad example in the Laravel’s own docs. I corrected the example and added some notes to the docs recently, so feel free to look it up now <a href="https://laravel.com/docs/5.6/queries#parameter-grouping">docs</a></p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">orWhere</code> again: Same as No. 19.</p>
  </li>
</ol>]]></content><author><name></name></author><category term="coding" /><category term="laravel" /><category term="eloquent" /><category term="php" /><summary type="html"><![CDATA[Recently I stumbled upon interesting article by Povilas Korop on laravel-news 20 eloquent tips and tricks. First of all thanks for sharing your knowledge Povilas – it helps many people out there, keep it up!]]></summary></entry><entry><title type="html">A story about Laravel resources</title><link href="https://softonsofa.com/a-story-about-laravel-resources/" rel="alternate" type="text/html" title="A story about Laravel resources" /><published>2018-03-11T04:00:00+00:00</published><updated>2018-03-11T04:00:00+00:00</updated><id>https://softonsofa.com/a-story-about-laravel-resources</id><content type="html" xml:base="https://softonsofa.com/a-story-about-laravel-resources/"><![CDATA[<h1 id="a-story-about-laravel-resources">A story about laravel resources</h1>

<p>Leo is a brilliant developer. He turns every idea into code in no time. He’s prepared for any task thrown at him and dives into coding straight away, delivering successfully and rapidly.</p>

<p>These days he’s been working on a public API for the application he and his team is building. A few resources with a few endpoints were not a big challenge for Leo obviously. He caught some models in the wild and turned them into <strong>beatiful REST API</strong> data source. Done deal.</p>

<p>A few days passed and <code class="language-plaintext highlighter-rouge">Whoops! Something went wrong</code> unfortunately.</p>

<p>But worry not, for Leo is well-prepared – he wrote tests for the API, so whatever went wrong, was caught during proper build process before going live, so all that needs to be done is tracking down the culprit and fixing the issue.</p>

<p>Leo found out that JSON from <code class="language-plaintext highlighter-rouge">GET /users/{uuid}</code> endpoint returned <code class="language-plaintext highlighter-rouge">posts</code> related collection, even though it wasn’t requested by the consumer (test in this case).
After scratching his head for 15 minutes, playing with the endpoint manually, checking the transforming method, he was a bit lost.
Finally Leo found out that his colleague, Francis, added a key to the <code class="language-plaintext highlighter-rouge">$appends</code> array on the <code class="language-plaintext highlighter-rouge">User</code> model, which in turn called the accessor behind the scenes, and the latter did some calculations on related <code class="language-plaintext highlighter-rouge">posts</code> collection. This ended up in loading the relation implicitly.</p>

<p>Now, this is a puzzle… Leo had to discuss it with Francis, and they realized, that using <code class="language-plaintext highlighter-rouge">$appends</code> is a very bad idea, but it is too hard now to change it, because features planned for the release are necessary for the business. They agreed, that Leo is gonna make a quick fix in his transformer class and instead of deceptive <code class="language-plaintext highlighter-rouge">whenLoaded</code> he will simply rely on old-skool, a bit rusty nowadays, yet effective <code class="language-plaintext highlighter-rouge">if</code> statement.</p>

<p><em>Screw it</em>, he thought to himself, <em>I’m never gonna show this sh.t on twitter, so let it be…</em></p>

<p>Issue fixed, case closed!</p>

<hr />

<p>Things were going great for Leo until one Friday afternoon, when sales team manager Jonathan, approached him.</p>

<p>Leo wasn’t sure whether it was a threatening expression on Jonathan’s face, or it was just a Friday prank.
<em>He’s serious, too serious</em>, Leo whispered to his neighbour, Alice, and he was damn right…</p>

<p>The API that Leo created has been working for a few weeks now. It was fine and healthy, there were some inconsistencies in response times without any clear reason, but nobody complained.</p>

<p>Today, however, somebody did…</p>

<p>Jonathan was furious about some sensitive users’ data leaking through the API. He was so angry while shouting he spit on Leo’s shiny MBP, and it wasn’t cool. Not cool at all if you ask me!</p>

<p>It took a while before Leo actually learned from Jonathan what the problem was. Apparently, Jonathan had a friendly meeting with one of the customers, who also was API consumer, and after a drink or two, the customer said something between the lines of</p>

<p><em>I’m really glad you guys share all that info there, in your API, but you may want to actually hide it. If I didn’t know you from college I could simply steal your customers, you know… I bet Donnie from XYZ is already doing that mate hahahaha!</em></p>

<p>WAT?!</p>

<p>Jonathan thought it was a joke first, but after asking his college friend a few questions, he was horrified and dashed back to the office.</p>

<p>Leo started to panic. He knew, it could end up badly, so he reassured Jonathan that there was no issue in the API and it must have been a glitch that made the guy receive some excess data. He also promised to stay in the office as long as necessary to check everything in and out and fix if there was anything wrong.</p>

<p>He knew, his girlfriend was preparing for a Friday night out already, so he acted quickly. After browsing through all the codes related to <code class="language-plaintext highlighter-rouge">/users</code> resource in his API, Leo couldn’t find the problem, so he asked Alice for help. They were always there for each other, so she agreed to stay after-hours and help.
Alice wasn’t too familiar with the structure of Resources, so after reading the code, she resorted to checking the docs on the framework’s website.</p>

<p>Spot on! During browsing the docs page, she noticed something familiar: <code class="language-plaintext highlighter-rouge">when($this-&gt;isAdmin(), ...)</code> – they had the same construct in their code. However, both she and Leo missed the important bit in the beginning:</p>

<p><img width="658" alt="image" src="https://user-images.githubusercontent.com/6928818/85195280-b28bc680-b303-11ea-9af1-95e2140e0858.png" /></p>

<p>That moment Leo realized he was screwed…</p>

<p><em>It isn’t about the authenticated user, it is the requested data where that method is being called</em>, he muttered, then yelled <em>FFS!!</em></p>

<p>—</p>

<p>The story went on, Leo fixed everything in the API, he asked his old-skool colleague (Dinosaur they called him) Richard for advice this time. He learned it the hard way, but he did, and these days he makes his code predictable.</p>

<p>Now he knows and now he spreads the word out to all the New Kids On The Block:</p>

<p><strong>Save yourself that Friday Night with your bae!</strong></p>]]></content><author><name></name></author><category term="coding" /><category term="solid" /><category term="laravel" /><category term="php" /><summary type="html"><![CDATA[A story about laravel resources]]></summary></entry><entry><title type="html">How to add custom casters in Laravel Tinker</title><link href="https://softonsofa.com/how-to-add-custom-casters-in-laravel-tinker/" rel="alternate" type="text/html" title="How to add custom casters in Laravel Tinker" /><published>2018-03-04T04:00:00+00:00</published><updated>2018-03-04T04:00:00+00:00</updated><id>https://softonsofa.com/how-to-add-custom-casters-in-laravel-tinker</id><content type="html" xml:base="https://softonsofa.com/how-to-add-custom-casters-in-laravel-tinker/"><![CDATA[<p>I made a series about psysh and Laravel’s tinker – powerful REPL where you can play with your whole application.</p>

<p>ICYMI check it out here: <a href="https://softonsofa.com/tinker-like-a-boss-in-psysh/">tinker like a boss</a> and here’s example of what we can achieve:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">=&gt;</span> <span class="nc">Carbon\Carbon</span> <span class="o">@</span><span class="mi">1519569240</span> <span class="p">{</span><span class="c1">#745</span>
 <span class="o">+</span><span class="n">date</span><span class="o">:</span> <span class="s2">"2018-02-25 14:34:00.000000"</span><span class="p">,</span>
 <span class="o">+</span><span class="n">weekday</span><span class="o">:</span> <span class="s2">"Sunday"</span><span class="p">,</span>
 <span class="o">+</span><span class="n">day_of_year</span><span class="o">:</span> <span class="mi">55</span><span class="p">,</span>
 <span class="o">+</span><span class="n">unix</span><span class="o">:</span> <span class="mi">1519569240</span><span class="p">,</span>
 <span class="o">+</span><span class="n">diff_for_humans</span><span class="o">:</span> <span class="s2">"6 days ago"</span><span class="p">,</span>
 <span class="p">}</span>
</code></pre></div></div>

<p>There is, however, missing piece of the puzzle in the series. It describes how you can custimze presenters in REPL (called casters in PsySH), but I describe generic, global casters that reside in PsySH config. This is very handy, but you cannot distribute them among your team members (or anyone else for that matter) in the repo.</p>

<p>Today we are going to add that piece to the puzzle and see <strong>how to customize and override psysh casters in Laravel app</strong>.</p>

<p>We need just a few simple steps:</p>

<ol>
  <li>Override tinker command</li>
  <li>Override service provider</li>
  <li>Create our casters and define them in the application config</li>
</ol>

<h3 id="override-original-serviceprovider-and-command">Override original ServiceProvider and Command</h3>

<p>First let’s create our customized Command, which will allows us to provide array with customized casters:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kn">namespace</span> <span class="nn">App\Console</span><span class="p">;</span>

<span class="kd">class</span> <span class="nc">TinkerCommand</span> <span class="k">extends</span> <span class="err">\</span><span class="nc">Laravel\Tinker\Console\TinkerCommand</span>
<span class="p">{</span>
    <span class="k">protected</span> <span class="kt">array</span> <span class="nv">$casters</span> <span class="o">=</span> <span class="p">[];</span>

    <span class="cd">/**
     * Set custom casters for this tinker session.
     *
     * @param array $casters
     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">setCasters</span><span class="p">(</span><span class="kt">array</span> <span class="nv">$casters</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">casters</span> <span class="o">=</span> <span class="nv">$casters</span><span class="p">;</span>

        <span class="k">return</span> <span class="nv">$this</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="cd">/**
     * Get an array of custom and Laravel's own casters.
     *
     * @return array
     */</span>
    <span class="k">protected</span> <span class="k">function</span> <span class="n">getCasters</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="nb">array_merge</span><span class="p">(</span><span class="k">parent</span><span class="o">::</span><span class="nf">getCasters</span><span class="p">(),</span> <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">casters</span><span class="p">);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Next step is to use this command instead of the original – we can achieve that by replacing the service provider:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// in config/app.php replace the line:</span>
<span class="nc">Laravel\Tinker\TinkerServiceProvider</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>

<span class="c1">// with:</span>
<span class="nc">App\Providers\TinkerServiceProvider</span><span class="o">::</span><span class="n">class</span><span class="p">,</span>

<span class="c1">// and create the your own provider:</span>
<span class="kd">class</span> <span class="nc">TinkerServiceProvider</span> <span class="k">extends</span> <span class="err">\</span><span class="nc">Laravel\Tinker\TinkerServiceProvider</span>
<span class="p">{</span>
    <span class="cd">/**
     * Register the service provider.
     *
     * @return void
     */</span>
    <span class="k">public</span> <span class="k">function</span> <span class="n">register</span><span class="p">()</span>
    <span class="p">{</span>
        <span class="nv">$this</span><span class="o">-&gt;</span><span class="n">app</span><span class="o">-&gt;</span><span class="nf">singleton</span><span class="p">(</span>
            <span class="s1">'command.tinker'</span><span class="p">,</span>
            <span class="k">fn</span> <span class="p">()</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="k">new</span> <span class="err">\</span><span class="nc">App\Console\TinkerCommand</span><span class="p">)</span><span class="o">-&gt;</span><span class="nf">setCasters</span><span class="p">(</span>
                <span class="nf">config</span><span class="p">(</span><span class="s1">'tinker.casters'</span><span class="p">,</span> <span class="p">[])</span>
            <span class="p">)</span>
        <span class="p">);</span>

        <span class="nv">$this</span><span class="o">-&gt;</span><span class="nf">commands</span><span class="p">([</span><span class="s1">'command.tinker'</span><span class="p">]);</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<h3 id="create-and-register-casters">Create and register casters</h3>

<p>Finally, let’s create example caster and set it up in the <code class="language-plaintext highlighter-rouge">config/tinker.php</code> configuration file:</p>

<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// config/tinker.php</span>
<span class="k">return</span> <span class="p">[</span>
    <span class="s1">'casters'</span> <span class="o">=&gt;</span> <span class="p">[</span>
        <span class="c1">// Either inline function:</span>
        <span class="nc">Carbon\Carbon</span><span class="o">::</span><span class="n">class</span> <span class="o">=&gt;</span> <span class="k">fn</span> <span class="p">(</span><span class="kt">Carbon</span><span class="err">\</span><span class="nc">Carbon</span> <span class="nv">$carbon</span><span class="p">)</span> <span class="o">=&gt;</span> <span class="p">[</span>
            <span class="s1">'date'</span> <span class="o">=&gt;</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="n">date</span><span class="p">,</span>
            <span class="s1">'weekday'</span> <span class="o">=&gt;</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="nf">format</span><span class="p">(</span><span class="s1">'l'</span><span class="p">),</span>
            <span class="s1">'day_of_year'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">int</span><span class="p">)</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="nf">format</span><span class="p">(</span><span class="s1">'z'</span><span class="p">),</span>
            <span class="s1">'unix'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">int</span><span class="p">)</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="nf">format</span><span class="p">(</span><span class="s1">'U'</span><span class="p">),</span>
            <span class="s1">'diff_for_humans'</span> <span class="o">=&gt;</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="nf">diffForHumans</span><span class="p">(),</span>
        <span class="p">],</span>
        <span class="c1">// OR class-based static method:</span>
        <span class="nc">Carbon\Carbon</span><span class="o">::</span><span class="n">class</span> <span class="o">=&gt;</span> <span class="s1">'App\Console\Casters::carbon'</span><span class="p">,</span>
    <span class="p">],</span>
<span class="p">];</span>

<span class="c1">// app/Console/Casters.php</span>
<span class="kd">class</span> <span class="nc">Casters</span>
<span class="p">{</span>
    <span class="k">public</span> <span class="k">static</span> <span class="k">function</span> <span class="n">carbon</span><span class="p">(</span><span class="err">\</span><span class="nc">Carbon\Carbon</span> <span class="nv">$carbon</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="k">return</span> <span class="p">[</span>
            <span class="s1">'date'</span> <span class="o">=&gt;</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="n">date</span><span class="p">,</span>
            <span class="s1">'weekday'</span> <span class="o">=&gt;</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="nf">format</span><span class="p">(</span><span class="s1">'l'</span><span class="p">),</span>
            <span class="s1">'day_of_year'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">int</span><span class="p">)</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="nf">format</span><span class="p">(</span><span class="s1">'z'</span><span class="p">),</span>
            <span class="s1">'unix'</span> <span class="o">=&gt;</span> <span class="p">(</span><span class="n">int</span><span class="p">)</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="nf">format</span><span class="p">(</span><span class="s1">'U'</span><span class="p">),</span>
            <span class="s1">'diff_for_humans'</span> <span class="o">=&gt;</span> <span class="nv">$carbon</span><span class="o">-&gt;</span><span class="nf">diffForHumans</span><span class="p">(),</span>
        <span class="p">];</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>And we are up &amp; running!</p>

<p>Let’s see that in action before we dive into the code:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>=&gt; Carbon\Carbon @1519569240 {#745
 +date: "2018-02-25 14:34:00.000000",
 +weekday: "Sunday",
 +day_of_year: 55,
 +unix: 1519569240,
 +diff_for_humans: "6 days ago",
}
</code></pre></div></div>

<p>PS. Soon you will be able to customize casters without hassle, as I’ve already pushed a PR, which provides this functionality out-of-the-box:</p>

<p><a href="https://github.com/laravel/tinker/pull/39">https://github.com/laravel/tinker/pull/39</a></p>]]></content><author><name></name></author><category term="laravel" /><category term="tinker" /><category term="psysh" /><category term="php" /><category term="repl" /><summary type="html"><![CDATA[I made a series about psysh and Laravel’s tinker – powerful REPL where you can play with your whole application.]]></summary></entry><entry><title type="html">Too much magic will kill you or at least bite your ass</title><link href="https://softonsofa.com/too-much-magic-will-kill-you-or-at-least-bite-your-ass/" rel="alternate" type="text/html" title="Too much magic will kill you or at least bite your ass" /><published>2017-07-13T04:00:00+00:00</published><updated>2017-07-13T04:00:00+00:00</updated><id>https://softonsofa.com/too-much-magic-will-kill-you-or-at-least-bite-your-ass</id><content type="html" xml:base="https://softonsofa.com/too-much-magic-will-kill-you-or-at-least-bite-your-ass/"><![CDATA[]]></content><author><name></name></author><category term="coding" /><category term="laravel" /><category term="php" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Tinker like a boss helpers</title><link href="https://softonsofa.com/tinker-like-a-boss-helpers/" rel="alternate" type="text/html" title="Tinker like a boss helpers" /><published>2017-07-09T04:00:00+00:00</published><updated>2017-07-09T04:00:00+00:00</updated><id>https://softonsofa.com/tinker-like-a-boss-helpers</id><content type="html" xml:base="https://softonsofa.com/tinker-like-a-boss-helpers/"><![CDATA[]]></content><author><name></name></author><category term="coding" /><category term="laravel" /><category term="php" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Tinker like a boss in psysh</title><link href="https://softonsofa.com/tinker-like-a-boss-in-psysh/" rel="alternate" type="text/html" title="Tinker like a boss in psysh" /><published>2016-09-26T04:00:00+00:00</published><updated>2016-09-26T04:00:00+00:00</updated><id>https://softonsofa.com/tinker-like-a-boss-in-psysh</id><content type="html" xml:base="https://softonsofa.com/tinker-like-a-boss-in-psysh/"><![CDATA[]]></content><author><name></name></author><category term="coding" /><category term="laravel" /><category term="php" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">They can bite how not to use accessors in eloquent</title><link href="https://softonsofa.com/they-can-bite-how-not-to-use-accessors-in-eloquent/" rel="alternate" type="text/html" title="They can bite how not to use accessors in eloquent" /><published>2016-09-20T04:00:00+00:00</published><updated>2016-09-20T04:00:00+00:00</updated><id>https://softonsofa.com/they-can-bite-how-not-to-use-accessors-in-eloquent</id><content type="html" xml:base="https://softonsofa.com/they-can-bite-how-not-to-use-accessors-in-eloquent/"><![CDATA[]]></content><author><name></name></author><category term="coding" /><category term="laravel" /><category term="php" /><summary type="html"><![CDATA[]]></summary></entry><entry><title type="html">Querying relations in laravel get models where latest related is</title><link href="https://softonsofa.com/querying-relations-in-laravel-get-models-where-latest-related-is/" rel="alternate" type="text/html" title="Querying relations in laravel get models where latest related is" /><published>2015-12-02T04:00:00+00:00</published><updated>2015-12-02T04:00:00+00:00</updated><id>https://softonsofa.com/querying-relations-in-laravel-get-models-where-latest-related-is</id><content type="html" xml:base="https://softonsofa.com/querying-relations-in-laravel-get-models-where-latest-related-is/"><![CDATA[]]></content><author><name></name></author><category term="coding" /><category term="laravel" /><category term="php" /><summary type="html"><![CDATA[]]></summary></entry></feed>