<?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>Forem: Lina Jelinčić</title>
    <description>The latest articles on Forem by Lina Jelinčić (@linajelincic).</description>
    <link>https://forem.com/linajelincic</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%2F605316%2F8e6c8f02-00a3-40cf-a3d5-c5a778082587.jpeg</url>
      <title>Forem: Lina Jelinčić</title>
      <link>https://forem.com/linajelincic</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/linajelincic"/>
    <language>en</language>
    <item>
      <title>How I switched from PHP to Node.js</title>
      <dc:creator>Lina Jelinčić</dc:creator>
      <pubDate>Mon, 10 Jan 2022 14:00:57 +0000</pubDate>
      <link>https://forem.com/bornfightcompany/how-i-switched-from-php-to-nodejs-2bhf</link>
      <guid>https://forem.com/bornfightcompany/how-i-switched-from-php-to-nodejs-2bhf</guid>
      <description>&lt;p&gt;I've been a PHP developer for a couple of years now and I love PHP. However, I believe that learning other programming languages can only make you a better developer. That is why I decided to tackle the fun new world of Node.js. (note: maybe not so new, but bear with me, I am a PHP developer after all)&lt;/p&gt;

&lt;p&gt;After my first 'node.js for beginners courses' google search, I realized I'm missing some basics and that there is a lot that I'll have to tackle. There are millions of tutorials out there and it all can be a bit overwhelming when you're starting to learn something new.&lt;/p&gt;

&lt;p&gt;I wanted this to be as simple as possible so I picked my favorite for each 'category'. &lt;/p&gt;

&lt;h3&gt;
  
  
  JavaScript
&lt;/h3&gt;

&lt;p&gt;Node.js is a JavaScript runtime. If you don't know what runtime is at the moment, just ignore it for a while.&lt;/p&gt;

&lt;p&gt;Node.js is JavaScript [insert something]. That means you'll have to learn JavaScript.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript"&gt;Learn JavaScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This was a documentation that proved as the most useful to me. It covers the basics as well as some advanced concepts. I had a hard time switching to async and in my opinion this documentation explains it so that you can sufficiently understand how JavaScript utilizes asynchronous programming.&lt;/p&gt;

&lt;h3&gt;
  
  
  TypeScript
&lt;/h3&gt;

&lt;p&gt;Use TypeScript. I won't even explain why, just use it. TypeScript is JavaScript with some added functionalities (like, you've guessed it, types). &lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/intro.html"&gt;Learn TypeScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Official docs are concise and they should give you an idea what are the differences between using TypeScript to JavaScript. But like I said, it's actually JavaScript so while learning JavaScript you're also learning TypeScript.&lt;/p&gt;

&lt;h3&gt;
  
  
  Node.js
&lt;/h3&gt;

&lt;p&gt;And finally, we are here :) Now you'll learn what is a runtime or V8 and what Node.js actually is.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://nodejs.dev/learn/introduction-to-nodejs"&gt;Learn Node.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;These are official docs and they are great. While you can find a lot of free or paid courses on the internet I really think these docs should be more than enough to understand what can be done with Node.js. &lt;/p&gt;

&lt;h3&gt;
  
  
  Extra
&lt;/h3&gt;

&lt;p&gt;Learn a Node.js framework! I've had the opportunity to work with Nest.js and I really liked it. Lots of people use Express.js so that is another possibility. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.nestjs.com/"&gt;Learn Nest.js&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nest.js also has great official docs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Keep in mind
&lt;/h3&gt;

&lt;p&gt;While writing this article I realized most of my favorites are official docs. Maybe that is something we all should remember: taking courses is great, there are a bunch of helpful resources and people out there and we should take advantage of it. However, when learning something completely new, stick to the basics and RTFM. &lt;/p&gt;

&lt;p&gt;If you are wondering what to do next, do something that excites you with your new set of skills! If you can't come up with an idea for a personal project, google 'project ideas for backend'. Find something that sounds interesting and happy coding :) &lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>programming</category>
      <category>engineeringmonday</category>
    </item>
    <item>
      <title>Background jobs with Symfony messenger component</title>
      <dc:creator>Lina Jelinčić</dc:creator>
      <pubDate>Mon, 09 Aug 2021 11:47:50 +0000</pubDate>
      <link>https://forem.com/bornfightcompany/background-jobs-with-symfony-messenger-component-p63</link>
      <guid>https://forem.com/bornfightcompany/background-jobs-with-symfony-messenger-component-p63</guid>
      <description>&lt;p&gt;Let’s say your client comes up with this request: whenever an image is uploaded, do something with it. Change background color, convert it to some other format, add watermark… Whatever it is, image processing is often a slow process that will add significant time to your ‘upload image’ action.   &lt;/p&gt;

&lt;h3&gt;
  
  
  Do it later
&lt;/h3&gt;

&lt;p&gt;But, if you were to think about it, there is no reason why it should be executed during the request. The user doesn’t really care about that. He will upload the image, continue with his day and image processing will be done somewhere.. in the background.  &lt;/p&gt;

&lt;p&gt;Flow of any background job looks like this: &lt;strong&gt;create job&lt;/strong&gt; + &lt;strong&gt;store necessary data somewhere so it can be executed later&lt;/strong&gt; + &lt;strong&gt;execute it  &lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symfony messenger&lt;/strong&gt; component, introduced in version 4.1, handles this for you!  &lt;/p&gt;

&lt;h3&gt;
  
  
  Create job
&lt;/h3&gt;

&lt;p&gt;Think about the data necessary for job execution. In this case, we should remember some kind of identifier that will let us fetch the image later on. Depending on your requirements, it can be id of an entity stored in the database, path to the image or something else.&lt;/p&gt;

&lt;p&gt;In the Message folder of your project, create a class that will encapsulate that data (and do nothing else).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SetBackgroundColorToBlack&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * @var string
     */&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$imageIdentifier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

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

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getImageIdentifier&lt;/span&gt;&lt;span class="p"&gt;():&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;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;imageIdentifier&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inject MessageBusInterface into a service that handles image uploading. After the image is uploaded, create your message and dispatch it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt; &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;MessageBusInterface&lt;/span&gt; &lt;span class="nv"&gt;$messageBus&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;messageBus&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$messageBus&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

 &lt;span class="nv"&gt;$message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SetBackgroundColorToBlack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getIdentifier&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
 &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;messageBus&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congrats! You've just told symfony... well, nothing much. &lt;/p&gt;

&lt;h3&gt;
  
  
  Where do all the messages go to?
&lt;/h3&gt;

&lt;p&gt;You've created your message and dispatched it. What now? Store it somewhere so the class that knows how to handle it can pick it. &lt;/p&gt;

&lt;p&gt;In this case, it's called transport. Symfony provides multiple transport options as well as retry strategies, so read the docs and decide what's best for your case. I used doctrine transport that won't be suitable for large projects.&lt;/p&gt;

&lt;p&gt;Two transports are defined: async, that handles messages of SetBackgroundColorToBlack type and failure transport.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;framework&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;messenger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;failure_transport&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;failed&lt;/span&gt;
        &lt;span class="na"&gt;transports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;dsn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;%env(MESSENGER_TRANSPORT_DSN)%'&lt;/span&gt;
            &lt;span class="na"&gt;failed&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
                &lt;span class="na"&gt;dsn&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;doctrine://default?queue_name=failed'&lt;/span&gt;

        &lt;span class="na"&gt;routing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;App\Message\SetBackgroundColorToBlack'&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;async&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's best to define your transports as env variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;###&amp;gt; symfony/messenger ###
MESSENGER_TRANSPORT_DSN=doctrine://default
###&amp;lt; symfony/messenger ###
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Do the job
&lt;/h3&gt;

&lt;p&gt;Someone should do the job. In MessageHandler directory of your project, create class SetBackgroundColorToBlackHandler.&lt;/p&gt;

&lt;p&gt;This class &lt;strong&gt;must&lt;/strong&gt; implement &lt;strong&gt;MessageHandlerInterface&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SetBackgroundColorToBlackHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;MessageHandlerInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="cd"&gt;/**
     * @var ImageProcessingService
     */&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$imageProcessingService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="cd"&gt;/**
     * @var ImageRepository
     */&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$imageRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;ImageProcessingService&lt;/span&gt; &lt;span class="nv"&gt;$imageProcessingService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
&lt;span class="kt"&gt;ImageRepository&lt;/span&gt; &lt;span class="nv"&gt;$imageRepository&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;imageProcessingService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$imageProcessingService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;imageRepository&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$imageRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SetBackgroundColorToBlack&lt;/span&gt; &lt;span class="nv"&gt;$setBackgroundColorToBlack&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$image&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;imageRepository&lt;/span&gt;
                 &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$setBackgroundColorToBlack&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getImageIdentifier&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;imageProcessingService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;setBackgroundColorToBlack&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$image&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Symfony is smart enough to connect message to the handler. It's enough to type hint variable of __invoke() method signature in the handler class.&lt;/li&gt;
&lt;li&gt;Handlers are services which means that you can inject other services.
&lt;/li&gt;
&lt;li&gt;Maybe the image can't be fetched because someone deleted it in the meantime. Depending on your domain, maybe the image must exist and you want to throw an exception in that case.&lt;/li&gt;
&lt;li&gt;Maybe imageProcessingService throws exception (it probably does). Remember we defined failure transport? By default, all messages will be retried 3 times before they end up in failure transport.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Work, work, work, work, work
&lt;/h3&gt;

&lt;p&gt;Define worker that is gonna consume those messages.&lt;br&gt;
&lt;code&gt;php bin/console messenger:consume async&lt;/code&gt;  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install supervisor on production that will watch out for your workers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;How do you like symfony messenger component? What do you use to handle background jobs? Do you think they are necessary in the first place?&lt;/p&gt;

</description>
      <category>engineeringmonday</category>
      <category>php</category>
      <category>symfony</category>
    </item>
    <item>
      <title>You ain't gonna need it</title>
      <dc:creator>Lina Jelinčić</dc:creator>
      <pubDate>Mon, 29 Mar 2021 11:42:06 +0000</pubDate>
      <link>https://forem.com/bornfightcompany/you-ain-t-gonna-need-it-517j</link>
      <guid>https://forem.com/bornfightcompany/you-ain-t-gonna-need-it-517j</guid>
      <description>&lt;p&gt;I love coming back to a feature that was developed a couple of months ago and seeing that extending it is just a walk in a park. When thinking about a solution, I always ask myself the same question: If I were to change this in a month, how hard would it be?&lt;/p&gt;

&lt;p&gt;I find it a great way to catch flaws in my solutions very early, but it can also lead to something called &lt;strong&gt;overengineering&lt;/strong&gt;. To put it simple, overengineering is the act of solving a problem that doesn’t exist anywhere besides your mind. &lt;/p&gt;

&lt;h3&gt;
  
  
  Overengineering leads to bad code
&lt;/h3&gt;

&lt;p&gt;It took me a long time to realize that even though my code is nice, clean and easy to extend, it is still a &lt;strong&gt;bad&lt;/strong&gt; code. It often introduces unnecessary complexity, being harder to maintain and harder to understand by other devs, while taking a longer time to build.&lt;/p&gt;

&lt;p&gt;None of it is a bad thing by itself. If you were to code just to get it done, you can get by, but in a month all you would get is messy, spaghetti code that nobody wants to work with in the future. It becomes a bad thing when that price is paid for a feature that you really don’t need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do you actually need it?
&lt;/h3&gt;

&lt;p&gt;I’m still fighting this battle myself and the thing that is helping me is a principle of extreme programming (XP) called &lt;strong&gt;“You ain’t gonna need it”&lt;/strong&gt; (or simply, YAGNI). XP co-founder Ron Jeffries has written: "Always implement things when you actually need them, never when you just foresee that you need them.”&lt;/p&gt;

&lt;p&gt;Now, whenever I start overthinking and catch myself wondering “But what if X happens” I just stop and write down my what ifs. Also, I think about &lt;strong&gt;what would happen if that feature is not implemented&lt;/strong&gt;. Is the added complexity the price I’m willing to pay just now?&lt;/p&gt;

&lt;h3&gt;
  
  
  Making that call is not easy
&lt;/h3&gt;

&lt;p&gt;It is important to differ what is needed and what is not, even though it is difficult to do that. If that is a decision you are having problems with, ask your teammates. A fresh look at the problem is something that always helps. If for whatever reason that is not possible, go with a simpler solution. &lt;strong&gt;Keep the list of what ifs and if they actually happen, choose the more complex solution.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This approach helped me with decision making paralysis and I believe it also made me a better developer.&lt;/p&gt;

&lt;p&gt;How about you? Do you also sometimes overengineer? What are your tips and tricks for deciding what is needed and what is not?&lt;/p&gt;

</description>
      <category>engineeringmonday</category>
      <category>yagni</category>
      <category>codequality</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
