<?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: Jakub Stibůrek</title>
    <description>The latest articles on DEV Community by Jakub Stibůrek (@alco).</description>
    <link>https://dev.to/alco</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%2F629355%2F30ce4fe2-4c67-43cf-ac9c-510d573d7deb.jpeg</url>
      <title>DEV Community: Jakub Stibůrek</title>
      <link>https://dev.to/alco</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/alco"/>
    <language>en</language>
    <item>
      <title>Neon + Postgres.js: The Perfect Combo for Your MVP Project</title>
      <dc:creator>Jakub Stibůrek</dc:creator>
      <pubDate>Wed, 02 Aug 2023 13:56:30 +0000</pubDate>
      <link>https://dev.to/alco/neon-postgresjs-the-perfect-combo-for-your-mvp-project-56hd</link>
      <guid>https://dev.to/alco/neon-postgresjs-the-perfect-combo-for-your-mvp-project-56hd</guid>
      <description>&lt;p&gt;I was choosing the tech stack for a small MVP project. I went with a familiar backend framework &lt;a href="https://nestjs.com/"&gt;Nest.js&lt;/a&gt;. But I wanted to do something new regarding the DB. &lt;/p&gt;

&lt;p&gt;In this particular project I had to develop a feature that would let users import a bunch of CSV files and then generate a huge table out of the data. I knew that the generation itself can be done in a single SQL query (although it was gonna be a fat one). &lt;/p&gt;

&lt;p&gt;So instead of choosing a serverless document DB I wanted a standard relational DB and specifically Postgres. But I didn't want the hustle of hosting and managing it. Then I discovered &lt;a href="//https:\neon.tech"&gt;Neon&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Neon, a serverless Postgres
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The fully managed multi-cloud Postgres with a generous free tier. We separated storage and compute to offer autoscaling, branching, and bottomless storage.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;neon.tech&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Serverless connotes effortless deploy, scaling and availability. Serverless functions are quite well known concept now. You probably know the Firebase implementation or AWS lambda functions. Basically it's a piece of code that you don't have to host, monitor, manage... etc. yourself. You write it, ship it and it just works. If it doesn't get traffic, it automatically scales down or completely turns itself off. On the other hand on the occasion of a sudden surge of requests the functions gets more resources allocated automatically and your business continues to make you rich.&lt;/p&gt;

&lt;p&gt;Ok so imagine having a database that scales automatically and turns itself off when you don't use it. That's Neon. And if you need to add a few extra billions of rows, no problem the storage scales too.&lt;/p&gt;

&lt;h3&gt;
  
  
  Branching, a killer feature
&lt;/h3&gt;

&lt;p&gt;Consider how you develop and test changes to the DB, be it the scheme or data migration. You might have a staging environment with some fixtures simulating production DB. You try your change first there then you clench your ass and do the same thing on production. Neon got better solution for that.&lt;/p&gt;

&lt;p&gt;At any point of time you can duplicate, branch off, your database. So your new workflow might look like this: create a new branch out of prod. branch (main), run your migrations, test or somehow check that everything went ok, then run the migration on main. Since you've tested your migration on a disposable exact copy of the production DB you can be sure that your change didn't wipe all your business data or whatever hellish scenario you can come up with.&lt;/p&gt;

&lt;p&gt;It's similar to how GIT works. So any developer can create their branches and delete them any time. Also it's fast and easy to do so. And now there is a CLI for Neon which makes the workflow easier and can facilitate automation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;There must be more use cases for this feature but I'm not a DB specialist so you tell me (in the comment section).&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Still a technical preview but...
&lt;/h3&gt;

&lt;p&gt;Yeah, Neon is still officially in technical preview stage. But the Neon developers basically keep it this way due to their perfectionism. They have a feature list they want to create and until those are done, they won't officially kick the product off. But the main things are done and they work well. Meaning the database itself, scaling and branching.&lt;/p&gt;

&lt;p&gt;I've encountered problems with the SQL editor on the Neon dashboard. (The web dashboard overall has this &lt;em&gt;beta&lt;/em&gt; feeling to it.) The editor throws syntax errors on me but when I run my scripts in a DB admin on my machine, it works. And as of now there is no feature that would let you gather logs in some useful way, which can be a bummer for many users.&lt;/p&gt;

&lt;h2&gt;
  
  
  Postgres.js, I choose you (and not an ORM)
&lt;/h2&gt;

&lt;p&gt;Let's use the Neon DB in a Node and specifically Nest.js app.&lt;/p&gt;

&lt;p&gt;I don't like to work with ORMs. I'd rather separate the DB from my backend because I'm concerned with separation of different system layers. I consider it a bad practice when data mixes with logic of the system. Coupling them makes it way harder to change anything, more prone to bugs and from a certain size of the project impossible to change or certain decisions.&lt;/p&gt;

&lt;p&gt;On top of that I'd rather write SQL then use some kind of builder. I feel like this kind of abstraction is not very helpful. But rawdogging SQL as string is bound to introduce bugs to your code. So I think that library like &lt;a href="https://github.com/porsager/postgres"&gt;Postgres.js&lt;/a&gt; is a perfect solution. It makes use of JS template strings and checks that your queries make sense. Yes you can still make a typo in a field or table name but that can be solved easily by your IDE. For example I use WebStorm as a DB admin tool and when I have the the DB introspected I get code suggestions when writing SQL.&lt;/p&gt;

&lt;p&gt;There are some quirks you need to get used to when using this library and yes it's also a kind of abstraction especially when nesting SQL expressions but it resembles the SQL more then any builder while still keeping you safe.&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementation in a Nest.js app
&lt;/h3&gt;

&lt;p&gt;Let's get coding! When creating a DB and a branch in Neon you get connection details. Save these details to the &lt;code&gt;.env&lt;/code&gt; file and let's build a simple DB service which we can use throughout our application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Neon postgres connection  
PGHOST="..."  
PGDATABASE="..."  
PGUSER="..."  
PGPASSWORD="..."  
ENDPOINT_ID="..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ConfigService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;postgres&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postgres&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="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;DbService&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ConfigService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;  &lt;span class="c1"&gt;// 1&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;PG_HOST&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PGHOST&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// 2&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;PG_DATABASE&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PGDATABASE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;PG_USER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PGUSER&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;PG_PASSWORD&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PGPASSWORD&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;ENDPOINT_ID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ENDPOINT_ID&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`postgres://username:password@host/database?options=project%3D&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ENDPOINT_ID&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 3&lt;/span&gt;

    &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;sql&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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="p"&gt;{&lt;/span&gt;  &lt;span class="c1"&gt;// 4&lt;/span&gt;
    &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PG_USER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PG_PASSWORD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PG_HOST&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="na"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PG_DATABASE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  
    &lt;span class="na"&gt;ssl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;require&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;First we grab the Nest ConfigService which gives us access to the environmental variables&lt;/li&gt;
&lt;li&gt;We extract them. (Notice that validation is missing here, so if I forget to provide &lt;code&gt;.env&lt;/code&gt; file the app crashes, don't do that)&lt;/li&gt;
&lt;li&gt;Here we prepare the URL string&lt;/li&gt;
&lt;li&gt;The Postgres.js gets the URL string we've prepared, fills in the variables in place of the keywords like &lt;code&gt;username&lt;/code&gt; and returns the &lt;code&gt;postgres.Sql&lt;/code&gt; method. (Notice that the &lt;code&gt;ENDPOINT_ID&lt;/code&gt; is not one of the predefined aka standard Postgres connection elements so I've just baked it in the string using template string)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Since my app is built using the Nest.js framework I make use of the dependency injection which is a big part of the framework. So this service can be registered as a provider in any Nest.js module. Like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ConfigModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[...],&lt;/span&gt;
    &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;DbService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;GetUsersPgOperation&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;InfrastructureModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The ConfigModule from Nest must be accessible to our service in order to reach the environmental variables.&lt;/p&gt;

&lt;p&gt;Finally let's use the service to get a list of users.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;GetUsersPgOperation&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Inject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;DbService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// 1&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DbService&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;async&lt;/span&gt; &lt;span class="nx"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
            &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sql&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;UserInterface&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;`select * from users_table`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;// 2&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="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
                &lt;span class="c1"&gt;// handle this  &lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;  

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(...)&lt;/span&gt;  
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  
            &lt;span class="c1"&gt;// handle error&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;ol&gt;
&lt;li&gt;Grab the service&lt;/li&gt;
&lt;li&gt;Call the &lt;code&gt;sql&lt;/code&gt; method, provide return type and the query itself. (Return type must be an array because it represents the rows which our DB will return)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's it. We have a reliable, serverless Postgres DB available to our application!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading and please let me know what you think about Neon, my implementation or how horribly wrong I'm about ORM in the comment section.&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Agile vs. SCRUM</title>
      <dc:creator>Jakub Stibůrek</dc:creator>
      <pubDate>Mon, 01 May 2023 11:06:35 +0000</pubDate>
      <link>https://dev.to/alco/agile-vs-scrum-1g7h</link>
      <guid>https://dev.to/alco/agile-vs-scrum-1g7h</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Agile is like communism. It fails because it has never been implemented correctly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As far as I understand the main driving force behind legends like Cunningham, Beck and Fowler gathering at a mountain cabin and instead of having a nice BBQ party coming up with the Agile Manifesto was &lt;strong&gt;frustration&lt;/strong&gt;. They were working in the corporate environment that was awfully inflexible, punishing and just overall not suitable for developing software. I guess the kind of programmers who have been building their stuff in garage haven't faced the same problems as the manifesto-men. So it was this group of hardened and frustrated programmers who put together these &lt;a href="https://agilemanifesto.org/"&gt;4 values&lt;/a&gt;: &lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Individuals and interactions&lt;/strong&gt; over processes and tools
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Working software&lt;/strong&gt; over comprehensive documentation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Customer collaboration&lt;/strong&gt; over contract negotiation
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responding to change&lt;/strong&gt; over following a plan&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;They also have come up with &lt;a href="https://agilemanifesto.org/principles.html"&gt;12 principles&lt;/a&gt; but the core values are enough for figuring out why Agile Manifesto exists. Obviously the four things on the left were at the time sidelined in favour of the four things on the right.&lt;/p&gt;

&lt;p&gt;Documentation, plan, processes... that sounds like &lt;em&gt;a bridge construction project!&lt;/em&gt; The favourite comparison of SW development and bridge-building is a bit flawed. Civil engineering and software engineering are obviously different disciplines but so are mechanical engineering and electrical engineering. The overarching notion should be that each engineering discipline is different and thus the software engineering should be treated accordingly as a separate discipline.&lt;/p&gt;

&lt;p&gt;Agile Manifesto was a public movement that has pointed this out and tried to give us a description of what building software is and how it should be approached.&lt;/p&gt;

&lt;h2&gt;
  
  
  Idea vs. Methodology
&lt;/h2&gt;

&lt;p&gt;The Agile Manifesto is an expression of an idea. A model of software development and how this kind of work should be approached. (Reading the &lt;a href="https://agilemanifesto.org/principles.html"&gt;12 principles&lt;/a&gt; now is a good idea.)&lt;/p&gt;

&lt;p&gt;The Agile Manifesto is not a prescriptive document. It doesn't give us a todo list that upon completion would grant us the AGILE stamp. It sure does suggest some practices but no methodologies.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The most efficient and effective method of conveying information to and within a development team is face-to-face conversation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There's nothing about how, when, how often etc. should such conversation happen. It's simply saying that instead of sending an email or memo you should get up, come to your coworker and tell them what you need.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Simplicity--the art of maximising the amount of work not done--is essential.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's up to you to decide what this means. Minimising premature optimisation? Perhaps.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;At regular intervals, the team reflects on how to become more effective, then tunes and adjusts its behaviour accordingly.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There is nothing specific about this principle. It just states that you should confer regularly how you do your work.&lt;/p&gt;

&lt;p&gt;What brings specificity to the table are agile frameworks. Unlike the manifesto frameworks are prescriptive. They suggest methodologies that should be practiced in order to use the framework effectively.&lt;/p&gt;

&lt;p&gt;For example XP (extreme programming) comes up with things like sprint, pair programming, mob code review, mob programming etc. SCRUM comes up with its ceremonies aka meetings. Kanban is the ubiquitous project board.&lt;/p&gt;

&lt;p&gt;In an essence the Agile Manifesto is exactly what manifestos are, an idea. The frameworks are then exercising the idea, interpreting the principles and values and  putting them to practice.&lt;/p&gt;

&lt;h2&gt;
  
  
  SCRUM Ceremonies aren't Agile
&lt;/h2&gt;

&lt;p&gt;Unfortunately SCRUM is almost synonymous to agile these days. Due to that people who would sincerely like to make agile work for their team and coworkers have often no choice but to do SCRUM.&lt;/p&gt;

&lt;p&gt;Now, what is a ceremony? For anyone outside the SW development it's probably tight to religion or some social practice. The Cambridge dictionary:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;(a set of) formal acts, often fixed and traditional, performed on important social or religious occasions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And here's the definition of ritual which I believe to be very similar to a ceremony:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a way of doing something in which the same actions are done in the same way every time&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;"formal act", "fixed", "done in the same way every time" well that sounds an awful lot like a corporate process. Let's remind ourselves the first agile value: &lt;strong&gt;Individuals and interactions&lt;/strong&gt; over processes and tools. This is why SCRUM is flawed.&lt;/p&gt;

&lt;p&gt;Here's a list of usual SCRUM ceremonies: daily standup, refinement, planning, retrospective, demo. &lt;/p&gt;

&lt;p&gt;Standup can last 5-20 minutes the other meetings can take 20 minutes to 2 hours. Often it's about 4-5 hours each sprint doing meta-work = working in order to eventually actually work on the software. On top of that many organisations and teams have company-wide meetings, various guild meetings, interest-groups meetings etc. And to take it to the extreme these meetings tend to be longer when working remotely because of technical problems and the fact that many people in one video-call just slow everything down. And don't get me started on the mental toll that these activities have on people. The ceremonies stress the same muscle as the work we do - the brain.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Simplicity--the art of maximising the amount of work not done--is essential.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the spirit of agility let's assess the meta-work that ceremonies are and find a way how to minimise the time spent on them.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Daily: if you have a blocker, talk to someone who can help you immediately. For checking the status of work, see the board.&lt;/li&gt;
&lt;li&gt;Refinement, planning: in my opinion these are contradictory to the agile principles in the most blatant way. They serve only as micro-management tools.&lt;/li&gt;
&lt;li&gt;Retrospective: if you have an idea how to improve the way we do our work, present it to the interested people whenever you have time. You can talk about it at lunchtime.&lt;/li&gt;
&lt;li&gt;Demo, review: this is probably only reasonable meeting. Gather the team and the users and show them what's been released and how to take advantage of it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SCRUM ceremonies are not necessary and definitely not agile. They as a core part of the framework render it as a whole not agile. The amount of focus on meta-work itself is contradictory to agile principles which stress the importance of actually working on the software. Does that make SCRUM bad? Not necessarily but it makes it bad agile implementation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Agile is like communism. It fails because it has never been implemented correctly. &lt;em&gt;Because everyone tries only SCRUM.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  My Few Ideas
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;for the authors of the Agile Manifesto communication was crucial. But communication must be natural and needs no schedule. &lt;strong&gt;Communicate whenever you need it, don't wait for a meeting.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;don't do any meta-work.&lt;/strong&gt; Concentrate maximum of your time on developing and/or discussing the software.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;focus on building your own methodology&lt;/strong&gt;, your own practices and let them naturally surface. Like the nature of the product, the work itself is volatile. Using a prefabricated framework leads to apathy, inefficiency and bad software. &lt;strong&gt;Abolish ceremonies.&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consider moving away from sprints.&lt;/strong&gt; They don't bring much value to software developers or users. They bring value to the management because they introduce subtle deadlines and a way how to measure (although inefficiently) work. Develop whatever you agree on is most important and when you are done just pick another feature and show the finished work to the users.&lt;/li&gt;
&lt;li&gt;lastly &lt;strong&gt;not working in an agile way doesn't necessarily mean that you have to get back to waterfall.&lt;/strong&gt; Agile is relying heavily on the face-to-face communication. It can be hard to work that way remotely for example. Just imagine open-source software being built in an agile way. It doesn't work. Agile is meant for small concentrated teams. &lt;strong&gt;Don't be afraid to embrace a different approach.&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>agile</category>
      <category>developer</category>
      <category>productivity</category>
      <category>rant</category>
    </item>
    <item>
      <title>Better keys</title>
      <dc:creator>Jakub Stibůrek</dc:creator>
      <pubDate>Wed, 28 Dec 2022 10:25:09 +0000</pubDate>
      <link>https://dev.to/alco/better-keys-lhc</link>
      <guid>https://dev.to/alco/better-keys-lhc</guid>
      <description>&lt;p&gt;As a self-taught software engineer I'm quite used to having a different view on certain topics than my peers coming from technical backgrounds. Most often it's about our approach to organising work or communicating rather than the coding itself. One of the first things that have struck me when I started to code, even when I wasn't a professional yet, was the health issues and that a lot of IT professionals ignore them. Working as a SW developer inevitably means hours spent in front of a computer every day. So I looked at my desk and the things that I use to produce code. I saw a monitor, keyboard, computer, table and chair and I thought about the ways I can improve these to not get the carpal tunnel syndrome (or many more health problems induced by this way of life) in 10 years.&lt;/p&gt;

&lt;p&gt;I actually started with my monitor and not the keyboard because I was using a laptop back then and I was going to get a second monitor. My primary focus wasn't to get the highest frequency or the best colours. Don't get me wrong I wanted to get the best product I could afford but mainly I wanted a monitor that would go easy on my eyes. I purchased a monitor that can adjust contrast and brightness on the fly based on the conditions in my room. Looking back I would get a different model because I now don't use two or three monitors setup but a single big one (at the office) and the one I have at home is too small for my liking. But still it's quite pleasant to look at it in the evening when the light in my room is dim. My eyes don't hurt even if I don't use a dark theme in my IDE (yes, I'm a light-theme-using psycho). And the monitor can be easily moved up and down to be at the right level for the person using it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Down the rabbit hole
&lt;/h2&gt;

&lt;p&gt;Soon after I've got myself a second monitor (so I had a laptop and two monitors on my table) I decided that a standalone keyboard would be more practical than using the laptop build-in even though I was pretty content with it. I went to a local computer shop and tried a few displayed keyboards. I found out that there are basically two kinds of keyboards out there: &lt;em&gt;mechanical&lt;/em&gt; and &lt;em&gt;membrane&lt;/em&gt;. And so my journey to the mechanical keyboard realm has begun. Anyone who owns one must know how treacherous and deep this rabbit hole is. &lt;/p&gt;

&lt;p&gt;Well initially I didn't know of course... and I got myself a &lt;em&gt;gaming&lt;/em&gt; mechanical keyboard. Low profile stacked with shiny LEDs that would be enough for an entire U2 show. It was kind of expensive compared to a basic 10€ membrane keyboard but still cheap for a mechanical keyboard. And it broke soon. Some keys stopped working and I was pissed. Unfortunately I couldn't return it because I tried to fix it and I messed up and broke it even more. But as I poked the thing and I googled a few things I found out that the switches (that's what goes &lt;em&gt;clickity click&lt;/em&gt; when you press a key) are actually not very common even for a low profile keyboard. You see there is two or three common interfaces that connect a switch to a keycap and those I had on my first keyboard were some knockoff that wasn't compatible with anything. So I had to get a new keeb. And I was just starting my research on the &lt;strong&gt;&lt;em&gt;mechanical wonderland&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why?
&lt;/h2&gt;

&lt;p&gt;I'd like to briefly explain how these keyboards work and what kinds are there available but before that I want get to what initially made me buy a mechanical keyboard.&lt;/p&gt;

&lt;p&gt;When typing on most membrane keyboards and predominantly on laptop keyboards the feeling of pressing a key can be mushy, sometimes keys respond to any slight touch, some keyboards bend, keys rub one another, etc. the main point is that you get what the manufacturer serves you, like it or not. And I just felt like I want a keyboard that would fit me and my hands. The mechanical keyboards are produced usually in a small quantity by invested people for their peers, you have to often put them together yourself but even if they are pre-built you still have some degree of control. You can choose the size of the keyboard, maybe you don't need a function row or a numpad... you can choose the switches, how hard are they to press, whether they make sound or not, haptic response, how precise are they and so on.&lt;/p&gt;

&lt;p&gt;At the beginning I didn't even know what else I can customise, yet I was already sold on the idea of &lt;strong&gt;&lt;em&gt;custom keyboard.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mechanical switch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How does a membrane keyboard work?
&lt;/h3&gt;

&lt;p&gt;Mechanical switch actually predates a membrane keyboards. It was the original way how keyboards were made. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;So a pro tip: If you want a mechanical keyboard and you are on a tight budget, just get an old keyboard from 80's or 90's from your local used electronics shop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nowadays keyboards are usually membrane. That means that a key is actuated by two thin metal pieces touching. This design has many advantages over the mechanical keyboards. Firstly it's much cheaper, it's thinner and it's quite durable. You can even prevent it from short circuiting when you spill a coffee on it quite easily.&lt;/p&gt;

&lt;p&gt;This diagram shows how a membrane key actuates.&lt;br&gt;
&lt;a href="https://media2.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%2F8gsmklxxu1l1thjmdaq6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8gsmklxxu1l1thjmdaq6.png" alt="Membrane keyboard diagram" width="800" height="183"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How does a mechanical switch work?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fmwdtn67rhm4xbedi2u6i.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmwdtn67rhm4xbedi2u6i.gif" alt="Cherry MX linear switch gif diagram" width="200" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see how a mechanical switch actuates when pressed on the diagram above. This particular switch is called &lt;em&gt;Cherry MX Red&lt;/em&gt; and it's a very popular switch used e.g. in pro-gaming. It's so called linear switch. Meaning that the moving part is traveling from the initial position to the actuating position with no obstruction along the way. These are very precise and that's why they are popular among gamers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fo618h2u0lqu30xzclpjr.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fo618h2u0lqu30xzclpjr.gif" alt="Cherry MX tactile switch gif diagram" width="200" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The second kind of a switch is so called &lt;em&gt;tactile&lt;/em&gt;, this particular is a &lt;em&gt;Cherry MX Brown&lt;/em&gt;. These switches have a little bump on the moving body which upon actuation gives a haptic response to the finger. I personally like the feel of pressing a button which these tactile switches provide and I think they are the best kind for typing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fphhceqre7hjb19tcy8p0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fphhceqre7hjb19tcy8p0.gif" alt="Cherry MX tactile clicky switch gif diagram" width="200" height="200"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.keyboardco.com/blog/index.php/2012/12/an-introduction-to-cherry-mx-mechanical-switches/" rel="noopener noreferrer"&gt;Source of the gifs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The third diagram shows a &lt;em&gt;Cherry MX Blue&lt;/em&gt; which is a tactile and &lt;em&gt;clicky&lt;/em&gt; switch. Unlike the linear switch this one is not silent. You can see that the moving body is made out of two parts. The white part jumps when the switch actuates resulting in a quite loud click which you either love or hate. Either way I don't recommend using these in an office. You might get hit by a mere basic Logitech keyboard in the face. &lt;/p&gt;

&lt;p&gt;Here is a nice video explaining the difference between a mechanical and membrane keyboard.&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=CVtjCbpW7as" rel="noopener noreferrer"&gt;Mechanical vs Membrane Keyboards: Are Mechanical Keyboards Worth It?&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Layout
&lt;/h2&gt;

&lt;p&gt;Have you ever looked at your keyboard and wonder why is that the letters are arranged in this particular way? Why is the top row widest and the second and third row slightly thiner and kinda shifted to a side? Why is the space button so big? The questions could and should go on. You can find many &lt;a href="https://.youtube.com/watch?v=c8f6us-Sjlo" rel="noopener noreferrer"&gt;videos&lt;/a&gt; on the internet explaining why QERTY keyboard layout has won the &lt;em&gt;most used layout&lt;/em&gt; prize. TLDR is that we just got used to it. But since you have already read all the text above this paragraph you know that can't stop me!&lt;/p&gt;

&lt;p&gt;I wasn't ever taught how to properly touch type. I have learnt to somehow type fast and even without looking at the keyboard myself as a lot of people do. This might sound like a disadvantage but actually that means that when you want to learn to touch type properly you can consider yourself a clean sheet. You don't have to limit yourself to a status quo layout, learn some DVORAK maybe.&lt;/p&gt;

&lt;p&gt;Yeah there are many alternative keyboard layouts that have been put together by a chance, method of science or compulsive need for symmetry. You can even try to create your own unique layout since you are building your keyboard, you can have your layout as well. I even tried to do it the scientific way. I took my mother tongue (Czech) and got some data on the frequency of letter occurrence and their combinations then I laid those most frequent on the home-row (that's the starting position for your fingers when you lay them on the keyboard, on qerty it's 'asdfghjkl;'). Then the less frequent on the edges and so on. Unfortunately I have never actually tried this layout. I soon realised that I write more English on my keyboard than Czech and I need to write a bunch of special symbols since I'm a programmer. So I gave in on creating my own layout.&lt;/p&gt;

&lt;p&gt;And on top of that I realised that even though I'm going to have my own special keyboard I still would from time to time need to use a laptop keyboard or someone else's keyboard and it could be quite hard after I've spent some time learning some totally different layout. So in the end I personally have kept using QERTY on all of my custom made keyboards and I don't have any trouble using the standard keyboards. (Unless they don't have English legends, then I'm lost.)&lt;/p&gt;

&lt;p&gt;Nevertheless I strongly support use of alternate layouts and perhaps one day I'll also switch.&lt;/p&gt;

&lt;p&gt;BUT you don't have to give in to the peer-pressure all the way. There is still one distinct problem of the standard kb layout. The width of lines and the shift (which is called stagger). It bothered me that to write 'FRV' my left index finger would have to go up and left and then down and right. Try it. This is so unintuitive and awkward. Remove the stagger and align the letters in neat columns and you get an ortho-columnar layout. Much better.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fa4dsolw0zhhr7cnavjjd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fa4dsolw0zhhr7cnavjjd.png" alt="orthocolumnar layout" width="776" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was but a beginning of my 'ortho' journey. But if this is already something you'd like to use there is this &lt;a href="https://www.zsa.io/planck/" rel="noopener noreferrer"&gt;keeb&lt;/a&gt; preassembled and easy to program.&lt;/p&gt;

&lt;h2&gt;
  
  
  End game?
&lt;/h2&gt;

&lt;p&gt;After I've spent some time typing on a mechanical keyboard, but still the standard qerty staggered layout, I've done the aforementioned research. I've found out about alternate layouts, staggerless ortho-columnar keyboards and finally about split keyboards. As I've mentioned before my end goal is to have &lt;em&gt;my&lt;/em&gt; keyboard, meaning I wanted a keyboard that would fit me, no factory made standard bs. And one of my biggest concerns from the beginning was health. I knew going in the programming career that I'll spend thousands of hours typing and siting (actually I've a standing desk so some standing is going on as well) in front of the computer and I want to minimise the consequences of this lifestyle. Kinda like sportsmen know about the stress their career puts on their body and so they take precautions.&lt;/p&gt;

&lt;p&gt;A split keyboard consists of two halves. They can be completely split and connected via bluetooth or a cable or they can be kinda still together but separated by a few inches of plastic. My keyboard(s) are split and connected by a TRRS cable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F5ne3s2thess9c5zaf4bw.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F5ne3s2thess9c5zaf4bw.jpeg" alt="Kyria keyboard" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This model is called Kyria and you can get a DIY kit &lt;a href="https://splitkb.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Why have I chosen to build and use Kyria. &lt;em&gt;Such a weird keyboard... it doesn't even have a legend on the keys. Is there enough keys for everything that I have on my laptop keyboard?&lt;/em&gt; I get you. I've listened to people admire the weirdness and also to just laugh at it. Let me explain how it works and what are the benefits.&lt;/p&gt;

&lt;p&gt;The white keys are standard qerty layout so if you can touch type, you can use this keyboard just right to type. There is no big space because there is no real need for it on a modern keyboard. On this kb space is one of the blue keys in the left thumb cluster. The blue keys are either modifier keys like &lt;em&gt;cmd, shift, ctrl,&lt;/em&gt; etc. or a layer swap keys (I'll explain layers soon) or some kind of macro key. I have for example a macro to switch input language to Czech and back to English. I have a macro for signing out of my computer.&lt;/p&gt;

&lt;p&gt;The arrangement of the keys, as you can see, is ortho-columnar and I've talked about the benefits of that but they are not ortho-linear. The stagger on Kyria is much different from the standard columnar stagger which serves no real purpose. The linear stagger is used to compliment your fingers because they are, as you may have noticed, not of the same length. So the layout basically copies the shape o your hand. One way of going even further would be to not use a pre-designed kb like a Kyria but to design it from scratch to match your hand exactly. I might once get there.&lt;/p&gt;

&lt;p&gt;Now where the &lt;em&gt;hell&lt;/em&gt; are numbers, function row, brackets... that's where the layers come in. The idea behind Kyria is that your fingers never have to travel more then one key from the home row to type anything. So using a firmware like &lt;a href="https://qmk.fm/" rel="noopener noreferrer"&gt;QMK&lt;/a&gt; or &lt;a href="https://zmk.dev/docs" rel="noopener noreferrer"&gt;ZMK &lt;/a&gt; we can program the keyboard to do anything and one common technique is to create multiple contexts (layers) which change the behaviour of the keys. You then assign some keys (in my case those in thumb clusters) to switch the contexts. So to write down &lt;em&gt;(35-45)&lt;/em&gt; I have to switch from my querty layer to brackets, special and numbers characters layer. It takes some learning but in the end it's very effective.&lt;/p&gt;

&lt;p&gt;Here are some of the layers that I have programmed for my kbs.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F8ijmmrnj8p557um28bfn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F8ijmmrnj8p557um28bfn.png" alt="keyboard layout" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fl0hviyvix399rplbbhlc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fl0hviyvix399rplbbhlc.png" alt="keyboard layout" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Feow29czzhl6jzgn1ybh2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Feow29czzhl6jzgn1ybh2.png" alt="keyboard layout" width="800" height="267"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may think that I've already taken it to the extreme but check this &lt;a href="https://www.youtube.com/@BenVallack" rel="noopener noreferrer"&gt;&lt;em&gt;mad lad&lt;/em&gt; &lt;/a&gt;out.&lt;/p&gt;

&lt;p&gt;Is this the end game for me? Have I found the right keeb for myself? At the moment I'm pretty content with what I have. I'm experimenting from time to time with some modifications like a rotary encoder etc. and I was thinking about building another keeb that would have the number row because Czech special characters are quite hard to tackle using the layers or key combos and on standard keyboards the number row is where these are located. &lt;/p&gt;

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

&lt;p&gt;There is many ordinary things around us that we've got used to never change and often changing them would probably bring more harm than benefits. As engineers say &lt;em&gt;"If it works don't change it but pretend like you did."&lt;/em&gt;. I'm looking at you Apple. BUT sometimes trying to look at such an ordinary thing as a keyboard from a different angle may pay out. I have to admit that this journey, have it not become my hobby as well, would be tedious. The total customisability always comes with a lot of work. You should consider whether this is a thing that you should spend time on. If you can't or don't want to spend too much time building your very own keeb, there is a bunch of options which are somewhere in the middle, you can customise them but only in some aspects, e. g. &lt;a href="https://ergodox-ez.com/" rel="noopener noreferrer"&gt;Ergodox&lt;/a&gt; have a split keyboard that you can program to your liking.&lt;/p&gt;

&lt;p&gt;Ultimately I hope this article have entertained you and perhaps gave you some insight in the realm of mechanical keyboards.&lt;/p&gt;

</description>
      <category>watercooler</category>
      <category>writing</category>
    </item>
    <item>
      <title>Domain-Driven Design by Eric Evans</title>
      <dc:creator>Jakub Stibůrek</dc:creator>
      <pubDate>Mon, 08 Aug 2022 07:00:57 +0000</pubDate>
      <link>https://dev.to/alco/domain-driven-design-by-eric-evans-30g8</link>
      <guid>https://dev.to/alco/domain-driven-design-by-eric-evans-30g8</guid>
      <description>&lt;p&gt;When I took on my current role at &lt;a href="https://www.betsys.com/" rel="noopener noreferrer"&gt;Betsys&lt;/a&gt; as a Node.js developer, I was quite thrilled to start working in a whole new field, both in terms of programming, since I was a FE developer before, and also from the business perspective since I used to work at a software agency and now I'm working on a product. There were plenty of things that I had to learn, e.g. the Nest.js framework, Angular to help also on FE side of the application, hexagonal architecture and &lt;strong&gt;DDD&lt;/strong&gt; - Domain-Driven Design. &lt;/p&gt;

&lt;p&gt;This concept was unknown to me even though it's apparently been around for quite some time and has gained a lot of popularity among those who design robust software systems - the enterprise kind. I did get some introduction to the topic from my team members but that wasn't enough. I then found out the origin of this concept - which is the book by Eric Evans. &lt;/p&gt;

&lt;p&gt;This article would be too long if I were to sum up the whole book, so I have focused only on the main principles that you're gonna need if you want to employ DDD. The rest of the book, that I have not covered, is also full of examples which are really helpful, but I don't see the point in copying them here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ubiquitous language
&lt;/h2&gt;

&lt;p&gt;Fans of Philip K. Dick should be intrigued when they see the word &lt;em&gt;ubiquitous&lt;/em&gt; or shortly &lt;a href="https://www.supersummary.com/ubik/summary/" rel="noopener noreferrer"&gt;&lt;em&gt;Ubik&lt;/em&gt;&lt;/a&gt;. But in the case of DDD this isn’t a spray that reverses regression of time and space. The ubiquitous language is actually a foundation of DDD. If all you take from DDD is ubiquitous language, then you have already learned an important lesson.&lt;/p&gt;

&lt;p&gt;Usually people who work with code, people who design graphical interfaces, people who work with clients… they all tend to have their own jargon, specific vocabulary. One group might refer to a user of an application as a client, other as a customer. Developers can call a group of data a table but to a business analyst these are simply stock items. When these professionals get together their &lt;em&gt;languages&lt;/em&gt; may collide. Someone may stand out as a so to speak translator, a person who have learnt multiple of these languages. Then they become a bottleneck of the communication.&lt;/p&gt;

&lt;p&gt;The fact that different professions have their way to speak and talk about they work is… well a fact. We would hardly get them to change they jargon and it wouldn’t be much useful. But people naturally, when trying to achieve a common goal, want to and try to communicate effectively. Paying attention to this human trait, cultivating it and investing in it our time and energy bears fruit.&lt;/p&gt;

&lt;p&gt;So on a software project different teams have their &lt;em&gt;language&lt;/em&gt; but they share a common goal. They want to develop a piece of software and they need to talk about it for various reasons. We also need to realise that the communication is crucial. Software development is a teamwork (mostly) and core concept in teamwork is communication. Key thing to achieving smooth and effective communication is minimising ambiguity and maximising clarity. We all need to be on the same page. Thus we need a common language to talk, write, document, model, plan… our project.&lt;/p&gt;

&lt;p&gt;It would be naive thinking that such language can be put together at the beginning of a project and used effectively during the whole life of the project. Ubiquitous language should feel natural so its creation must also be natural and natural processes take some time. Basically the whole team and even clients, everyone involved in the project should right from the beginning at least know that there is a goal of having some ubiquitous language. A bit contrary to the beginning of this paragraph, a significant amount of the vocabulary will be created at the initial phase of the project as the basic form of a model will be put together. Some foundation has to be present when embarking on an adventure that developing software is. But this foundation must be scrutinised. Throughout the project’s life more and more precise language and model will be shaped naturally.&lt;/p&gt;

&lt;p&gt;Important notion about the foundation of and ubiquitous language is that it should not be a synthetic mix of different jargons, vocabularies etc. The DDD defines a &lt;em&gt;domain expert&lt;/em&gt;, a person who knows the most about the project’s domain. It can be for example a user of the to be created SW. Now the domain expert’s language should be the foundation of the ubiquitous language. We want the whole team to be able to talk about the domain and using an existing language is natural, compared to making up a completely new one probably consisting of a professional vocabulary forced on to the domain. I can even imagine this foundation being right in the beginning of a project altered by let’s say a developer to better reflect how the domain will be represented in the model and the actual code. But this is already initialising the process of creating a working ubiquitous language.&lt;/p&gt;

&lt;p&gt;The ubiquitous language is quite similar to what is in linguistics called a &lt;em&gt;pidgin.&lt;/em&gt; The pidgin is a kind of made up language. When two tradesmen from different cultures have met for the first time, speaking completely different languages but sharing a common goal - making a deal - they would eventually create a new language, simplified mixture of the two original languages designed only to achieve the common goal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Practical tips for ubiquitous language
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  keep an up to date dictionary. It's an easy to maintain documentation of the project and can help immensely to onboard new team members.&lt;/li&gt;
&lt;li&gt;  discuss and scrutinise the language as often as you can, this way you not only get a consensus but also make everyone consider twice how will they name their next variable, function etc.&lt;/li&gt;
&lt;/ul&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%2Fxg7skdyj5cklj70pmyxi.jpeg" 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%2Fxg7skdyj5cklj70pmyxi.jpeg" alt="Example from the book"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Isolating the domain
&lt;/h2&gt;

&lt;p&gt;It can be hard to focus on one &lt;em&gt;thing&lt;/em&gt; when another &lt;em&gt;thing&lt;/em&gt; gets in your way. How can you find anything in your drawer when there is everything in there. It would be much more practical to have a few drawers one for each kind of things you want to keep there. If you are familiar with the office drawer cabinet you can take that as an illustration of the concept that will unfold on the lines to come.&lt;/p&gt;

&lt;p&gt;Understandably the DDD must focus on domain. That is the one thing. But when developing an application there is more things that we have to deal with other than domain. We need to show something to the user, we need to store data somewhere, etc. An quite often in an OOP program the domain is spread in the whole project. There is a piece in the UI, piece in a controller and some of it right at the place where we query our database. At scale this brings a lot of problems. It gets hard to follow the trace and we can easily change the business logic when fixing some UI issue. Much like when we want to get something from a drawer everything in it moves inevitably and uncontrollably.&lt;/p&gt;

&lt;p&gt;The solution presented by DDD and a prerequisite for applying the DDD principles is to separate concerns. Most importantly, isolate the domain from the rest of the application. The separation of concerns can be fairly complex but commonly it is done by creating layers. The DDD requires practically just two layers - domain layer and everything else layer - but that wouldn’t be thorough. So instead of such simplistic solution, DDD encourages at least 4 layered structure. The layers are: UI layer, application layer, domain layer, infrastructure layer.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;User Interface (or Presentation Layer)&lt;/td&gt;
&lt;td&gt;Responsible for showing information to the user and interpreting the user's commands. The external actor might sometimes be another computer system rather than a human user.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Application Layer&lt;/td&gt;
&lt;td&gt;Defines the jobs the software is supposed to do and directs the expressive domain objects to work out problems. The tasks this layer is responsible for are meaningful to the business or necessary for interaction with the application layers of other systems. This layer is kept thin. It does not contain business rules or knowledge, but only coordinates tasks and delegates work to collaborations of domain objects in the next layer down. It does not have state reflecting the business situation, but it can have state that reflects the progress of a task for the user or the program.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Domain Layer (or Model Layer)&lt;/td&gt;
&lt;td&gt;Responsible for representing concepts of the business, information about the business situation, and business rules. State that reflects the business situation is controlled and used here, even though the technical details of storing it are delegated to the infrastructure. This layer is the heart of business software.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure Layer&lt;/td&gt;
&lt;td&gt;Provides generic technical capabilities that support the higher layers: message sending for the application, persistence for the domain, drawing widgets for the UI, and so on. The infrastructure layer may also support the pattern of interactions between the four layers through an architectural framework.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;Evans, E. (2004) Domain-Driven Design. p. 70&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;DDD only &lt;em&gt;really requires&lt;/em&gt; one isolated layer which is the Domain Layer.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The "domain layer" is the manifestation of the domain model and all directly related design elements.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Simply because it's impractical to mix the domain with other parts of a program - the domain model must be separated. How we decide to further isolate other parts of the structure is entirely up to us. &lt;/p&gt;

&lt;h2&gt;
  
  
  Expressing the domain-model in the software
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Entity
&lt;/h3&gt;

&lt;p&gt;Basis of any domain model are objects. They describe different actors, patients, commodities etc. of the domain and in OOP they carry the actions that can be invoked on them. Some of these objects are unique. Like a customer for example. We need to be sure that one customer can't be mistaken for another. We need to express and ensure their uniqueness within the program. These objects are called Entities in DDD.&lt;/p&gt;

&lt;p&gt;The uniqueness of an Entity mustn't rely simply on its attributes. There can be two customers living in the same building and having the same name. There is thousands of Toyota Corollas yet they are not the same. Each of them has some kind of identifier to tell them apart. Perhaps a VIN number. Similar to that, Entities tend to have an ID (or some other unique attribute, a fingerprint).&lt;/p&gt;

&lt;p&gt;To ensure system that is not error prone we need to match Entities predominantly by these fingerprints. Creating such IDs that persist through time and even in distributed or mixed systems is a delicate matter. Still the concern of DDD is to have unique entities identified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Value Object
&lt;/h3&gt;

&lt;p&gt;Many objects have no conceptual identity. These objects describe some characteristic of a thing. They are not merely missing an identity they are holding a value that can be used independent of its application. E. g. digit 7 doesn't need any ID because it's nothing unique. You can use it in "17" or "57" and we don't care which instance of the digit 7 you have used. &lt;/p&gt;

&lt;p&gt;Another example is a child drawing a picture with crayons. If the kid wants to use a yellow crayon to draw sun and there is 3 yellow crayons on the table, the child doesn't care which one they use. Its identity is irrelevant. But if the crayon is a storage item of an art supply store we may want to identify it in some way.&lt;/p&gt;

&lt;p&gt;Whether an object is a VO or an Entity is something to be discussed and depends on the context. When we design a model we should ask ourselves do we need this object to be differentiated from others? If the answer is "Yes." then it's an Entity and vice versa.&lt;/p&gt;

&lt;p&gt;An Entity may be comprised of VOs. VO can be, since they aren't unique, reused or shared by Entities. For example when two people have a same name we don't need to create a second "John" we can reuse the first one. But to make sure this is safe VOs must be immutable. So to change a value you need to use another VO and not change the original one's value. If John changes his name to Clarence we mustn't change the content of the "John" VO, we need to use the "Clarence" VO. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A Value Object can give information about an Entity. It should be conceptually whole.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Services
&lt;/h3&gt;

&lt;p&gt;In OOP developers fit everything from the domain to objects - attributes and functionalities. The same developers commonly stumble upon a functionality that they can't properly assign to an object because it may fit to multiple objects or none at all. Such functionalities are in DDD called Services. They are independent from Entities and VOs. We keep Services separated in order to not distort conceptuality of Entities and VOs and they hold &lt;strong&gt;no state&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Services are also called operations. Each operation should perform one functionality, its name should come from Ubiquitous language. Parameters and results of an operation should be domain objects.&lt;/p&gt;




&lt;p&gt;If you are not a fan of OOP you may take this a step forward and separate all the functionality from domain objects. Keep in mind that this article focuses on the book by Eric Evans but DDD is not exclusive to OOP as it may seem in this book. Actually DDD fits well with functional programming and it's compositional principle. You can learn more about that in videos by &lt;a href="https://www.youtube.com/watch?v=2JB1_e5wZmU" rel="noopener noreferrer"&gt;Scott Wlaschin&lt;/a&gt; And feel free not to constrain yourself with the choice between those two paradigms, in fact at our company we mix concepts from both and the result is great developer experience. &lt;/p&gt;




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

&lt;p&gt;This book has a lot more to offer: how to refactor toward a deeper domain insight, practical examples, using DDD in large-scale application... I only wanted to offer you a summary of the main concepts but I strongly recommend you to explore the book yourself.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>beginners</category>
      <category>tldr</category>
      <category>book</category>
    </item>
    <item>
      <title>Rust Journal [0]</title>
      <dc:creator>Jakub Stibůrek</dc:creator>
      <pubDate>Sun, 13 Feb 2022 12:40:34 +0000</pubDate>
      <link>https://dev.to/alco/rust-journal-0-14b1</link>
      <guid>https://dev.to/alco/rust-journal-0-14b1</guid>
      <description>&lt;p&gt;Today marks the first time ever I have written a Rust code. I have followed “the book”, the official handbook for the Rust language (&lt;a href="https://doc.rust-lang.org/book/"&gt;here it is&lt;/a&gt;) , and have written two programs: Hello world and Guess the Number Game. &lt;/p&gt;

&lt;p&gt;How have I learned about Rust. I’m actually a web developer and I usually work with JavaScript or TypeScript on front-end. So I develop web UI. I have no CS degree and all the official education in CS I have constists of what they have thought me in high school, which wasn’t much since it was only an electrical engineering school. I’m from Europe and high schools work quite different from those in US here, the high schools here center around a certain goal: e.g. go to University, professional aim etc. I have learned web development on my own and felt pretty acomplished when I’ve succesfully started a career in programming.&lt;/p&gt;

&lt;p&gt;Nevertheless I’m at the point now where I feel like what I’m doing isn’t enough. I’m not really sure what I want but I feel like I should try to make something different than another web app or website. So I have investigated what other languages or technologies I might be interested in. And suddenly my favourite YT channel, which focuses on 100 second long (more like 100 sec short) videos explaining various programming topics, published a video about the Rust programming language. And I felt like - wow this is it. &lt;/p&gt;

&lt;p&gt;What is it actually that got me so much interested in the language on the first brief sight? I have no idea. But I know that I want to understand it and that’s the only driving force necessary for starting a new learning journey.&lt;/p&gt;

&lt;p&gt;So it begins. And I wonder where will this journey get me.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learning in public
&lt;/h3&gt;

&lt;p&gt;I’m planning on trying the technique of learning in public. Many people online recommend doing it. It supposedely should make me not quit and by trying to explain things make myself understand them better. The second thing I know for sure works because I have worked as a language teacher before, the first thing... we will see. Anyway if you want to follow my journey, I’ll be posting updates here and later on my personal website (that one is under reconstruction at the moment so I’ll share it with you when it’s done).&lt;/p&gt;

&lt;h3&gt;
  
  
  Goals
&lt;/h3&gt;

&lt;p&gt;I believe that I should have a certain goal or goals in front of me so that I know how far I’m in the progress and what lies in front of me. I’ll try to make up a few points that I feel like are acomplishable in the near future.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[ ]  learn the basic syntax

&lt;ul&gt;
&lt;li&gt;quite self-explenatory I believe&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;[ ]  make a simple CLI program

&lt;ul&gt;
&lt;li&gt;I’ve got the recommendation from another YT person that CLI is a good starting point and I could actually make something really useful to me right from the beginning&lt;/li&gt;
&lt;li&gt;I’m thinking of currency rate calculater or something of that sort&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;[ ]  learn about connecting to the web

&lt;ul&gt;
&lt;li&gt;I want to know, eventualy, how to make a REST api, because that’s again something I could really use, e.g. creating a backend for my personal website&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;[ ]  make a simple REST api

&lt;ul&gt;
&lt;li&gt;by simple I mean one endpoint or something like that&lt;/li&gt;
&lt;li&gt;maybe I could make the CLI program I would have done by this time accesible on the www&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;[ ]  make new goals

&lt;ul&gt;
&lt;li&gt;I know already that it would take me at least a few months before I get here, so nothing further needs to be planned, when I get here I’ll figure out some proper project&lt;/li&gt;
&lt;/ul&gt;


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

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;I have started to learn a new programming lanaguage. I hope it will be a lot of fun and I’ll get to create amazing things with it and I want to try to do it in public. If you feel like you wanted to start something new lately, join me and learn with me. We can move each other forward.&lt;/p&gt;




&lt;p&gt;The book: &lt;a href="https://doc.rust-lang.org/book/"&gt;https://doc.rust-lang.org/book/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The 100 sec channel: &lt;a href="https://www.youtube.com/c/Fireship"&gt;https://www.youtube.com/c/Fireship&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Let’s get rusty channel: &lt;a href="https://www.youtube.com/channel/UCSp-OaMpsO8K0KkOqyBl7_w"&gt;https://www.youtube.com/channel/UCSp-OaMpsO8K0KkOqyBl7_w&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My GitHub where I’ll store my Rust projects: &lt;a href="https://github.com/JakubStiburek"&gt;https://github.com/JakubStiburek&lt;/a&gt;&lt;/p&gt;

</description>
      <category>rust</category>
      <category>beginners</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Learn the basics of algorithms and data structures</title>
      <dc:creator>Jakub Stibůrek</dc:creator>
      <pubDate>Wed, 15 Sep 2021 12:49:09 +0000</pubDate>
      <link>https://dev.to/alco/learn-the-basics-of-algorithms-and-data-structures-2f5m</link>
      <guid>https://dev.to/alco/learn-the-basics-of-algorithms-and-data-structures-2f5m</guid>
      <description>&lt;p&gt;For anyone who hasn't gone trough a proper CS program the programming theory is a challenging topic. Learning how to code, learning syntax and just using the chosen programming language is already a challenge. Soon (when one aims to get to a professional level) student finds out about more abstract topics which are not a matter of a particular language but they are shared amongs many. Such topics are programming paradigms like OOP or functional programming, algorithms, etc. Algorithms are particularly important, since we all are using them no matter the language or framework we prefer. As a self-taught developer I have felt that I'm missing out on this fundamental knowledge which is not commonly taught on the internet. So I have researched for a book that would help me understand it at least a bit. Unfortunately most of the theoretical literature consists of thick and hard-to-read books. Well except the &lt;strong&gt;grokking algorithms&lt;/strong&gt; by &lt;strong&gt;A. Y. Bhargava&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Contents of the book
&lt;/h1&gt;

&lt;p&gt;It's structured into rather independent chapters covering always one coherent topic (it's always a specific algorithm, except for the beginning of the book ). Depending on the knowledge you already have you can read it in two ways, chapter by chapter: that is obviously best for those with zero knowledge, or you can cherry pick chapters: and this is probably best approach for the second reading or for those who know about some of the algorithms already. But overall it's a book for beginners so experienced programmers will probably find it useless.&lt;/p&gt;

&lt;h2&gt;
  
  
  Big O Notation
&lt;/h2&gt;

&lt;p&gt;One of the first concepts introduced is a so-called Big O Notation. This is, simply put, a measurement of time efficiency of a given algorithm. Even with the contemporary computers if one chooses a wrong algorithm for the job, they can wait for years for it to finish.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"big o" ---&amp;gt; O(n)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Data structures
&lt;/h2&gt;

&lt;p&gt;Throughout the book you'll learn not only about algorithms but also about data structures. For us, JavaScript, developers this is quite foreign topic. There is an array in JS but what it really is and how it actually works? Well that's a topic for another article. However in this book you will learn what is: &lt;strong&gt;array&lt;/strong&gt;, &lt;strong&gt;queue&lt;/strong&gt;, &lt;strong&gt;linked list&lt;/strong&gt;, &lt;strong&gt;stack&lt;/strong&gt; and &lt;strong&gt;hash table&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The algorithms
&lt;/h2&gt;

&lt;p&gt;The author has picked only a handful of algorithms but also the most important or rather most useful ones or even better put those which you might most probably see in the code you work with at work.&lt;/p&gt;

&lt;p&gt;Starting with &lt;strong&gt;binary search&lt;/strong&gt;, &lt;strong&gt;quicksort&lt;/strong&gt; going trough &lt;strong&gt;Breadth-first search&lt;/strong&gt;, &lt;strong&gt;Dijkstra's algorithm&lt;/strong&gt; and finishing with &lt;strong&gt;K-nearest neighbours&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I've found the book most useful in the early chapters because it helped me to put together scarcely found information on the internet and the latter topics I sometimes had a hard time to grasp and I will definitely get back to them once I will need it.&lt;/p&gt;

&lt;p&gt;One of the side-topics is &lt;strong&gt;Recursion chapter&lt;/strong&gt; which I found very important because this is an idea that you build many algorithms on top of and you will most probably use it in a real-life project at some point.&lt;/p&gt;

&lt;h1&gt;
  
  
  Do the exercises (when you feel like doing them)
&lt;/h1&gt;

&lt;p&gt;The author stresses out multiple times that readers should open an editor and try running or writing the code themselves. The code examples in the text are written in Python but JS being my language I have tried to write some of the algorithms myself. &lt;/p&gt;

&lt;p&gt;I do agree that having the code in your hands helps but as I don't usually like to read sitting by the desk I've tried out only a few of the samples and whenever I felt that I don't need to see it on the screen I just skipped and understood it anyway (hopefully).&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;I haven't really talked about the drawings in the book. This wasn't really a selling point for me because I don't have this type of memory and I'm quite used to learn from textbooks but I can see that it may be an important thing for a lots of readers - so simply put the illustrations are well made, comprehensive and funny.&lt;/p&gt;

&lt;p&gt;I really recommend to get a copy of this book and keep it close by to be able to reference it when needed. It helped me a lot to feel comfortable about another theoretical aspect of the programming.&lt;/p&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;This is my first ever article published here and also the first text I have written on a technical topic, so I hope you've found it helpful and enjoyed reading it.&lt;/p&gt;

</description>
      <category>algorithms</category>
      <category>datastructures</category>
      <category>books</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
