<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Naster Blue</title>
    <description>The latest articles on DEV Community by Naster Blue (@nasterblue).</description>
    <link>https://dev.to/nasterblue</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F254547%2Fc00ffd8c-c2e1-490b-9bae-a1a43dfd3a29.jpg</url>
      <title>DEV Community: Naster Blue</title>
      <link>https://dev.to/nasterblue</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nasterblue"/>
    <language>en</language>
    <item>
      <title>Install and run Asgard CMS by docker stack</title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Sat, 22 Feb 2020 13:04:28 +0000</pubDate>
      <link>https://dev.to/nasterblue/install-and-run-asgard-cms-by-docker-stack-399</link>
      <guid>https://dev.to/nasterblue/install-and-run-asgard-cms-by-docker-stack-399</guid>
      <description>&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;We will install and run Asgard CMS by docker stack :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NGINX web server
MYSQL database
REDIS cache
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;a href="https://asgardcms.com/"&gt;AsgardCms
A modular multilingual CMS built with Laravel 5, with an MIT license.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://laradock.io/"&gt;Laradock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/bss-taiphung/asgardcms-docker"&gt;Demo Source code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  System Requirements
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;docker
docker-compose
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Directory Structure
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+ asgardcms-docker &amp;lt;root directory&amp;gt;
  + laradock &amp;lt;docker stack&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  1.Build Docker stack
&lt;/h1&gt;

&lt;p&gt;1.0.Working directory : &lt;code&gt;/laradock &amp;lt;docker stack&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  asgardcms-docker &lt;span class="nb"&gt;cd &lt;/span&gt;laradock 
➜  laradock git:&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; ✗ 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;1.1.Create .env&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  laradock git:&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; ✗ &lt;span class="nb"&gt;cp &lt;/span&gt;env-example  .env
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;1.2.Then update mysql/nginx/redis configuration in .env&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Define the prefix of container names.&lt;/span&gt;
&lt;span class="nv"&gt;COMPOSE_PROJECT_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;asgardcms-laradock
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# PHP version of the Workspace and PHP-FPM containers&lt;/span&gt;
&lt;span class="c"&gt;# Accepted values: 7.4 - 7.3 - 7.2 - 7.1 - 7.0 - 5.6&lt;/span&gt;
&lt;span class="nv"&gt;PHP_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;7.3
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;### MYSQL #####&lt;/span&gt;
&lt;span class="nv"&gt;MYSQL_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;latest
&lt;span class="nv"&gt;MYSQL_DATABASE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;asgardcms
&lt;span class="nv"&gt;MYSQL_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;asgardcms
&lt;span class="nv"&gt;MYSQL_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;asgardcms
&lt;span class="nv"&gt;MYSQL_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;3306
&lt;span class="nv"&gt;MYSQL_ROOT_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;asgardcms

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;### REDIS #####&lt;/span&gt;
&lt;span class="nv"&gt;REDIS_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;6379

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;





&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;### NGINX #####&lt;/span&gt;
&lt;span class="nv"&gt;NGINX_HOST_HTTP_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;80
&lt;span class="nv"&gt;NGINX_HOST_HTTPS_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;443
&lt;span class="nv"&gt;NGINX_HOST_LOG_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./logs/nginx/
&lt;span class="nv"&gt;NGINX_SITES_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./nginx/sites/
&lt;span class="nv"&gt;NGINX_PHP_UPSTREAM_CONTAINER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;php-fpm
&lt;span class="nv"&gt;NGINX_PHP_UPSTREAM_PORT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;9000
&lt;span class="nv"&gt;NGINX_SSL_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;./nginx/ssl/

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;1.3.Run docker-compose&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  laradock git:&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; ✗ docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt; nginx mysql redis laravel-horizon
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;1.4.Verify all done&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  laradock git:&lt;span class="o"&gt;(&lt;/span&gt;master&lt;span class="o"&gt;)&lt;/span&gt; ✗ docker ps
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                                 NAMES
acfe204292b1        asgardcms-laradock_nginx             &lt;span class="s2"&gt;"/bin/bash /opt/star…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       81/tcp, 0.0.0.0:80-&amp;gt;80/tcp, 443/tcp   asgardcms-laradock_nginx_1
6bbdcadef86b        asgardcms-laradock_php-fpm           &lt;span class="s2"&gt;"docker-php-entrypoi…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       9000/tcp                              asgardcms-laradock_php-fpm_1
6848c2af2394        asgardcms-laradock_laravel-horizon   &lt;span class="s2"&gt;"/usr/bin/supervisor…"&lt;/span&gt;   28 minutes ago      Up 28 minutes                                             asgardcms-laradock_laravel-horizon_1
e2cdbc9b3784        asgardcms-laradock_workspace         &lt;span class="s2"&gt;"/sbin/my_init"&lt;/span&gt;          28 minutes ago      Up 28 minutes                                             asgardcms-laradock_workspace_1
f8373d74d46a        asgardcms-laradock_mysql             &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       0.0.0.0:3306-&amp;gt;3306/tcp, 33060/tcp     asgardcms-laradock_mysql_1
ab08ba38616f        asgardcms-laradock_redis             &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       0.0.0.0:6379-&amp;gt;6379/tcp                asgardcms-laradock_redis_1
23868938380e        docker:19.03-dind                    &lt;span class="s2"&gt;"dockerd-entrypoint.…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       2375-2376/tcp                         asgardcms-laradock_docker-in-docker_1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  2.Install and run Asgard CMS
&lt;/h1&gt;

&lt;p&gt;2.0.Working directory : &lt;code&gt;asgardcms-docker &amp;lt;root directory&amp;gt;&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  asgardcms-docker docker ps
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                                 NAMES
acfe204292b1        asgardcms-laradock_nginx             &lt;span class="s2"&gt;"/bin/bash /opt/star…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       81/tcp, 0.0.0.0:80-&amp;gt;80/tcp, 443/tcp   asgardcms-laradock_nginx_1
6bbdcadef86b        asgardcms-laradock_php-fpm           &lt;span class="s2"&gt;"docker-php-entrypoi…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       9000/tcp                              asgardcms-laradock_php-fpm_1
6848c2af2394        asgardcms-laradock_laravel-horizon   &lt;span class="s2"&gt;"/usr/bin/supervisor…"&lt;/span&gt;   28 minutes ago      Up 28 minutes                                             asgardcms-laradock_laravel-horizon_1
e2cdbc9b3784        asgardcms-laradock_workspace         &lt;span class="s2"&gt;"/sbin/my_init"&lt;/span&gt;          28 minutes ago      Up 28 minutes                                             asgardcms-laradock_workspace_1
f8373d74d46a        asgardcms-laradock_mysql             &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       0.0.0.0:3306-&amp;gt;3306/tcp, 33060/tcp     asgardcms-laradock_mysql_1
ab08ba38616f        asgardcms-laradock_redis             &lt;span class="s2"&gt;"docker-entrypoint.s…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       0.0.0.0:6379-&amp;gt;6379/tcp                asgardcms-laradock_redis_1
23868938380e        docker:19.03-dind                    &lt;span class="s2"&gt;"dockerd-entrypoint.…"&lt;/span&gt;   28 minutes ago      Up 28 minutes       2375-2376/tcp                         asgardcms-laradock_docker-in-docker_1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;2.1.Enter the Workspace container, to execute commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  asgardcms-docker docker &lt;span class="nb"&gt;exec&lt;/span&gt;  &lt;span class="nt"&gt;-it&lt;/span&gt; e2cdbc9b3784 bash
root@e2cdbc9b3784:/var/www# 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;2.2.Install the Asgard CMS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;➜  asgardcms-docker docker &lt;span class="nb"&gt;exec&lt;/span&gt;  &lt;span class="nt"&gt;-it&lt;/span&gt; e2cdbc9b3784 bash
root@e2cdbc9b3784:/var/www# php artisan asgard:install

  Welcome!                              
  Starting the installation process...  

Successfully created .env file

 Enter your database driver &lt;span class="o"&gt;(&lt;/span&gt;e.g. mysql, pgsql&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;mysql]:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; mysql

 Enter your database host &lt;span class="o"&gt;[&lt;/span&gt;127.0.0.1]:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; mysql

 Enter your database port &lt;span class="o"&gt;[&lt;/span&gt;3306]:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 3306

 Enter your database name &lt;span class="o"&gt;[&lt;/span&gt;homestead]:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; asgardcms

 Enter your database username &lt;span class="o"&gt;[&lt;/span&gt;homestead]:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; asgardcms

 Enter your database password &lt;span class="o"&gt;(&lt;/span&gt;leave &amp;lt;none&amp;gt; &lt;span class="k"&gt;for &lt;/span&gt;no password&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;secret]:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; asgardcms

Database successfully configured

 Enter you application url &lt;span class="o"&gt;(&lt;/span&gt;e.g. http://localhost, http://dev.example.com&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;http://localhost]:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; http://localhost


  User Module                        
  Starting the User Module setup...  


 Enter your first name:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; naster

 Enter your last name:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; blue

 Enter your email address:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; taipv.uit@gmail.com

 Enter a password:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

 Please confirm your password:
 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 

Please &lt;span class="nb"&gt;wait &lt;/span&gt;&lt;span class="k"&gt;while &lt;/span&gt;the admin account is configured...
The application is now installed
Platform ready! You can now login with your username and password at /backend

&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;2.3 Configuration file .env need to be update too&lt;br&gt;
From&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REDIS_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;127.0.0.1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;REDIS_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;redis
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;2.3 Open your browser and visit your localhost address. Happy hacking!&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CFuQjOQN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/falsdpxzk13jpm1ofcpt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CFuQjOQN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/falsdpxzk13jpm1ofcpt.png" alt="Login"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MC04nQ-V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/decsesoh18mqgpirmii0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MC04nQ-V--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/decsesoh18mqgpirmii0.png" alt="Edit Admin Role"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>asgardcms</category>
      <category>docker</category>
      <category>dockercompose</category>
    </item>
    <item>
      <title>Implement Repository Design Pattern in Laravel</title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Wed, 04 Dec 2019 18:39:39 +0000</pubDate>
      <link>https://dev.to/nasterblue/implement-repository-design-pattern-in-laravel-2138</link>
      <guid>https://dev.to/nasterblue/implement-repository-design-pattern-in-laravel-2138</guid>
      <description>&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-us/previous-versions/msp-n-p/ff649690(v=pandp.10)?redirectedfrom=MSDN" rel="noopener noreferrer"&gt;# The Repository Pattern&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fprevious-versions%2Fmsp-n-p%2Fimages%2Fff649690.4058e458-bd54-4597-845e-6f8b1a21cfc3%2528en-us%252cpandp.10%2529.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fprevious-versions%2Fmsp-n-p%2Fimages%2Fff649690.4058e458-bd54-4597-845e-6f8b1a21cfc3%2528en-us%252cpandp.10%2529.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Use case
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;We have Post resource&lt;/li&gt;
&lt;li&gt;Need to implement controller to support APIs for these features :&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Get all posts&lt;br&gt;
 Paginate posts&lt;br&gt;
 Find posts with condition&lt;br&gt;
 Find post by id&lt;br&gt;
 Caching APIs to improve performance&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Preparation
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Post model (database driver can be MySQL/ PostgreSQL/ SQLite/ SQL Server)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;  

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Eloquent\Model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;  
&lt;span class="p"&gt;{&lt;/span&gt;  
  &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'posts'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Contract
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Contracts&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;RepositoryInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Retrieve all data of repository
     *
     * @param array $columns
     *
     * @return mixed
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Retrieve all data of repository, paginated
     *
     * @param null $limit
     * @param array $columns
     *
     * @return mixed
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Find data by multiple fields
     *
     * @param array $where
     * @param array $columns
     *
     * @return mixed
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * Find data by id
     *
     * @param       $id
     * @param array $columns
     *
     * @return mixed
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Implementation Details
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Newbie/Beginner/Fresher/Intern level
&lt;/h2&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Contracts\RepositoryInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Post&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;  &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RepositoryInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Post&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$where&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$field&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Database Repository/ Junior Level
&lt;/h2&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Contracts\RepositoryInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Post&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DbPostRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RepositoryInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Post&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$where&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$field&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$val&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;model&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;post&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DbPostController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$dbPostRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DbPostRepository&lt;/span&gt; &lt;span class="nv"&gt;$dbPostRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$dbPostRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;h2&gt;
  
  
  Caching Repository/ Senior Level
&lt;/h2&gt;


&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Http\Controllers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Http\Contracts\RepositoryInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Contracts\Cache\Repository&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;CacheRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CachePostRepository&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;RepositoryInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$dbPostRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$cacheRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DbPostRepository&lt;/span&gt; &lt;span class="nv"&gt;$dbPostRepository&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;CacheRepository&lt;/span&gt; &lt;span class="nv"&gt;$cacheRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$dbPostRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cacheRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$cacheRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getCacheMinutes&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'repository.cache.minutes'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getCacheKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;app&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Illuminate\Http\Request'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$args&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$criteria&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;serializeCriteria&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'%s@%s-%s'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;get_called_class&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;$method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;md5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$args&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$criteria&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;fullUrl&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCacheKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'all'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;func_get_args&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nv"&gt;$minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCacheMinutes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cacheRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCacheKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'paginate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;func_get_args&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nv"&gt;$minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCacheMinutes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cacheRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCacheKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'findWhere'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;func_get_args&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nv"&gt;$minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCacheMinutes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cacheRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCacheKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'find'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;func_get_args&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
        &lt;span class="nv"&gt;$minutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getCacheMinutes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cacheRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$minutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;use&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;dbPostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CachePostController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$cachePostRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CachePostRepository&lt;/span&gt; &lt;span class="nv"&gt;$cachePostRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cachePostRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$cachePostRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cachePostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cachePostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cachePostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;findWhere&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$where&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;cachePostRepository&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$columns&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>repositorydesignpattern</category>
      <category>laravel</category>
      <category>laravelcachingapi</category>
      <category>cachingapi</category>
    </item>
    <item>
      <title>Nhân Sinh Như Mộng</title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Tue, 03 Dec 2019 16:05:48 +0000</pubDate>
      <link>https://dev.to/nasterblue/nhan-sinh-nh-m-ng-ghj</link>
      <guid>https://dev.to/nasterblue/nhan-sinh-nh-m-ng-ghj</guid>
      <description>&lt;p&gt;Một nhà doanh nghiệp rất nổi tiếng, cứ cách một đoạn thời gian, ông lại dẫn theo vợ con đến nơi hỏa táng để xem. Có người không hiểu, hỏi ông nguyên do. Ông nói rằng, chỉ cần đến  nơi hỏa táng, cái tâm nóng nảy sẽ rất mau chóng an tĩnh lại, thấy danh lợi tiền tài thật nhẹ nhàng. Ở nơi hỏa táng này, không kể bạn là quan to quý tộc quyền cao chức trọng, uy danh hiển hách hay  là một người dân bình thường, nghèo rớt mồng tơi, không ai biết đến, cuối cùng đều sẽ phải đến đây, chung một tư thế, lặng yên nằm xuống, sau đó bị đưa vào bên trong lò hỏa táng đang bốc cháy ngùn ngụt, khi trở ra lần nữa, thì chỉ là một chiếc hộp vuông nho nhỏ được bọc trong tấm vải đỏ.&lt;/p&gt;

&lt;p&gt;Khi đến chẳng mang theo thứ gì, khi đi chỉ như một làn khói. Đời người chính là đơn giản như vậy! Vinh hoa phú quý phút chốc thoáng qua, ân ái tình thù cũng chỉ như cát bụi. Hôm nay sống trong một thế giới vật chất dục vọng tràn lan, bên cạnh chúng ta là đầy những cám dỗ mê hoặc: quyền lực, địa vị, tiền bạc, mỹ sắc.., hễ không  cẩn thận, thì trong tâm sẽ dậy sóng. Nội tâm chúng ta vốn dĩ trong sáng, thuần tịnh, bình lặng sẽ trở nên ngông cuồng, ngạo mạn và tư lợi.&lt;/p&gt;

&lt;p&gt;Khi bạn cảm thấy hiện thực và lý tưởng có sự chênh lệch,&lt;br&gt;
Khi bạn cảm thấy uất ức thương tâm, không có người hiểu bạn,&lt;br&gt;
Khi bạn vì ân oán tình thù mà canh cánh trong lòng,&lt;br&gt;
Khi bạn vì lợi ích được mất mà so đo tính toán,&lt;br&gt;
Khi bạn khom lưng chau mày đối với quyền thế,&lt;br&gt;
Khi bạn vì địa vị cao thấp mà mưu tính hại nhau…&lt;/p&gt;

&lt;p&gt;Sao bạn không đi đến nơi hỏa táng xem thử, đối diện với một nắm tro bụi, bạn còn có gì không buông xuống được đây? &lt;br&gt;
Đời người tựa như một giấc mộng! Tuyệt đối đừng nói rằng bạn có tiền..!!??&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Đã biết chốn ni là quán trọ&lt;br&gt;
   Hơn, thua, hờn oán.. để mà chi!&lt;br&gt;
   Thử ra ngồi xuống bên phần mộ&lt;br&gt;
   Hỏi họ mang theo được những gì..&lt;/p&gt;

&lt;p&gt;Chốn ấy trăm năm ngỡ tít mờ&lt;br&gt;
   Đâu ngờ ập đến tựa cơn mơ.&lt;br&gt;
   Sống Thương và Hiểu từng giây phút&lt;br&gt;
   Ngay kiếp mong manh gặp bến bờ..&lt;br&gt;
   Như Nhiên&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Sống Với Nhau
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;Lần nọ một người hỏi đất&lt;br&gt;
Đất sống với nhau thế nào?&lt;br&gt;
Chúng tôi bao hàm, chấp nhận&lt;br&gt;
Tô bồi, xây đắp cho nhau.&lt;/p&gt;

&lt;p&gt;Lần kia người hỏi rừng cây&lt;br&gt;
Cây sống làm sao với bạn?&lt;br&gt;
Chúng tôi vui mọc sum vầy&lt;br&gt;
Chở che nhau, cùng hoạn nạn...&lt;/p&gt;

&lt;p&gt;Người hỏi mây trời phiêu lãng&lt;br&gt;
Thế nào bay lượn cùng nhau?&lt;br&gt;
Chúng tôi lòng không giới hạn&lt;br&gt;
Tan vào nhau thuở ban đầu!&lt;/p&gt;

&lt;p&gt;Rồi người hỏi thầm lá cỏ&lt;br&gt;
Chung sống bạn bè ra sao?&lt;br&gt;
Mặt đất đan xen, nương tựa&lt;br&gt;
Chia từng sương nắng... gửi, trao.&lt;/p&gt;

&lt;p&gt;Hỏi dòng sông xuôi năm tháng&lt;br&gt;
Thế nào nước nhịp nhàng trôi?&lt;br&gt;
Chúng tôi quyện hòa nhau chảy&lt;br&gt;
Dù khi sóng dập gió dồi…&lt;/p&gt;

&lt;p&gt;Rồi người gạn hỏi từng người&lt;br&gt;
Với nhau, thế nào ta sống?&lt;br&gt;
Không ai một tiếng trả lời&lt;br&gt;
Những pho tượng cười… di động.&lt;/p&gt;

&lt;p&gt;Đời còn dẫm nhau mà sống&lt;br&gt;
Người còn nặng những niềm riêng…&lt;br&gt;
Vì ngỡ kiếp đời miên viễn&lt;br&gt;
Tình Người, đạo đức xô nghiêng…&lt;/p&gt;

&lt;p&gt;Người về thương người nhỏ lệ&lt;br&gt;
Cúi mình lạy khắp thiên nhiên…&lt;/p&gt;

&lt;p&gt;Như Nhiên - Thích Tánh Tuệ&lt;br&gt;
  (phóng tác)&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Materialized View trong DBMS là gì ?</title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Wed, 06 Nov 2019 17:13:40 +0000</pubDate>
      <link>https://dev.to/nasterblue/materialized-view-trong-dbms-la-gi-cp8</link>
      <guid>https://dev.to/nasterblue/materialized-view-trong-dbms-la-gi-cp8</guid>
      <description>&lt;p&gt;Phong, một developer tại công ty BSS. Nhân, là nhân viên kế toán cùng công ty.&lt;/p&gt;

&lt;p&gt;Một ngày nọ thấy Nhân đang rảnh rỗi không có chuyện gì làm, Phong lấy hết can đảm của mình tới nhờ Nhân hỗ trợ tìm những giấy tờ có liên quan tới Phong bao gồm : bảng lương, bảo hiểm y tế &amp;amp; xã hội, sở hưu cơ sở vật chất được công ty cấp cho nhu cầu công việc MacBook Pro 2019, nhu cầu đi lại xe Mercedes S450, hoá đơn tiền xăng dầu,...&lt;/p&gt;

&lt;p&gt;Nhân trên danh nghĩa là người tiếp nhận cũng như tạo ra những loại giấy tờ kể trên để tổng hợp và cất giữ vào kho hồ sơ ở nhiều nơi. Đồng thời cũng là người sẽ phải tính toán và phân tích số liệu để đưa ra dự báo về tình hình phát triển của công ty. Nhân phải mất thời gian trung bình khoảng 5 ngày để giải quyết yêu cầu của Phong.&lt;/p&gt;

&lt;p&gt;Vấn đề làm sao để cải thiện hiệu năng làm việc và đáp ứng yêu cầu trả lời nhanh hơn hiện tại mà Nhân đang làm?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ya9lY1El--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ep6rt06onbabjpf414mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ya9lY1El--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/ep6rt06onbabjpf414mg.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hệ quản trị cơ sở dữ liệu (DBMS) &lt;/p&gt;

&lt;h2&gt;
  
  
  Database Table
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Là nơi lưu trữ data từ nhiều nguồn. &lt;/li&gt;
&lt;li&gt;Data lưu trữ dạng vật lý.&lt;/li&gt;
&lt;li&gt;Khi có nhu cầu tra cứu thông tin đã từng lưu trữ thì thông tin cũng được trích xuất ra từ những table này.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Database View (DV)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Đây là cách mà Nhân kế toán của BSS đang làm, Nhân phải lục lại tủ hồ sơ ở nhiều nơi để phân loại và tìm kiếm hồ sơ của Phong.&lt;/li&gt;
&lt;li&gt;DV là 1 use case hỗ trợ cho việc tra cứu trích xuất thông tin đơn giản hơn table . &lt;/li&gt;
&lt;li&gt;&lt;p&gt;DV được định nghĩa bởi 1 câu lệnh base SQL những logic structure của những tables sẽ trả về data (tuỳ vào số lượng tables được join và số lượng các điều kiện tham gia vào mà câu lệnh SQL này trở thành đơn giản hoặc phức tạp) &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tạo 1 DV :&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;documents_of_employee_phong_dv&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;documentId&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="err"&gt;à&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="err"&gt;ủ&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Phong&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Sử dụng DV:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;documents_of_employee_phong_dv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Thực ra câu lệnh SQL thực hiện bên dưới DBMS là :
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
     &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
     &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;documentId&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;DV không lưu trữ data, DV là 1 table ảo, chỉ cần quan tâm đến câu lệnh SQL. Nên khi trích xuất thông tin từ DV thực chất ra là đang chạy lại những câu lệnh base SQL ở trên.&lt;/li&gt;
&lt;li&gt;Câu lệnh base SQL đơn giản (join 1 table) thì DV đơn giản và ngược lại câu lệnh base SQL phức tạp (join nhiều table, nhiều điều kiện tham gia) thì DV phức tạp.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Materialized View (MV)
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Giống với DV là MV được định nghĩa bằng 1 câu lệnh base SQL&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nhưng khác với cách lưu data của DV. MV lưu data dạng vật lý. Data được lưu là kết quả trả về từ câu lệnh base SQL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tạo 1 DV :&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="n"&gt;MATERIALIZED&lt;/span&gt;  &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;documents_of_employee_phong_mv&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;userId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;documents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;document_histories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;documentId&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;employees&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;//&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="err"&gt;à&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="err"&gt;ủ&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;Phong&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Tốc độ trích xuất thông tin từ MV nhanh hơn gấp nhiều lần so với DV vì data đang được lưu tương tự như database table đồng thời không tốn thời gian chạy lại câu lệnh base SQL . Trích xuất data trực tiếp vào table không thông qua câu lệnh base SQL.&lt;/li&gt;
&lt;li&gt;Nhân có thể tăng hiệu năng làm việc và cung cấp các giấy tờ cho Phong nhanh hơn từ 5 ngày xuống còn 1/2 ngày bằng cách mỗi lần khi nhận giấy tờ từ Phong thì Nhân nên đặt tất cả giấy tờ đó vào 1 túi hồ sơ dán tên Phong. Giờ đây khi có bất cứ khi nào Phong nhờ vã cung cấp hồ sơ giấy tờ  thì Nhân đều có thể tự tin hỗ trợ Phong ngay lập tức. Còn nhờ vã những chuyện ngoài khả năng như đi chơi, ăn uống thì khó quá nên bỏ qua.&lt;/li&gt;
&lt;li&gt;MV mang lại hiệu năng cao như vậy nhưng gặp phải vấn đề là vấn đề đồng bộ data mới nhất. Một lần nọ, Nhân đang bận đầu tắt mặt tối cả ngày thì Phong đưa hoá đơn tiền xăng xe cho Nhân nhưng sau đó Nhân để đâu quên mất và không cất vào túi hồ sơ của Phong. Nên hoá đơn này chắc chắn sau này sẽ không bao giờ đến được tay của Phong. Tốt nhất nếu Nhân quá bận rộn công việc thì nên cài đặt nhắc nhở trên điện thoại bổ sung túi hồ sơ của Phong sau đó.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;MV cũng có cơ chế tương tự để đồng bộ hoá data mới nhất như vậy nhưng cách tiếp cận theo 2 hướng:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;BASIC REFRESH 

&lt;ul&gt;
&lt;li&gt;DBMS cần thực hiện câu lệnh REFRESH MV để update data mới nhất (ví dụ như sau khi có data mới, data bị xoá hoặc có chỉnh sửa data sẽ ảnh hưởng với kết quả sai khác trả về trước đó). BASIC REFRESH sẽ READ LOCKING tất cả truy xuất tới MV khi đang trong quá trình thực hiện update data (để ngăn ngừa truy xuất ra thông tin cũ rích, sai khác dẫn đến ảnh hưởng gây ra hậu quả nghiêm trọng cho người dùng lẫn hệ thống).
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="n"&gt;REFRESH&lt;/span&gt; &lt;span class="n"&gt;MATERIALIZE&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;documents_of_employee_phong_mv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;



&lt;ul&gt;
&lt;li&gt;CONCURRENTLY REFRESH

&lt;ul&gt;
&lt;li&gt;Trong một số trường hợp data không bị quá đòi hỏi khắc khe phải trả về kết quả cập nhật mới nhất, nên có thể trả về data đang trong quá trình tiền xử lý, data trong suốt với người dùng  ví dụ như thông tin về tên/thông số sản phẩm trên ecommerce không nên để client ngồi chờ cả vài phút để chờ thực hiện xong lệnh update mới coi được. CONCURRENTLY REFRESH dùng để giải quyết READ LOCKING.
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;pre class="highlight sql"&gt;&lt;code&gt;  &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;UNIQUE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;documents_employee_ix&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;documents_of_employee_phong_mv&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;document_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="n"&gt;REFRESH&lt;/span&gt; &lt;span class="n"&gt;MATERIALIZED&lt;/span&gt; &lt;span class="k"&gt;VIEW&lt;/span&gt; &lt;span class="n"&gt;CONCURRENTLY&lt;/span&gt; &lt;span class="n"&gt;documents_of_employee_phong_mv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>materializedview</category>
      <category>databaseview</category>
      <category>datawarehousing</category>
      <category>dbms</category>
    </item>
    <item>
      <title>JSON Web Tokens (JWT) là gì ?</title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Thu, 31 Oct 2019 19:11:05 +0000</pubDate>
      <link>https://dev.to/nasterblue/json-web-tokens-jwt-la-gi-16f1</link>
      <guid>https://dev.to/nasterblue/json-web-tokens-jwt-la-gi-16f1</guid>
      <description>&lt;p&gt;Chúng ta đều biết thủ tục chung để xác thực user trong ứng dụng của mình. Đó là phương pháp đăng ký user với thông tin cơ bản như email, password. Tại thời điểm user đăng nhập ứng dụng, hệ thống sẽ kiểm tra trùng khớp email, password đã cho với dữ liệu được lưu trước đó. Nếu phù hợp thì cho user truy cập, nếu không thì chặn user lại.&lt;/p&gt;

&lt;p&gt;Chúng ta cũng biết thủ tục phân quyền user trong một ứng dụng. Đó là user bình thường chỉ được truy cập tính năng cơ bản (user xài free), những chức năng nâng cao chỉ giành cho những premium user (user chấp nhận thực hiện thanh toán tiền), admin user có quyền truy cập quản lý dashboard, sale admin có thể truy cập để xem thống kê và xuất ra file excel report theo tháng/ năm, ...&lt;/p&gt;

&lt;p&gt;Luồng cơ bản của xác thực dựa trên token (Stateful Token):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User nhập email/password trong form đăng nhập và gởi lên server.&lt;/li&gt;
&lt;li&gt;Server xác minh email/password này là chính xác sẽ tạo ra 1 unique token đồng thời lưu vào database. Sau đó server sẽ trả về cho user 1 token có chứa một số thông tin dưới dạng json như user_id, role, permission.&lt;/li&gt;
&lt;li&gt;Token này sẽ được lưu trữ phía user (cookie). &lt;/li&gt;
&lt;li&gt;Các request APIs tiếp theo đến server sẽ phải đính kèm token này vào header hoặc body của request.Server sẽ query database để kiểm tra nếu token này hợp lệ sẽ tiếp tục xử lý request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Client side :
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Server side
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Closure&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckUserRolePermissions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $role
     * @return mixed
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Closure&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$permission&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Authorization'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$currentUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;findByToken&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$currentUser&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
          &lt;span class="c1"&gt;// query database lấy ra những role của user này &lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$currentUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;hasRole&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$role&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Redirect...&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="c1"&gt;// query database lấy ra những permissions của user này &lt;/span&gt;
          &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nv"&gt;$currentUser&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;hasPermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$permission&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Redirect...&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="c1"&gt;// Redirect...&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Khi user logout, token bị hủy ở phía user và server sẽ xoá token này ra khỏi database.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nhưng thời gian luôn trôi qua nhanh cùng với rất phương thức xác thực và phân quyền khác cũng được ra đời. Ứng dụng liên tục mở rộng thêm chức năng mới và ngày càng phình to trở thành siêu ứng dụng. Đồng thời số lượng user cũng tăng lên đột biến. Để đảm bảo trải nghiệm tốt cho user thì hệ thống buộc phải scale up theo chiều ngang (horizontal scale) hết cỡ có thể. Từ một hệ thống duy nhất có kiến trúc đơn khối (Monolithic) nên được chia ra thành những hệ thống con (vật lý) đơn nhiệm (chỉ thực hiện đúng 1 loại nhiệm vụ chức năng). Kiến trúc hệ thống cũ chuyển sang kiến trúc hướng dịch vụ (Microservices): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mỗi service (đơn nhiệm) phải tự xác thực và phân quyền cho chính mình. Nếu clone source code xác thực và phân quyền từ hệ thống cũ sang từng service để tái sử dụng lại sẽ khiến việc maintain khi có bất cứ thay đổi gì trở nên tốn thời gian và phức tạp.&lt;/li&gt;
&lt;li&gt;Mỗi service (đơn nhiệm) nên chỉ thực hiện đúng 1 loại nhiệm vụ chức năng của cuộc đời nó, không nên làm mất tập trung sang những việc không phải nhiệm vụ chức năng của nó là xác thực và phân quyền.&lt;/li&gt;
&lt;li&gt;Kiến trúc Microservices khiến các service cần phải communicate với nhau, các request tới các service cũng tăng lên để lấy đủ dữ liệu từ nhiều service (ví dụ : sau khi add product vào cart thì khi tạo order sẽ cần request sang customer service lấy thông tin credit của customer có còn đủ để place order hay không, có thể request sang inventory service để kiểm tra còn hàng hay không, ... ). Nếu tiếp tục sử dụng cách xác thực, phân quyền theo Stateful Token sẽ làm performance thấp đi đáng kể, low latency (do query database để kiểm tra token quá nhiều lần).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JSON Web Tokens (JWT) là 1 loại Stateless token, có những ưu điểm vượt trội hơn Stateful token và thích hợp hơn khi áp dụng cho xác thực và phân quyền kiến trúc Microserives :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Token không lưu vào database. &lt;/li&gt;
&lt;li&gt;Không cần query database kiểm tra chi đỡ tốn thời gian và resource.&lt;/li&gt;
&lt;li&gt;JWT đảm bảo xác thực, phân quyền tốt cho cả users-to-services, services-to-services.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;JWT được bảo vệ và đảm bảo tính toàn vẹn dữ liệu bằng chữ ký số (Digitally Signed). Chữ ký số (Digitally Signed) được mã hoá bằng hệ mã hoá đối xứng HMAC hoặc bất đối xứng RSA.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;HMAC là hệ mã hoá đối xứng (Symmetric cryptography) : ví dụ 1 ổ khoá luôn có ít nhất 2 chìa khoá để backup lại phòng khi mất. Sau khi khoá cửa căn nhà lại thì ai có chìa khoá đều có thể mở cửa căn nhà ra lại. Hệ mã hoá và giải mã dùng chung 1 private key. Private key bị share ra cả client/server nên dễ bị lộ dẫn đến kém bảo mật.&lt;/li&gt;
&lt;li&gt;RSA là hệ mã hoá bất đối xứng (Asymmetric cryptography): ví dụ Nhân gởi 1 bức thư tay thông qua đường bưu điện tới nhà Phong. Nhân viên bưu điện sẽ mang bức thư tay tới tận địa chỉ nhà được ghi trên thư để xác nhận và giao cho đúng người nhận là Phong. Hệ mã hoá bất đối xứng cần public key (public cho mọi người đều biết) để mã hoá, người nhận cần private key (giữ bí mật không nên để lộ) để giải mã. Hệ mã hoá bất đối xứng dùng để kiểm tra tính toàn vẹn của dữ liệu không bị thay đổi/giả mạo. Địa chỉ Phong có thể được xem là public key, và để xác nhận là Phong thì giấy chứng minh nhân dân có thể được xem là private key. Private key được lưu trên server dùng để giải mã. Bảo mật cao hơn. RSA là hệ mã hoá thích hợp dùng cho chữ ký số (Digitally Signed) do vấn đề tính bảo mật tốt hơn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Chữ ký số (Digitally Signed): vai trò private key và public key trong RSA bị đảo ngược. Để tạo chữ ký số thì sẽ dùng private key, người nhận sẽ dùng public key để giải mã chữ ký số đó và xác thực xem chữ ký số có toàn vẹn không bị thay đổi/ giả mạo. Làm bằng cách nào ?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trong chữ chữ ký số đã mã hoá có chuỗi hash đính kèm (encrypted hash)&lt;/li&gt;
&lt;li&gt;Người nhận dùng public key để giải mã, sau khi có thông tin đã giải mã thì người nhận tiến hành dùng hàm hash để tính toán lại chuỗi hash gốc (original hash), sau đó so sánh chuỗi với (encrypted hash) xem có trùng khớp nhau không để biết là dữ liệu vẫn đảm bảo tính toàn vẹn hoặc đã bị thay đổi/ giả mạo.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;3 thành phần của JWT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT có format : xxxxx.yyyyy.zzzzz&lt;/li&gt;
&lt;li&gt;Header : các thông tin về thuật toán signing, type của payload (JWT).&lt;/li&gt;
&lt;li&gt;Payload : các dữ liệu thực tế trong JSON format (user info, roles, permissions)&lt;/li&gt;
&lt;li&gt;Signature : chữ kí&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Xem thêm về [3 thành phần của JWT ][&lt;a href="https://jwt.io/introduction/"&gt;https://jwt.io/introduction/&lt;/a&gt;]&lt;/p&gt;

&lt;p&gt;Luồng cơ bản của xác thực dựa trên JWT (Stateless Token):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;User nhập email/password trong form đăng nhập và gởi lên server.&lt;/li&gt;
&lt;li&gt;Server xác minh email/password này là chính xác sẽ tạo ra 1 JWT không  lưu lại vào bất cứ đâu. Trong Payload của JWT có chưa JSON format (user info, roles, permissions). Server trả JWT này về cho user.&lt;/li&gt;
&lt;li&gt;Token này sẽ được lưu trữ phía user (cookie). &lt;/li&gt;
&lt;li&gt;Các request APIs tiếp theo đến các services sẽ phải đính kèm token này vào header hoặc body của request. Services tiếp nhận request sẽ dùng public key (khoá công khai ) để giải mã token , kiểm tra token này hợp lệ sẽ tiếp tục xử lý request.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Client side :
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJ5b3VyLWFwaS1rZXkiLCJqdGkiOiIwLjQ3MzYyOTQ0NjIzNDU1NDA1IiwiaWF0IjoxNDQ3MjczMDk2LCJleHAiOjE0NDcyNzMxNTZ9.fQGPSV85QPhbNmuu86CIgZiluKBvZKd-NmzM6vo11DM&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nx"&gt;done&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  Server side
&lt;/h1&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nn"&gt;Closure&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CheckUserRolePermissions&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * Handle the incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string  $role
     * @return mixed
     */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Closure&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$role&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$permission&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'Authorization'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
        &lt;span class="nv"&gt;$userRolePermission&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JWT&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
        &lt;span class="c1"&gt;// kiểm tra tính toàn vẹn dữ liệu bằng cách dùng khoá công khai giả mã, dùng hàm hash tạo ra chuổi hash từ JWT vừa nhận đồng thời kiểm tra chuổi hash sau khi giải mã có giống với chuổi hash trong JWT vừa nhận.&lt;/span&gt;
        &lt;span class="c1"&gt;// $userRolePermission : {user : object, userRoles: object[], userPermissions: object[]}&lt;/span&gt;
        &lt;span class="nv"&gt;$currentUser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nv"&gt;$userRolePermission&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$userRoles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nv"&gt;$userRolePermission&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;userRoles&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$userPermissions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="nv"&gt;$userRolePermission&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;userPermissions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$currentUser&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
          &lt;span class="c1"&gt;// check user roles và permissions&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
         &lt;span class="c1"&gt;// Redirect...&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Khi user logout, token bị hủy ở phía user&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>jwt</category>
      <category>statelesstoken</category>
      <category>authentication</category>
      <category>authorization</category>
    </item>
    <item>
      <title>CQRS - là gì</title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Mon, 21 Oct 2019 18:08:24 +0000</pubDate>
      <link>https://dev.to/nasterblue/cqrs-la-gi-244k</link>
      <guid>https://dev.to/nasterblue/cqrs-la-gi-244k</guid>
      <description>&lt;p&gt;Con người bắt đầu lưu trữ dữ liệu từ xưa bằng viết lên giấy đóng lại thành sách, sách có thể được viết lại cập nhật thêm và truyền từ đời này sang đời khác cho con cháu. Cùng với sự phát triển của công nghệ về sau thì dữ liệu được lưu trữ thành tệp, rồi bằng cơ sở dữ liệu bằng các hệ quản lý cơ sở dữ liệu như MySql, SqlServer, PostgreSQL, MongoDB, ...&lt;/p&gt;

&lt;p&gt;Bốn chức năng cơ bản mà một hệ quản trị cơ sở dữ liệu cần phải đảm đảo là C(Create : tạo mới) - R(Retrieve : đọc) - U(Update : cập nhật) - D(Delete : xoá). Có thể nhóm 4 chức năng cơ bản này lại thành 2 nhóm chức năng chính :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query Model - Nhóm chỉ thao tác đọc dữ liệu, cần có kết quả trả về.&lt;/li&gt;
&lt;li&gt;Command Model - Nhóm chỉ thao tác làm thay đổi dữ liệu, không cần trả về kết quả.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Đối với các ứng dụng quản lý truyền thống thì 2 nhóm này thuộc cùng một tập hợp các model để thao tác đọc và làm thay đổi dữ liệu.&lt;/p&gt;

&lt;p&gt;Ứng dụng quản lý sơ khai ban đầu do có ít người dùng nên dữ liệu lưu và truy cập rất ít nên hệ thống hoạt động không gặp vấn đề gì.&lt;br&gt;
Qua một thời gian sản phẩm được công chúng biết đến, công ty quyết định đưa đưa ứng dụng này ra thế giới khiến lượng truy cập tăng lên đột biến server phải chịu tải cả triệu request đồng đời, cùng với khối lượng dữ liệu người dùng tăng lên chóng mặt cả vài trăm Terabyte data mỗi ngày khiến cho hệ thống hiện tại trở nên quá chậm chạp và không đáp ứng được lượng yêu cầu truy cập.&lt;/p&gt;

&lt;p&gt;CQRS là viết tắt của Command Query Responsibility Segregation. Tách biệt hẳn 2 nhóm Query và Command Model về mặt vật lý. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Command &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tối ưu hoá cho thao tác thay đổi dữ liệu.&lt;/li&gt;
&lt;li&gt;Chỉ xài các truy vấn đơn giản.
&lt;/li&gt;
&lt;li&gt;Command model vẫn lưu trong DBMS cùng các khoá quan hệ giữa các bảng.&lt;/li&gt;
&lt;li&gt;Tính Consistency trong ACID (Atomicity, Consistency, Isolation, Durability) phải được hạ thấp và đánh đổi. &lt;/li&gt;
&lt;li&gt;Tập trung xử lý business logic trong Bounded Context.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Query &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tối ưu hoá cho thao tác đọc dữ liệu.&lt;/li&gt;
&lt;li&gt;Xài cho các truy vấn cực kỳ phức tạp.&lt;/li&gt;
&lt;li&gt;Query model có thể lưu trong GraphQL, Cached (Redis), Materialized View (Oracle, PostgreSQL, SQL Server), MongoDB, Elastic, ... hỗ trợ query nhanh, tăng tốc độ đọc nhanh đến chóng mặt.&lt;/li&gt;
&lt;li&gt;Đồng bộ data cho Query Model sẽ có độ trễ hơn so với Command Model data (Eventual Consistency) thông qua message queue.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MpasJPJT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/46tvw927ysd2ru43zkxm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MpasJPJT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/46tvw927ysd2ru43zkxm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cqrs</category>
      <category>querymodel</category>
      <category>commandmodel</category>
      <category>eventsourcing</category>
    </item>
    <item>
      <title>DDD - Bounded Context là gì ? </title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Mon, 21 Oct 2019 12:47:26 +0000</pubDate>
      <link>https://dev.to/nasterblue/ddd-bounded-context-la-gi-54gb</link>
      <guid>https://dev.to/nasterblue/ddd-bounded-context-la-gi-54gb</guid>
      <description>&lt;p&gt;Bounded Context (BC) là gì?&lt;/p&gt;

&lt;p&gt;BC là một trong những nguyên tắc DDD khó giải thích nhất, nhưng có lẽ nó là quan trọng nhất, bởi vì sẽ không thể làm DDD mà không có BC. Vì vậy, phải hiểu cách xác định BC trước khi thực sự tìm hiểu đến với Aggregate Roots, Aggregates, Entities and Value Objects.&lt;br&gt;&lt;br&gt;
Một Context mang ý nghĩa là một phòng ban trong một công ty sẽ đảm nhận một trách nhiệm cụ thể. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bộ phận kinh doanh sẽ hỗ trợ thương mại, tác nghiệp kinh doanh. &lt;/li&gt;
&lt;li&gt;Bộ phận R&amp;amp;D sẽ chịu trách nhiệm nghiên cứu phát triển sản phẩm mới, nghiên cứu gia tăng tính năng, chất lượng sản phẩm hiện hữu, xây dựng và triển khai các dự án kinh doanh, công trình, sản xuất,...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Phong, một developer tại công ty BSS. Phong làm việc trong bộ phận CNTT.&lt;br&gt;
Bộ phận CNTT là một BC . Nó có trách nhiệm xử lý mọi thứ liên quan đến CNTT trong công ty. &lt;br&gt;
Nhân, một kế toán tại cùng công ty. Nhân làm việc trong phòng Kế toán. Bộ phận kế toán xử lý mọi thứ liên quan đến kế toán, bao gồm cả bảng lương.&lt;br&gt;
Cả hai đều có trách nhiệm rất chính xác và ranh giới của họ là khá rõ ràng.&lt;/p&gt;

&lt;p&gt;Về thực tế 2 người họ ở các văn phòng khác nhau. Họ có tổ chức nội bộ của riêng họ, quy tắc nội bộ của riêng họ, nhân viên, v.v.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Phong không vào văn phòng của Nhân để sửa đổi bảng lương tăng lên x2, thưởng x4.&lt;/li&gt;
&lt;li&gt;Nhân không đến chỗ làm việc của Phong để sửa đổi code của Phong cho sai logic. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;2 người họ có thể làm những điều trên nhưng đó sẽ gây ảnh hưởng và dẫn đến hậu quả nghiêm trọng. Nếu Nhân tìm thấy một lỗi trong phần mềm kế toán (được phát triển nội bộ), Nhân nên gọi cho bộ phận CNTT để xử lý nó. Phong muốn tăng lương nên thương lượng lại lương với giám đốc công ty.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Nhân không thể cài đặt PhpStorm và bắt đầu code Laravel (là một framework PHP hiện đại, design pattern xịn, code rất là đẹp). Đó không phải là trách nhiệm của Nhân và Nhân không biết làm thế nào để làm điều đó, ngay cả khi Nhân biết rằng PhpStorm (IDE rất tốt cho PHP  developer) là chương trình được Phong hay sử dụng để viết code. Trên thực tế, PhpStorm sẽ là một phần mềm rất lạ trên máy tính của kế toán viên. Tương tự thì các tập tin về bảng lương, biên chế hoặc hóa đơn cũng không có trong bộ phận CNTT.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nhưng tất nhiên, khi Phong gặp vấn đề liên quan đến bảng lương, Phong có thể yêu cầu Nhân xem xét nó. Cả hai đều tôn trọng ranh giới của nhau và hành động theo trách nhiệm của họ. Nhưng bộ phận CNTT tự tổ chức thành 2 nhóm: nhóm phát triển phần mềm và nhóm quản trị.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nhóm đầu tiên thực hiện các tính năng và sửa lỗi (Developer: Đa số là sinh viên vừa ra trường, làm được vài dự án khủng khi bảo vệ luận văn, đa số không biết design principle, SOLID, DRY, KISS  là gì, phận mãi làm cuder, lương đủ mua mì gói sống qua ngày ). &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nhóm thứ hai xử lý các máy chủ data(DBA : Database Administrator, mấy ông này làm việc ít,  đa số thời gian là thảnh thơi trong công ty nhưng lương tháng lại cao ngất ngưỡng). &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Mỗi nhóm là một Bounded Context. Họ có trách nhiệm riêng và ranh giới rõ ràng. DBA không viết code Laravel PHP và Phong không  tự ý cài đặt lại cấu hình máy chủ. Mọi người hành động theo trách nhiệm của họ và trong ranh giới của họ.&lt;/p&gt;

&lt;p&gt;Vì vậy, bộ phận CNTT là một BC. Phong là một phần của mô hình của nó. Trong thực tế thì mọi thứ có ý nghĩa như (developer, máy chủ, v.v.) là một phần của BC và nó phải nhất quán bên trong nó (developer nên viết phần mềm và không được đòi hỏi về quản lý hóa đơn).&lt;/p&gt;

&lt;p&gt;Điều tương tự là Nhân không có vị trí trong bộ phận CNTT và Nhân không nên xử lý bất cứ điều gì liên quan đến bộ phận CNTT. Nhân là một phần của Kế toán BC. Nhân có thể đến bộ phận CNTT chơi nhưng sau đó Nhân chỉ là một người bạn đi ngang qua, Nhân không có ý nghĩa gì với bộ phận CNTT và không ai mong Nhân sẽ ở lại viết code Laravel PHP hay fix bugs hộ hoặc đóng vai trò là developer.&lt;/p&gt;

&lt;p&gt;Phong có thể phải lòng Nhân và dành một chút thời gian trong văn phòng của Nhân, nhưng điều đó không khiến Phong trở thành một kế toán viên.&lt;/p&gt;

&lt;p&gt;Có  khá nhiều những BC độc lập và chúng không trùng nhau. Hơn nữa, nếu một đối tượng từ một BC (X) chuyển sang BC (Y) khác, điều đó không có nghĩa là bây giờ nó là một phần của sau này, nó được xem giống như một đối tượng đơn giản không có ý nghĩa đối với Y.&lt;/p&gt;

&lt;p&gt;2 người làm việc gần như độc lập nhưng làm thế nào họ có thể làm việc cùng nhau không? Nghĩa là bộ phận CNTT và Kế toán phải làm việc cùng nhau theo thời gian. Họ làm điều đó bằng cách nói chuyện với đúng người  (người thứ 3 :) ).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Khi Nhân cần một tính năng phần mềm mới, Nhân có thể nói với Phong, nhưng người quản lý của Phong (là Dự) cuối cùng sẽ quyết định xem những tính năng nào sẽ được thêm vào.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dự là người tiếp nhận cuộc nói chuyện khi Nhân muốn các tính năng mới hoặc thậm chí để sửa một số lỗi. Dự là người quản lý bộ phận CNTT và giao tasks cho Phong (hoặc bất kỳ ai khác trong bộ phận CNTT) sẽ phải làm gì tiếp theo.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nhân không thể bỏ qua Dự xem như người vô hình được vì đây là quy tắc trong bộ phận CNTT: Dự là người sẽ ra quyết định. Nhân phải trình bày ý tưởng của mình cho Dự  nghe, nếu không thì yêu cầu sẽ bị từ chối. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Nếu các yêu cầu không có ý nghĩa đối với bộ phận CNTT như bao cafe Phúc Long hay bánh mì 7-eleven, yêu cầu sẽ bị từ chối. Dự là Anti Corruption Layer của CNTT BC. Không yêu cầu gì có thể tự ý thông qua nếu chưa được sự đồng ý của Dự và những yêu cầu gì  nếu đã thông qua, nó sẽ được chấp nhận để phát triển thêm cho phù hợp với tổ chức nội bộ của bộ phận CNTT.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>domaindrivendesign</category>
      <category>boundedcontext</category>
      <category>anticorruptionlayer</category>
    </item>
    <item>
      <title>Low Coupling &amp; High Cohesion là gì ? </title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Mon, 21 Oct 2019 12:42:59 +0000</pubDate>
      <link>https://dev.to/nasterblue/low-coupling-high-cohesion-la-gi-47nm</link>
      <guid>https://dev.to/nasterblue/low-coupling-high-cohesion-la-gi-47nm</guid>
      <description>&lt;ol&gt;
&lt;li&gt;Mục đích của giai đoạn thiết kế trong vòng đời phát triển phần mềm là tạo ra giải pháp cho một vấn đề được đưa ra trong tài liệu SRS(Software Requirement Specification). Đầu ra của giai đoạn thiết kế là SDD (Sofware Design Document).&lt;/li&gt;
&lt;li&gt;Về cơ bản, thiết kế là một quá trình lặp lại gồm hai phần:

&lt;ul&gt;
&lt;li&gt;Phần đầu tiên là thiết kế ý tưởng cho khách hàng biết hệ thống sẽ làm gì.&lt;/li&gt;
&lt;li&gt;Thứ hai là thiết kế kỹ thuật cho phép người xây dựng hệ thống hiểu được phần cứng và phần mềm thực tế cần thiết để giải quyết vấn đề của khách hàng.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Thiết kế khái niệm hệ thống:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Viết bằng ngôn ngữ đơn giản tức là ngôn ngữ khách hàng dễ hiểu.&lt;/li&gt;
&lt;li&gt;Giải thích chi tiết về đặc điểm hệ thống.&lt;/li&gt;
&lt;li&gt;Mô tả chức năng của hệ thống.&lt;/li&gt;
&lt;li&gt;Độc lập thực hiện.&lt;/li&gt;
&lt;li&gt;Liên kết với tài liệu yêu cầu.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Thiết kế kỹ thuật hệ thống:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Thành phần phần cứng và thiết kế.&lt;/li&gt;
&lt;li&gt;Chức năng và phân cấp của thành phần phần mềm.&lt;/li&gt;
&lt;li&gt;Kiến trúc phần mềm.&lt;/li&gt;
&lt;li&gt;Kiến trúc mạng.&lt;/li&gt;
&lt;li&gt;Cấu trúc dữ liệu và luồng dữ liệu.&lt;/li&gt;
&lt;li&gt;Thành phần I/O của hệ thống.&lt;/li&gt;
&lt;li&gt;Giao diện hiển thị.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Modularization
&lt;/h1&gt;

&lt;p&gt;Đề cập đến quá trình phân chia một hệ thống phần mềm thành nhiều module độc lập trong đó mỗi module hoạt động độc lập. Ví dụ : Những nhân viên làm việc về bảng lương, hóa đơn, hồ sơ giấy tờ nên được tách riêng ra thành một bộ phận trong công ty.  Tương tự đối với những nhân viên làm việc liên quan tới coding website, android/iOS app thì cũng nên tách ra thành một bộ phận riêng.&lt;br&gt;
Có nhiều lợi thế của Modularization trong công nghệ phần mềm. Một số trong số này được đưa ra dưới đây:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dễ hiểu hệ thống.&lt;/li&gt;
&lt;li&gt;Bảo trì hệ thống dễ dàng.&lt;/li&gt;
&lt;li&gt;Một module có thể được sử dụng nhiều lần theo yêu cầu của họ. Không cần phải viết đi viết lại.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Coupling
&lt;/h1&gt;

&lt;p&gt;Đề cập đến mức độ liên quan hoặc phụ thuộc của các class/module đối với nhau. Ví dụ : kế toán viên nên làm việc ở bộ phận kế toán.  Web developer nên làm việc ở bộ phận CNTT. 2 bộ phận nên tách rời nhau, không phải xung đột hay phụ thuộc nhau trong quá trình làm việc.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Đối với High Coupling sẽ gây khó khăn cho việc thay đổi và duy trì code của bạn, vì các class/module được liên kết chặt chẽ với nhau, nên việc thay đổi có thể yêu cầu viết lại toàn bộ hệ thống.&lt;/li&gt;
&lt;li&gt;Đối với Low Coupling, việc thay đổi thứ gì đó trong một class/module sẽ không ảnh hưởng đến class/module kia. (Dependency Inversion Principle : xem chữ D trong SOLID)&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Cohesion
&lt;/h1&gt;

&lt;p&gt;Đề cập đến những class/module có thể làm những chức năng nhiệm vụ gì. Ví dụ :  bộ phận kế toán nên làm việc liên quan tới bảng lương, hóa đơn, hồ sơ,... bộ phận kết toán không nên tự ý sửa đổi sourcode của bộ phận phát triển web. Tương tự bộ phận CNTT không nên tự ý sửa đổi tăng lương lên x2.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Low Cohesion là class/module thực hiện rất nhiều hành động - phạm vi hoạt động rộng và dàn trãi không rõ ràng và chuyên biệt, không tập trung vào những gì nó nên làm (God Object).&lt;/li&gt;
&lt;li&gt;High Cohesion là class/module tập trung vào những gì nó nên làm, tức là chỉ các phương thức liên quan đến ý định của Class (Single Repository Principle : xem chữ S trong SOLID).&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>coupling</category>
      <category>lowcoupling</category>
      <category>cohesion</category>
      <category>highcohesion</category>
    </item>
    <item>
      <title>SOLID là gì ? </title>
      <dc:creator>Naster Blue</dc:creator>
      <pubDate>Mon, 21 Oct 2019 12:42:50 +0000</pubDate>
      <link>https://dev.to/nasterblue/solid-la-gi-5gnl</link>
      <guid>https://dev.to/nasterblue/solid-la-gi-5gnl</guid>
      <description>&lt;p&gt;SOLID là 5 nguyên lý trong thiết kế phần mềm giúp code trở nên dễ hiểu, linh động và dễ bảo trì hơn. 5 nguyên lý trong SOLID bao gồm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;S: Single responsibility principle&lt;/li&gt;
&lt;li&gt;O: Open/closed principle&lt;/li&gt;
&lt;li&gt;L: Liskov substitution principle&lt;/li&gt;
&lt;li&gt;I: Interface segregation principle&lt;/li&gt;
&lt;li&gt;D: Dependency inversion principle&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  S — Single Responsibility Principle (SRP)
&lt;/h2&gt;

&lt;p&gt;A class should have only a single responsibility.&lt;br&gt;
Một class nên chỉ xử lý đơn nhiệm.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Accountant&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;codeJS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;=&amp;gt; correct it&lt;br&gt;
Nhiệm vụ code JS nên được giao cho developer JS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;JSDeveloper&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="nx"&gt;codeJS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Accountant chỉ nên làm việc liên quan tới kế toán như : về bảng lương, hóa đơn, hồ sơ giấy tờ.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;Accountant&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;prepareAccountsAndTaxReturns&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;administerPayrolls&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;controllingIncomeAndExpenditure&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  O — Open-Closed Principle
&lt;/h2&gt;

&lt;p&gt;Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.&lt;br&gt;
Nên mở rộng/kế thừa các class đã tồn tại thay vì sửa đổi chúng.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ReactJSDeveloper&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;JSDeveloper&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;codeReactJS&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Một JSDeveloper ngoài biết code JS thuần ra về lâu dài còn có khả năng học và code React JS với tư duy reactive. &lt;/p&gt;

&lt;h2&gt;
  
  
  L — Liskov Substitution Principle
&lt;/h2&gt;

&lt;p&gt;Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.&lt;br&gt;
Các đối tượng của class cha có thể được thay thế bởi các đối tượng của các class con mà không làm thay đổi tính đúng đắn của chương trình.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;ReactJSDeveloper&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;JSDeveloper&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;codeJS&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;//  override code logic&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;ReactJS Developer ngoài biết code ReactJs mà còn phải biết code JS thuần.&lt;/p&gt;

&lt;h2&gt;
  
  
  I — Interface Segregation Principle
&lt;/h2&gt;

&lt;p&gt;Many client-specific interfaces are better than one general-purpose interface.&lt;br&gt;
Nên tách thành nhiều interface nhỏ cho các mục đích riêng, không nên để 1 interface phình quá to cho nhiều mục đích.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IAccountant&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;prepareAccountsAndTaxReturns&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;administerPayrolls&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;controllingIncomeAndExpenditure&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IJSDeveloper&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nx"&gt;codeJS&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IReactJsDeveloper&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;IJSDeveloper&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;codeReactJS&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  D — Dependency Inversion Principle
&lt;/h2&gt;

&lt;p&gt;Depend on abstractions, not on concretions.&lt;br&gt;
Các module cấp cao không nên phụ thuộc vào các module cấp thấp. Cả hai nên phụ thuộc vào abstraction.&lt;br&gt;
Abstraction không nên phụ thuộc vào detail. Detail nên phụ thuộc vào abstraction.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;VueJSDeveloper&lt;/span&gt;  &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;IJSDeveloper&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;codeJS&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// override improve JS performance&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;codeVueJS&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;WebProject&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kr"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;jsDeveloper&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IJSDeveloper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;jsDeveloper&lt;/span&gt; &lt;span class="nx"&gt;VueJSDeveloper&lt;/span&gt;&lt;span class="p"&gt;){}&lt;/span&gt;
    &lt;span class="nx"&gt;kickOff&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;jsDeveloper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;codeJS&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Khi lựa chọn developer cho Frontend  dự án thì có thể chọn VueJS Developer làm đầu vào.&lt;br&gt;
Dự án tiếp theo có thể  chọn ReactJS Developer làm frontend.&lt;/p&gt;

</description>
      <category>solid</category>
      <category>srp</category>
      <category>dependency</category>
      <category>interface</category>
    </item>
  </channel>
</rss>
