<?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: Hernan Reyes</title>
    <description>The latest articles on DEV Community by Hernan Reyes (@hernanreyes).</description>
    <link>https://dev.to/hernanreyes</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%2F580001%2F6cf385da-87e4-42ee-84d2-1b493c612d50.jpg</url>
      <title>DEV Community: Hernan Reyes</title>
      <link>https://dev.to/hernanreyes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hernanreyes"/>
    <language>en</language>
    <item>
      <title>Keeping track of database schema changes</title>
      <dc:creator>Hernan Reyes</dc:creator>
      <pubDate>Mon, 20 Jun 2022 15:04:18 +0000</pubDate>
      <link>https://dev.to/hernanreyes/keeping-track-of-database-schema-changes-2g62</link>
      <guid>https://dev.to/hernanreyes/keeping-track-of-database-schema-changes-2g62</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Have you ever wonder how do developers handle changes in the database schema of a project?, what do they do when a new table/column/index is added, or when a table is dropped, a column, an index and that. How they ensure that everyone involved in the project have all the changes applied to their database?. Well, for this, they keep track of a history of every change made to the database schema.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwardo129k2elort0ms6b.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwardo129k2elort0ms6b.png" alt="SQL migrations and git agreement"&gt;&lt;/a&gt;&lt;br&gt;
 This was something I didn't know until I first work with other people and I read the README of the project and said that I have to run the “migrations” to have my database schema up-to-date. That made me ask my self: how it didn’t cross my mind handling something that obvious before?, well, was because I never change off computer or reformatted my pc, so it made me reinstall the hole project from zero to realize that I haven’t a way to restore my database without a backup.&lt;/p&gt;

&lt;p&gt;My goal in this article is to show you how this database migrations works, so you know what to do when new changes are applied to the database, whether you’re working solo or with other people.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it works?
&lt;/h2&gt;

&lt;p&gt;The way it works is simple, you have to do the same you do when you keep a history of the project’s code, so we’ll need a version control system like &lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;GIT&lt;/a&gt;, then we can ensure that everyone involved in the project can have the database’s changes history up-to-date. Here I’ll show you two ways to handle the database migrations, but first let's see what they have in common:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;You’ll write files that contain the SQL with a name format like: &lt;code&gt;{version}_{description}.{up/down}.{ext}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;the &lt;code&gt;description&lt;/code&gt; can be a short explanation of what the migration file does, ex:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;create_users_table&lt;/li&gt;
&lt;li&gt;adds_birthdate_column_to_users_table&lt;/li&gt;
&lt;li&gt;drops_country_column_from_users_table&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The SQL to apply changes to the schema (known as &lt;code&gt;up&lt;/code&gt; migration) and a SQL to reverse those changes (known as &lt;code&gt;down&lt;/code&gt; migration)&lt;/p&gt;

&lt;p&gt;That’s why in the previous point, the name format indicates whether is an &lt;code&gt;up&lt;/code&gt; or &lt;code&gt;down&lt;/code&gt; migration&lt;/p&gt;


ℹ️ Some libraries manage one file and with comments indicate the `up` SQL and `down` SQL

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A way to run the migrations in order&lt;/p&gt;

&lt;p&gt;For this, we make use of the &lt;code&gt;version&lt;/code&gt; of the filename format, you can put a sequence number or the timestamp of when you created the file, so when we run the migrations we execute them in ascending order. This is needed because you may add migrations that depend on other migrations to be executed first.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Ensure we don’t run a migration twice&lt;/p&gt;

&lt;p&gt;Libraries may create a table to keep a log of the executed migrations, so they don’t do it twice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The extension of the file depends on the method you choose to handle the migrations&lt;/p&gt;

&lt;p&gt;It can be a &lt;code&gt;.sql&lt;/code&gt; file or the extension of your programming language&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that we know what they have in common, let's see each method in action.&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Pure&lt;/strong&gt; &lt;strong&gt;SQL’s migrations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here you’ll have to create a directory to store the &lt;code&gt;.sql&lt;/code&gt; files, which will contain the changes made to the database schema and a way to reverse them. Following the format described in the previous section, you’ll have files like these:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4a1zcq6t875qfispvwm0.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4a1zcq6t875qfispvwm0.png" alt="SQL migrations directory"&gt;&lt;/a&gt;&lt;br&gt;
Then in your migration files, just write the changes you want to make, for example the &lt;code&gt;000001_create_users_table.up.sql&lt;/code&gt; migration in the above image would have something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-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;TABLE&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;id&lt;/span&gt;         &lt;span class="nb"&gt;SERIAL&lt;/span&gt;       &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;last_name&lt;/span&gt;  &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;email&lt;/span&gt;      &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;password&lt;/span&gt;   &lt;span class="nb"&gt;VARCHAR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;256&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and for the migration &lt;code&gt;000001_create_users_table.down.sql&lt;/code&gt;, the needed SQL to reverse the changes made by the &lt;code&gt;up&lt;/code&gt; migration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DROP&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;IF&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;ℹ️ Some libraries can read the SQL files from sources like github, gitlab, aws s3, etc&lt;/p&gt;

&lt;p&gt;For this method, you can use the next libraries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/golang-migrate/migrate" rel="noopener noreferrer"&gt;https://github.com/golang-migrate/migrate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/pressly/goose" rel="noopener noreferrer"&gt;https://github.com/pressly/goose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.prisma.io/migrate" rel="noopener noreferrer"&gt;https://www.prisma.io/migrate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/yoyo-migrations/" rel="noopener noreferrer"&gt;https://pypi.org/project/yoyo-migrations/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/alexyslozada/migrations" rel="noopener noreferrer"&gt;https://github.com/alexyslozada/migrations&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Migrations with your programming language&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Here applied the same conventions as in the Pure SQL’s migrations, but instead of having &lt;code&gt;.sql&lt;/code&gt; migrations, you’ll have migrations with the extension of your programming language, in my case, I’ll be using Golang, so the previous structure of files I showed you earlier will look like this with a timestamp versioning instead of a sequence:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94hsibszzue6u4osa8m4.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F94hsibszzue6u4osa8m4.png" alt="Go SQL migrations directory"&gt;&lt;/a&gt;&lt;br&gt;
As you can see, unlike the previous method, here we only have 3 files, why is that?, it is because of the library I’m using, we indicate the &lt;code&gt;up&lt;/code&gt; and &lt;code&gt;down&lt;/code&gt; migration in the same file, here is the content for the users table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;goose&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddMigration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upCreateUsersTable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;downCreateUsersTable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;upCreateUsersTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;`
        CREATE TABLE users
        (
            id         SERIAL       NOT NULL,
            first_name VARCHAR(100) NOT NULL,
            last_name  VARCHAR(100),
            email      VARCHAR(100) NOT NULL,
            password   VARCHAR(256) NOT NULL
        );`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;downCreateUsersTable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tx&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Tx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;tx&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DROP TABLE IF EXISTS users;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here you have an &lt;code&gt;up&lt;/code&gt; and &lt;code&gt;down&lt;/code&gt; function which are passed to &lt;code&gt;goose.AddMigration()&lt;/code&gt;, this will obviously be different depending on your programming language and library you’re using.&lt;br&gt;
For this method, you can use the next libraries:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/pressly/goose" rel="noopener noreferrer"&gt;https://github.com/pressly/goose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://laravel.com/docs/9.x/migrations" rel="noopener noreferrer"&gt;https://laravel.com/docs/9.x/migrations&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/yoyo-migrations/" rel="noopener noreferrer"&gt;https://pypi.org/project/yoyo-migrations/&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  What if I’m mid-project and don’t have migrations?
&lt;/h3&gt;

&lt;p&gt;For this, you can create a backup of the database schema, so you can add it as an initial migration, but you have to make sure that the library you use does not execute it in your local database (because you already have those changes), so you have to dig into the library to see how they keep track of the migrations that have been already run, the ones I know creates a table in your database, so you can start there.&lt;/p&gt;

&lt;p&gt;Then you can start keeping track of the database changes. You want a new table?, add a migration, you want to drop a column?, add a migration, you want an index, add a migration, remember, every change to your database schema must have a migration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Here I gave you an overview of database migrations, with two common approaches on how to handle them. Personally, I like to use the first method because I just have to worry on writing the SQL and not writing code to execute the migration with my programming language, I’ve been using this method for over 3 years now and never had the need to use the second one.&lt;/p&gt;

&lt;p&gt;Hope you've learned something new today and start using these migrations if you’re not already, so when you join a project you are prepared to use them or teach to other developers how they work if they don’t know, as I didn’t 3 years ago.&lt;/p&gt;

&lt;p&gt;If you want to know how to create and run the file migrations automatically refer to the libraries I mentioned, there they explain how to use them.&lt;/p&gt;

&lt;p&gt;Thank you for reading and see you in the next article &lt;code&gt;👋&lt;/code&gt;&lt;/p&gt;

</description>
      <category>sql</category>
      <category>git</category>
      <category>go</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How the N+1 query problem can burn your database</title>
      <dc:creator>Hernan Reyes</dc:creator>
      <pubDate>Wed, 15 Jun 2022 11:38:34 +0000</pubDate>
      <link>https://dev.to/hernanreyes/how-the-n1-query-can-burn-your-database-an2</link>
      <guid>https://dev.to/hernanreyes/how-the-n1-query-can-burn-your-database-an2</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Have you ever watched a movie/series or experience your self going to a hotel where they have room service?, let's put that you go to one of these hotels, where the hotel’s restaurant is at the first floor, and you’re hosteling at the 10th floor. Now, when you are there, you decide to order something to eat for lunch, and imaging that the waitress instead of bringing you all the food with the compliments (drinks, desserts, etc.) at once, bring you every meal, drink, dessert and that, one by one, that will be so inefficient, because the waitress will have to do many runs before bringing you everything you asked for, going back and forth from floor 1 to 10. This is what the N+1 problem is, getting everything you request in many runs.&lt;/p&gt;

&lt;p&gt;The ideal will be to carry what you ordered in a bussing cart like this, so the waitress can bring all at once:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2DzPjZqR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ooogqb5ftjzgntey5z0v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2DzPjZqR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ooogqb5ftjzgntey5z0v.png" alt="Bussing cart" width="600" height="400"&gt;&lt;/a&gt;&lt;br&gt;
In this article will see how this problem look in code and some solutions you can do to avoid this and ensure the best performance for your application.&lt;/p&gt;
&lt;h2&gt;
  
  
  Time to see some code
&lt;/h2&gt;

&lt;p&gt;To show how the N+1 looks in your code, I’m going to build a simple console application that prints the available menus to order from a restaurant. For this, we’re going to have a database with a &lt;code&gt;meals&lt;/code&gt; and &lt;code&gt;drinks&lt;/code&gt; table, in the menu, each meal will come with a drink. Let's see the models for these tables:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y9rEAhYz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sue1w451bh7n3ftwf95f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y9rEAhYz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sue1w451bh7n3ftwf95f.png" alt="Tables" width="880" height="267"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;
&lt;span class="c"&gt;// Meal model a record of meals table&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Meal&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;          &lt;span class="kt"&gt;uint&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;DrinkID&lt;/span&gt;     &lt;span class="kt"&gt;uint&lt;/span&gt;
    &lt;span class="n"&gt;Drink&lt;/span&gt;       &lt;span class="n"&gt;Drink&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Meals&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Meal&lt;/span&gt;

&lt;span class="c"&gt;// Drink model a record of drinks table&lt;/span&gt;
&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Drink&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ID&lt;/span&gt;          &lt;span class="kt"&gt;uint&lt;/span&gt;
    &lt;span class="n"&gt;Name&lt;/span&gt;        &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="n"&gt;Description&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Drinks&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="n"&gt;Drink&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's see the N+1 in action, here we have some methods to query data from the database (you can find the full code on my repo)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Waitress&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// getMeals gets 20 meals from the db&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;Waitress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;getMeals&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// this method has the logic to query from the db, if you want to see&lt;/span&gt;
    &lt;span class="c"&gt;// the actual code, you can go the repo&lt;/span&gt;

    &lt;span class="c"&gt;// SQL used in this method&lt;/span&gt;
    &lt;span class="c"&gt;// `SELECT id, name, description, drink_id FROM meals LIMIT 20`&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// getDrinkByID gets a drink from the db by an id&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;Waitress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;getDrinkByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Drink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// this method has the logic to query from the db, if you want to see&lt;/span&gt;
    &lt;span class="c"&gt;// the actual code, you can go the repo&lt;/span&gt;

    &lt;span class="c"&gt;// SQL used in this method&lt;/span&gt;
  &lt;span class="c"&gt;// `SELECT id, name, description FROM drinks WHERE id = $1`&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Drink&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally the method with the N+1 query problem&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="n"&gt;Waitress&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ListMenu&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// the `1` of our `N+1`&lt;/span&gt;
    &lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getMeals&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// here is our waitress going back and forth &lt;/span&gt;
    &lt;span class="c"&gt;// from floor 1 to 10, this will be the `N` of our `N+1`&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;meal&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;meals&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;drink&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDrinkByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DrinkID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Drink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;drink&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Yes, this simple logic can burn your database, because you are going back and forth to add the drinks to each meal, which is not efficient. &lt;/p&gt;

&lt;p&gt;The more records you have to query or the most users you have, the most this N+1 problem we’ll affect your application because the time complexity is &lt;a href="https://learn2torials.com/a/linear-time-complexity"&gt;O(N)/Linear time&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;ℹ️ Here I gave you an example in the backend, but this problem can also be found in your frontend, where instead of calling your database directly, you’ll be calling an endpoint of your backend which at the same time would call the database.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solution
&lt;/h2&gt;

&lt;p&gt;Now let's see two solutions to our problem.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Join the authors in the SQL query&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This maybe the easier solution, in here you’ll just have to write a query like the following:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;meals&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;
    &lt;span class="k"&gt;INNER&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;drinks&lt;/span&gt; &lt;span class="k"&gt;AS&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;d&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;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drink_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;With this query, our code will look the following&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;type&lt;/span&gt; &lt;span class="n"&gt;Solution1&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;db&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DB&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;Solution1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ListMenu&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// this method will execute the previous SQL&lt;/span&gt;
    &lt;span class="c"&gt;// SELECT&lt;/span&gt;
    &lt;span class="c"&gt;// m.id,&lt;/span&gt;
    &lt;span class="c"&gt;//  m.name,&lt;/span&gt;
    &lt;span class="c"&gt;//  m.description,&lt;/span&gt;
    &lt;span class="c"&gt;//  d.name,&lt;/span&gt;
    &lt;span class="c"&gt;//  d.description&lt;/span&gt;
    &lt;span class="c"&gt;// FROM meals AS m&lt;/span&gt;
    &lt;span class="c"&gt;// INNER JOIN drinks AS d ON d.id = m.drink_id&lt;/span&gt;

    &lt;span class="c"&gt;// if you want to see the full code, refer to my repo&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;With this query, now we only have you query our database once and that’s it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Get the meals and then join the drinks with your programming language&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No, we won’t do the same as the example where we saw the N+1 problem, here, instead of querying the meals and then querying the drinks one by one, we’ll just do two queries to our database, let see how:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;Solution2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;ListMenu&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getMeals&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c"&gt;// this is our waitress bringing everything in a bussing cart &lt;/span&gt;
    &lt;span class="n"&gt;drinks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getDrinksByIDsIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetUniqueDrinkIDs&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;JoinDrinks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drinks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;Solution2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;getMeals&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Meals&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// this method has the logic to query from the db, if you want to see&lt;/span&gt;
    &lt;span class="c"&gt;// what's in these methods, you can go the repo&lt;/span&gt;

    &lt;span class="c"&gt;// sql used in this method&lt;/span&gt;
    &lt;span class="c"&gt;// `SELECT id, name, description, drink_id FROM meals LIMIT 20`&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Meals&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="n"&gt;Solution2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;getDrinksByIDsIn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Drinks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// this method has the logic to query from the db, if you want to see&lt;/span&gt;
    &lt;span class="c"&gt;// what's in these methods, you can go the repo&lt;/span&gt;

    &lt;span class="c"&gt;// sql used in this method&lt;/span&gt;
    &lt;span class="c"&gt;// `SELECT id, name, description FROM drinks WHERE id IN (1, 2, 3)`&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Drinks&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;As you can see, we only have two queries to our database: &lt;code&gt;s.getMeals()&lt;/code&gt; and &lt;code&gt;s.getDrinksByIDsIn&lt;/code&gt;, and if you read the &lt;code&gt;ListMenu&lt;/code&gt; method, you’ve noticed that we introduced to more methods, let see what they do and why we need them:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="c"&gt;// to query the drinks, we need to know their IDs, for that&lt;/span&gt;
&lt;span class="c"&gt;// we add this method to our `Meals` slice&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;Meals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetUniqueDrinkIDs&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ids&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt;
    &lt;span class="n"&gt;drinks&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;drinks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DrinkID&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;continue&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;drinks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DrinkID&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;struct&lt;/span&gt;&lt;span class="p"&gt;{}{}&lt;/span&gt;
        &lt;span class="n"&gt;ids&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ids&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DrinkID&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="n"&gt;ids&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;// once we've query our meals and drinks, we proceed to join the &lt;/span&gt;
&lt;span class="c"&gt;// corresponding drink to our meals&lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;Meals&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;JoinDrinks&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;drink&lt;/span&gt; &lt;span class="n"&gt;Drinks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;meal&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Drink&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;drink&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;meal&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DrinkID&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="c"&gt;// this methos is needed by the `JoinDrinks()` method&lt;/span&gt;
&lt;span class="c"&gt;// so it can find the drink for a meal &lt;/span&gt;
&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="n"&gt;Drinks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;GetByID&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;Drink&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;drink&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="k"&gt;range&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;drink&lt;/span&gt;&lt;span class="o"&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;ID&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;drink&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="n"&gt;Drink&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;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, you can see we don't query the database for every drink, instead, in one query we get all the meals, and in the other we query the drinks and then join them to the corresponding meals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;When to use one solution or the other?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, in this app, every meal includes just one drink, but what happened if a meal includes more than one drink?, in that scenario, the first solution can't help us, because the SQL query is going to repeat the record for every drink in a meal, so what we want to do, is use the second solution, when we first query the meals, and then get the drinks to join them to the corresponding meals&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Personal experience&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;At work, we have a microservice that is in charge to cache a lot of data about the products we have, twice a day or at demand, and it used to take about 1 minute to cache all the data because of this problem, after we remove the N+1s, it went from 1 minute to 2 seconds!.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Don’t overestimate a simple logic like the N+1’s, you can fall into this problem easily, but also you can fix it easily, but if you don’t do it in time, your application performance will let you know overtime. &lt;/p&gt;

&lt;p&gt;Something I didn’t mention is, the N+1 in ORMs like &lt;a href="https://gorm.io/"&gt;Gorm&lt;/a&gt; because I don’t have experience with these, but I will recommend if you are using ORMs, that you dig into the underlying code to see if you have this problem.&lt;/p&gt;

&lt;p&gt;⚠️ The way I structure the code in this article is not meant to be a guide on how you should structure your code, it is made as simple as possible to focus on the problem and solution code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Homework&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you are working on a project, or you already have projects in production, go check them out to get rid of any N+1 you find.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://laravel-news.com/laravel-n1-query-problems"&gt;N+1 in Laravel&lt;/a&gt;: &lt;strong&gt;Here you can see the N+1 in Eloquent (an ORM for Laravel)&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.figma.com/figjam/"&gt;Figma Jam&lt;/a&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;a href="https://iconduck.com/"&gt;IconDuck&lt;/a&gt;&lt;/strong&gt;: &lt;strong&gt;To make the illustrations&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/hernanhrm/blog-examples/tree/main/n-plus-1"&gt;Article repository&lt;/a&gt;&lt;/strong&gt;: &lt;strong&gt;You can find the examples in my GitHub&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>beginners</category>
      <category>go</category>
      <category>performance</category>
      <category>database</category>
    </item>
    <item>
      <title>How the Strategy Pattern works?</title>
      <dc:creator>Hernan Reyes</dc:creator>
      <pubDate>Thu, 09 Jun 2022 01:05:01 +0000</pubDate>
      <link>https://dev.to/hernanreyes/how-the-strategy-pattern-works-26k3</link>
      <guid>https://dev.to/hernanreyes/how-the-strategy-pattern-works-26k3</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Have you ever entered to an e-commerce and buy a product?, If you have, then you may have been show different ways to pay (PayPal, Credit Card, etc.)&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vp6dh0hyi9xpvhs0jkk.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2vp6dh0hyi9xpvhs0jkk.png" alt="Strategy pattern description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This purchase process is a way to see the Strategy Pattern. &lt;strong&gt;Strategy&lt;/strong&gt; is a Behavioral design pattern that lets you define different strategies and switch between them to reach a goal. In the above image, you have a goal (buy a product) and different strategies to accomplish it (pay with PayPal, Credit Card, etc.).&lt;/p&gt;

&lt;p&gt;Let’s see how we would implement this purchase process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Structure of Strategy Pattern
&lt;/h3&gt;

&lt;p&gt;First, let's understand the structure of the pattern. It is defined by 3 parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Context Class&lt;/p&gt;

&lt;p&gt;This is our goal&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Contract Interface&lt;/p&gt;

&lt;p&gt;These are the rules to be followed by the Strategies&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Strategy Classes&lt;/p&gt;

&lt;p&gt;Refers to the different strategies to reach my goal, are the implementation of the &lt;code&gt;Contract Interface&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is a Class Diagram for the &lt;strong&gt;Strategy&lt;/strong&gt; structure&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4mtsa2u18oquk39fho2.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg4mtsa2u18oquk39fho2.png" alt="Strategy Pattern Class Diagram description"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Will also need a Client who trigger the purchase process. Will see this in the code examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code time, yay!
&lt;/h2&gt;

&lt;p&gt;Now, let’s take the Class Diagram into code to see how it is done. I’ll be using &lt;a href="https://go.dev/" rel="noopener noreferrer"&gt;Golang&lt;/a&gt; because it is the language I’m comfortable with:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Define the Contract Interface&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fulk19bseyp6ajhygdzub.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fulk19bseyp6ajhygdzub.png" alt="Contract definiton"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define the Context&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvuxeho8odcamfaiu6bm.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuvuxeho8odcamfaiu6bm.png" alt="Purchase context implenmentation"&gt;&lt;/a&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Implement the Strategies&lt;br&gt;
For this, will have 3 different classes (PayPal, CreditCard and Bank)&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ob8n5yuctxszvirgzl0.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8ob8n5yuctxszvirgzl0.png" alt="PayPal strategy implementation"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fluj607lu9b7iogc7997m.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fluj607lu9b7iogc7997m.png" alt="CreditCard strategy implementation"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg70pacmsn43hz232xpz0.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg70pacmsn43hz232xpz0.png" alt="Bank strategy implementation"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Client&lt;/p&gt;

&lt;p&gt;In this example, I’ll be using the console to execute the purchase process.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3mgc2d6a9u7swdpobqr.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi3mgc2d6a9u7swdpobqr.png" alt="Client"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we run our program, this is what happen:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9c2y8iklsd5fe57rnzk.gif" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9c2y8iklsd5fe57rnzk.gif" alt="Strategy terminal example"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note:&lt;/strong&gt; This pattern is a way to implement the Open/Closed Principle of SOLID.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if we want to add another payment method?
&lt;/h3&gt;

&lt;p&gt;This would be easy, you just have to create another class that implements the &lt;code&gt;PaymentMethodStrategy&lt;/code&gt; interface:&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffi2soxhvbw1z7d9cmd6z.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffi2soxhvbw1z7d9cmd6z.png" alt="Bitcoin strategy implementation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;and after that, you just have to register it in your context class&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkzpttiz3xrboek0m55m.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmkzpttiz3xrboek0m55m.png" alt="Bitcoin registry"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  The conventional way
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;How would it be to implement this process without the Strategy pattern?&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Well, instead of having 3 classes (Context, Contract and Strategies), we’ll only have 1 class that implements all the logic to pay with PayPal, CreditCard, Bank, etc.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;This will be our Purchase Class that implements all the logic
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmtazlf8z22868ho7ljz.png" alt="Classic implementation"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5agllzmyp476wifcxm05.png" alt="Classic implementation"&gt;
&lt;/li&gt;
&lt;li&gt;Our client
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsi5uqbqgsdtyxv0rgx1y.png" alt="Classic implementation client"&gt; &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When we run our program, this is what happen:&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpmb7kuulek8o4x1x0dm4.gif" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpmb7kuulek8o4x1x0dm4.gif" alt="Classic example"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;This could be fine when you first build your app, or when you know that you’ll rarely will add or modify existent logic. But if you know that the business logic will grow, things like this may happen in the future:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It will be difficult to navigate throughout the code &lt;/li&gt;
&lt;li&gt;Highly chance you modify something you’re not supposed to&lt;/li&gt;
&lt;li&gt;Git conflicts when different people working on the same class&lt;/li&gt;
&lt;li&gt;A lot of conditionals to switch between the different payment methods&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From the business perspective it may be ok because it works, but from the technical perspective is not because it will not be maintainable in the future.&lt;/p&gt;

&lt;p&gt;ℹ️ &lt;strong&gt;Note:&lt;/strong&gt; Putting all the logic in one class, for this example, will go against the Single Responsibility Principle of SOLID.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practice
&lt;/h2&gt;

&lt;p&gt;Here I showed what the Strategy Pattern is, how it is structured, and when you should use this pattern instead of putting all the logic in one class.&lt;/p&gt;

&lt;p&gt;I invite you to implement this pattern to apply a discount to an order and share the code in the comments. Hope this blog helped you understand the Strategy pattern. See you in the next Design Pattern article of this series.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://refactoring.guru/design-patterns/book" rel="noopener noreferrer"&gt;Dive into Design Patterns&lt;/a&gt;: &lt;strong&gt;This article is made by the notes I took from this book&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/phw/peek" rel="noopener noreferrer"&gt;Peek&lt;/a&gt;: &lt;strong&gt;Tool to record my terminal&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.figma.com/figjam/" rel="noopener noreferrer"&gt;Figma Jam&lt;/a&gt; and &lt;a href="https://iconduck.com/" rel="noopener noreferrer"&gt;IconDuck&lt;/a&gt;: &lt;strong&gt;To make the illustrations&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://ray.so/" rel="noopener noreferrer"&gt;Ray.so&lt;/a&gt;: &lt;strong&gt;For the code images&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://github.com/hernanhrm/strategy-pattern" rel="noopener noreferrer"&gt;Article repository&lt;/a&gt;: &lt;strong&gt;You can find the examples in my GitHub&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>designpatterns</category>
      <category>go</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Hello, World!</title>
      <dc:creator>Hernan Reyes</dc:creator>
      <pubDate>Sat, 28 May 2022 12:07:09 +0000</pubDate>
      <link>https://dev.to/hernanreyes/hello-world-569d</link>
      <guid>https://dev.to/hernanreyes/hello-world-569d</guid>
      <description>&lt;p&gt;Hello everybody, welcome to my Behind The Scenes.&lt;/p&gt;

&lt;p&gt;Here, I'll be posting the new things I learn while working or just studying from a Backend Developer perspective, this is the first time for me writing on a platform like this, so I'm excited to join this world as a writer and share my knowledge with the community.&lt;/p&gt;

&lt;p&gt;See you soon!&lt;/p&gt;

</description>
      <category>beginners</category>
    </item>
  </channel>
</rss>
