<?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: Patricio Ferraggi</title>
    <description>The latest articles on DEV Community by Patricio Ferraggi (@patferraggi).</description>
    <link>https://dev.to/patferraggi</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%2F257973%2F8ec7581b-807e-448d-8d3a-d69b7126fcaf.jpg</url>
      <title>DEV Community: Patricio Ferraggi</title>
      <link>https://dev.to/patferraggi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/patferraggi"/>
    <language>en</language>
    <item>
      <title>One week with Nest.js, is it good?</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Mon, 29 Mar 2021 18:39:15 +0000</pubDate>
      <link>https://dev.to/patferraggi/one-week-with-nest-js-is-it-good-5hgo</link>
      <guid>https://dev.to/patferraggi/one-week-with-nest-js-is-it-good-5hgo</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2021/mar/nestjs-esta-bueno/"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hey guys, how you been? me? I have been working a lot on a new project I am building with the help of a friend, I will not discuss the details here but you will probably hear me talk about it very soon. Today I want to speak about one of the technology selections I made for building this project.&lt;/p&gt;

&lt;p&gt;I wanted to build an API, using node, using TypeScript. I have heard a lot of great things from this backend framework called &lt;a href="https://nestjs.com/"&gt;Nest.js&lt;/a&gt; but I hadn't tried it myself. Now after a week of coding the API, having several endpoints, authenticating, connecting to a database, and stuff I will give you my honest review. But let's start from the beginning.&lt;/p&gt;


&lt;h2&gt;
  
  
  What is Nest.js?
&lt;/h2&gt;

&lt;p&gt;From the documentation itself we get this answer: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A progressive Node.js framework for building efficient, reliable, and scalable server-side applications.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That doesn't say much right? well in my own words, Nest.js is a Node.js framework built on top of &lt;a href="https://expressjs.com/"&gt;express.js&lt;/a&gt; and &lt;a href="https://www.typescriptlang.org/"&gt;TypeScript&lt;/a&gt; that comes with a strong opinion on how API's should be built. Since it is very opinionated it provides a structure, a CLI, and an almost infinite amount of tools that let you create professional APIs very very fast.&lt;/p&gt;

&lt;p&gt;I guess it would be like Django for Python or asp.net Core for C#.&lt;/p&gt;
&lt;h2&gt;
  
  
  What is it like?
&lt;/h2&gt;

&lt;p&gt;Well, as with most API frameworks, Nest.js defines endpoints through an entity called &lt;code&gt;Controller&lt;/code&gt;.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Get&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cats&lt;/span&gt;&lt;span class="dl"&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;CatsController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kr"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This action returns all cats&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;span class="nd"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;:id&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;Param&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This action returns one cat&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;p&gt;For me, coming from C#, to see this in the JavaScript is just a pleasure. But I guess it can be daunting for you noders out there, so let me explain all the goodies that are happening in the previous example.&lt;/p&gt;

&lt;p&gt;This &lt;code&gt;Controller&lt;/code&gt; will create 2 endpoints in the routes &lt;code&gt;{url}/cats&lt;/code&gt; and &lt;code&gt;{url}/cats/{id}&lt;/code&gt;, the id in the URL of the second endpoint will be automatically mapped to the id parameter in the method. &lt;br&gt;
These types of tags &lt;code&gt;@Get()&lt;/code&gt; are called decorators and there are a bunch of them, you can use them for defining the HTTP method, for getting properties, for defining authentication, basically whatever you feel like.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But where do you write your business logic? you might ask.&lt;/strong&gt; Well Nest.js got you covered, for that you will use an entity called &lt;code&gt;Service&lt;/code&gt;&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;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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Cat&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;./interfaces/cat.interface&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;CatsService&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;cats&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;)&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;cats&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cat&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Cat&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cats&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;Nothing too weird here, except, what is that &lt;code&gt;@Injectable&lt;/code&gt; decorator doing?. Nest.js comes with &lt;code&gt;Dependency Injection&lt;/code&gt; by default, this decorator defines which dependencies can be injected into other components through their constructors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This seems like is gonna generate a lot of code, is there an easy way to manage dependencies?&lt;/strong&gt; yes, there is. You can pack functionality together by using Modules, they are like Node Modules but in Nest.js you can hold controllers, services, and more inside one Module that represent a feature, then inject that entire module into others to be used there.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Module&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CatsController&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;./cats.controller&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;CatsService&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;./cats.service&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;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CatsController&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;CatsService&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;CatsModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;I don't see any mention of how to contact a database, is there something for that?&lt;/strong&gt;. Didn't I tell you that Nest.js is pretty opinionated? as such, it comes with a way of working with databases. Enters &lt;a href="https://typeorm.io/#/"&gt;TypeORM&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Instead of doing SQL queries manually, we use an Object Relational Model, for working with the database, we define database entities that later will be used for creating the tables on the application startup and use automatic &lt;code&gt;Repositories&lt;/code&gt; created based on our database model.&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PrimaryGeneratedColumn&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;typeorm&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;Entity&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;Cat&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;PrimaryGeneratedColumn&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Column&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Seems super complicated, who is it for?
&lt;/h2&gt;

&lt;p&gt;I would lie if I say that everyone who starts messing with Nest.js is going to be productive immediately. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Nest.js follows a pattern that is very Object-Oriented, which is not something we see very often in the JavaScript world.&lt;/li&gt;
&lt;li&gt;If you only know dynamically typed languages is gonna be hard doing a switch because of TypeScript.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the other hand, if you come from a language like C#, then TypeScript is gonna feel right at home(they were actually designed by the same guy). On top of that, you probably used a framework like asp.net Core so you know exactly what a &lt;code&gt;Controller&lt;/code&gt; is, you probably created a layered architecture and used the word &lt;code&gt;Service&lt;/code&gt; to define your business logic even before seeing a single line of Nest.js code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;But, I have never done any backend, can I take Nest.js as my first project?&lt;/strong&gt; It depends.&lt;/p&gt;

&lt;p&gt;Nest.js is gonna be easier for you if you come from Angular instead of React.&lt;/p&gt;

&lt;p&gt;The entire Module, Dependency Injection, Decorator architectural patterns that Nest.js uses is heavily inspired in Angular, they are like cousins, and if you come from Angular you will already know TypeScript so picking up Nest.js will be a no brainer.&lt;/p&gt;




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

&lt;p&gt;You probably know that I gonna say I really like Nest.js, well yeah, it seems like a great framework to create reliable node.js APIs. It provides tons of functionality out the box, and if you wanna do something special, their documentation is just outstanding. If you come from one of the backgrounds I mentioned previously or you just want to learn something new I would definitely recommend you to give Nest.js a try 🤞.&lt;/p&gt;

&lt;p&gt;As always, if you liked this post go ahead and share it, have you tried Nest.js? Do you want to know something specific? let me know below in the comments 😄&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>beginners</category>
      <category>codenewbie</category>
      <category>node</category>
    </item>
    <item>
      <title>New laptop, new OS. My adventure going Linux starts here.</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Wed, 24 Mar 2021 16:53:01 +0000</pubDate>
      <link>https://dev.to/patferraggi/new-laptop-new-os-my-adventure-going-linux-starts-here-4697</link>
      <guid>https://dev.to/patferraggi/new-laptop-new-os-my-adventure-going-linux-starts-here-4697</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2021/mar/linux-journey/" rel="noopener noreferrer"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For quite some time already I have been thinking about buying my own laptop, see, for the last 3 and a half years I have been using a Macbook Pro that belongs to my employer (well, my previous employer now). &lt;br&gt;
The computer worked fine, great performance, great screen, amazing trackpad(although terrible keyboard), Windows 10 worked great on parallels. But for quite some time I didn't felt comfortable with a number of things.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The computer was not mine. Someone had a saying on what I could and couldn't do with the computer.&lt;/li&gt;
&lt;li&gt;The operating system worked great when you didn't touch it too much, once you wanted to install an obscure toolset (hello haskell-language-server 👋) you were out of luck.&lt;/li&gt;
&lt;li&gt;I knew I would have to return my computer once I switched jobs, which made me incredibly annoyed about personalizing and installing stuff because I knew I would have to start from scratch.&lt;/li&gt;
&lt;li&gt;MacOS as most operating systems are not customizable, apart from the wallpaper, maybe a dark background and some tint and that's it. Being a guy who spent years trying custom ROMs on Android to the point of compiling its own, I can't stand this anymore.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, after considering my options and checking my savings account, I decided it was time to buy a laptop, my first one, all for myself, and install Linux once I got it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The search
&lt;/h2&gt;

&lt;p&gt;I actually spend months looking for the right laptop, I am a picky bastard so I was not gonna buy any Linux laptop. &lt;br&gt;
I have to say that coming from a MacBook pro the search was harder than I thought it would be. I might have hated on Apple in the previous paragraphs but the truth is that Apple makes killer products, probably not the best laptop in any specific category, but an overall compelling package. &lt;br&gt;
I only realized this once I started looking for a Win/Linux alternative.&lt;/p&gt;

&lt;p&gt;These are the things I wanted in order of importance:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;I7 or AMD Ryzen 7&lt;/li&gt;
&lt;li&gt;32GB RAM (on my MacBook pro I had 32GB and I did felt the difference when running my entire development setup)&lt;/li&gt;
&lt;li&gt;Good Linux support&lt;/li&gt;
&lt;li&gt;US English keyboard (I live in Belgium and it is super hard to find one, most Win10 laptops come with Belgian/French AZERTY 🤮 - Apple lets you pick whatever keyboard layout you want).&lt;/li&gt;
&lt;li&gt;&amp;gt;= 13.4 inches 2k+ 16:10 ratio screen(there is no going back from this)&lt;/li&gt;
&lt;li&gt;Full metal aluminum body (say whatever you want but Apple's build quality is awesome, except for the keyboard)&lt;/li&gt;
&lt;li&gt;Light enough for carrying around&lt;/li&gt;
&lt;li&gt;Nice keyboard, big trackpad&lt;/li&gt;
&lt;li&gt;Good looking&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After months of searching, I came with only two options that would more or less match these requirements.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://www.ubergizmo.com/2021/01/lenovo-yoga-slim-7i-pro-ces-2021/" rel="noopener noreferrer"&gt;The Lenovo Yoga Slim 7i Pro&lt;/a&gt; and the &lt;a href="https://www.dell.com/en-us/shop/dell-laptops/new-xps-13-laptop/spd/xps-13-9310-laptop" rel="noopener noreferrer"&gt;Dell XPS 9310&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes, I know you are gonna recommend me another laptop, like a Thinkpad? the Yoga Slim 7Pro with AMD? maybe the Razr book? the Slimbook 14? I have looked at them all and if you consider all the things in the list you will notice that all other laptops fail to check something.&lt;/p&gt;

&lt;h2&gt;
  
  
  The winner is...
&lt;/h2&gt;

&lt;p&gt;This journey started around June 2020, by December I was still laptopless. I was stuck in a loop of researching and waiting for a new model to come out or some obscure provider to offer what I was looking for and could be delivered to Belgium. Finally, after some refreshing holidays, I decided to not wait anymore and I bought my Dell XPS 9310 i7 32GB 4k 1TB NVME. It's perfect, right?&lt;/p&gt;

&lt;p&gt;Not so fast, there are things I wished were different, for instance, 4k is too much, 2/3k would have been perfect for a laptop this size. The 32GB model comes with some problems on Linux that I will explain later. I don't really like the carbon fiber that Dell uses inside, I would prefer if it would just stick with all-metal, it took Dell a month to deliver it.&lt;/p&gt;

&lt;p&gt;But, those are minor complaints. The laptop is providing me with some happy moments that I would like to share with you.&lt;/p&gt;

&lt;p&gt;After receiving my laptop I went for dual-booting Windows 10 and Ubuntu 20.04.&lt;br&gt;
Hey if you wanna go Linux why not go Arch? or Arco? or Manjaro? or PopOS?. Well, again, the laptop is not perfect.&lt;/p&gt;

&lt;p&gt;Before buying it I knew that the 32GB model was a little different from the officially supported Linux Developer Edition 16GB model. Only God knows why but Dell had the brilliant idea to use another Wireless card for the 32GB model. Instead of going for the old and fully supported AX201 or the AX1650, Dell decided to include the AX500-DBS which when the laptop was released was not yet included in the Linux Kernel. I knew that there was some work being done to include it so I went ahead and bought it anyway.&lt;/p&gt;

&lt;p&gt;The driver is now included and few distros are merging the changes both to the Linux kernel and the &lt;code&gt;linux-firmware&lt;/code&gt; package. I tried many distros and so far I have only achieved fully working WiFi and Bluetooth on Ubuntu 20.04, not even on 20.10. &lt;/p&gt;

&lt;p&gt;That was quite an experience already, a front kick in the teeth of what is to live under Linux, multiple formats, distro switches, USB tethering network, kernels, firmware, heathers, you name it. After settling down with a working build, this is my current setup:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjj6a3k1y5uosbjntz5ce.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjj6a3k1y5uosbjntz5ce.png" alt="Linux desktop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvb7mdg5nlbz31r1l38e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmvb7mdg5nlbz31r1l38e.png" alt="Linux tiling"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 20.04&lt;/li&gt;
&lt;li&gt;Dracula Theme: GTK, GnomeShell, Vscode, GnomeTerminal, Chrome.&lt;/li&gt;
&lt;li&gt;PopOS Shell (tiling and app searcher)&lt;/li&gt;
&lt;li&gt;Removed activities shortcut&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  The outside also counts
&lt;/h1&gt;

&lt;p&gt;One of the things that I hated about switching laptops was that I used a lot of really cool stickers on my work laptop (like a fool). &lt;br&gt;
Sounds stupid but to me, that was kind of a big deal. Luckily, I kept duplicates of/managed to remove the stickers that I treasure the most (a few from conferences and meetups in my home country that I will not be able to get again).&lt;/p&gt;

&lt;p&gt;Here is a picture of the old laptop:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbyup38df0p15cxs87cwi.jpg" 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%2Fbyup38df0p15cxs87cwi.jpg" alt="Old laptop"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this is my new baby:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5r3urnt5tydcm5u68d9c.jpg" 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%2F5r3urnt5tydcm5u68d9c.jpg" alt="My baby"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am really loving that new look, I have one of &lt;a href="https://en.wikipedia.org/wiki/Tux_%28mascot%29" rel="noopener noreferrer"&gt;TUX&lt;/a&gt; saved up for the center of the laptop and I am just waiting for conferences to get the rest.&lt;/p&gt;




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

&lt;p&gt;After all that struggling you must be thinking, wow this guy is really regretting his decision. Well not at all, the computer is mine. I gain the freedom of doing whatever I want with it and having a pretty nice development setup that I can bring with me everywhere. The possibilities for having an environment that makes me happy to use every day are simply tied to my interesting in learning more about the operating system.&lt;/p&gt;

&lt;p&gt;I will continue exploring and tweaking, this computer will be with me for years to come and this journey has only started.&lt;/p&gt;

&lt;p&gt;I hope you liked this post, if you did please or you want to tell me your own story please do it in the comments. And don't forget to share it 😄&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>linux</category>
      <category>codenewbie</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Optimize for learning</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Mon, 01 Mar 2021 19:30:19 +0000</pubDate>
      <link>https://dev.to/patferraggi/optimize-for-learning-303p</link>
      <guid>https://dev.to/patferraggi/optimize-for-learning-303p</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2021/mar/optimizar-para-el-aprendizaje/"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Last week I finished this great book that we started reading at work for our book club, it is called &lt;a href="https://www.amazon.com/Effective-Engineer-Engineering-Disproportionate-Meaningful/dp/0996128107"&gt;"The effective engineer"&lt;/a&gt;, if you haven't read it then you should definitely consider it. &lt;/p&gt;

&lt;p&gt;The book has tons of good takeaways but one that really resonated with me was the concept of optimizing for learning. The idea of prioritizing learning over all other matters, so let's dive a little into the subject, shall we?&lt;/p&gt;




&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As you may already know if you follow my blog is that I am a big proponent of taking care of your career, the things that you learn, and how you direct your personal development. &lt;/p&gt;

&lt;p&gt;The author of the book goes even to say that you should devote 20% of your time to learning, but &lt;strong&gt;what does optimizing for learning really mean? it means picking, between a set of defined paths, the one that will teach you the most&lt;/strong&gt;. Learning is an investment that pays up in the long run but it is something you should always focus on.&lt;/p&gt;

&lt;p&gt;Up until reading this book, I considered this idea as both necessary to succeed in the software development industry and as a fun way to spend your free time. &lt;/p&gt;

&lt;p&gt;But there are a few things I didn't consider while following this path, these are: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many places there are for optimization&lt;/li&gt;
&lt;li&gt;How your growth can be directed to others&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Optimizing on multiple fronts
&lt;/h2&gt;

&lt;p&gt;There are some pre-established ways of learning, we all know them right? I am talking about going to school, taking courses, reading a book, learning a new programming language, doing an online tutorial.&lt;/p&gt;

&lt;p&gt;These ones are the first that come to my mind when I read about always keep learning, but there a few things that caught me of the guard.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pick the right job
&lt;/h3&gt;

&lt;p&gt;Throughout my career in software development, I have always focused on picking the next job that would drive my skills to the next level, at first it was unconscious.&lt;/p&gt;

&lt;p&gt;After a year and a half at the same job, I would get bored, when that happened a lot of things started bothering me and I would end up changing to a new and exciting role. It took me a few positions to actually realize that the problem was that after that time I would stop learning, my job would become repetitive, solving bugs on the same old systems. &lt;/p&gt;

&lt;p&gt;Now I always pick the next job for what I can learn from the company, the technologies, and especially the team. I want to work in systems that show me something I have never seen before, I want to work with people that are smarter/more experienced than myself. If I am the dumbest in the group, I will be happy, because that means there is a lot of potential for learning.&lt;/p&gt;

&lt;p&gt;Don't get me wrong, I am not saying you should pick a job that doesn't pay you enough to live in order to learn something new, but once basic needs are met, knowledge is always a better payment than some extra bucks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't avoid hard punches
&lt;/h3&gt;

&lt;p&gt;Do you know what is the best way to learn? by failing, by getting critiqued, by someone calling out your mistakes. &lt;/p&gt;

&lt;p&gt;When that happens, you don't quit, you don't complain, you listen. Is there something essential to be learned here? by now you already picked a job with a lot of very knowledgeable people so why don't take advantage of that fact?&lt;/p&gt;

&lt;p&gt;I was surprised to the extent where you can take this rule. You have two developers in your team, one doesn't pay much attention when doing code reviews and the other one is deadly on the comment thread, which one do you pick? You pick the stronger opponent of course, once you get punched in the face a  few times you will learn how to avoid that mean left hook.&lt;/p&gt;

&lt;p&gt;The same applies to when someone offers you a new piece of code you don't understand or the possibility to take on a project, don't hesitate, jump fearlessly into new code, dive in and try to learn as much as you can.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are you a one-person team?
&lt;/h2&gt;

&lt;p&gt;First of all, that is a bad idea, one-person teams mean you don't get questioned on your decisions, and you don't get to see your blind spots. &lt;/p&gt;

&lt;p&gt;So let's assume you already figured that out and you are part of a team that includes multiple developers, a product owner, a QA, and even a designer.&lt;/p&gt;

&lt;p&gt;How much progress can you make if you are only interested in yourself?. Usually, when I speak about self-improvement I forget to mention that improvement permeates around you and affects others close to you. Helping others is a great way of generating exponential growth.&lt;/p&gt;

&lt;p&gt;Could be pair-programming with another developer, mentoring a new guy joining the team, or as we did at my current job, reading a book as a team and discussing it.&lt;/p&gt;

&lt;p&gt;It doesn't have to be work-related, it could be writing stuff in a blog post like I am doing now, I hope it helps others, and at the same time, it helps me solidify my knowledge and clear my head after a long day of work.&lt;/p&gt;

&lt;p&gt;Sometimes bringing your A game is not enough if the rest of the team is struggling, be a team player, not a star.&lt;/p&gt;




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

&lt;p&gt;This was a short one, but I hope I can give you something to think about when you go on focusing on the next learning project or building that next feature, check for places where you haven't checked before, is there something there you could do that would give you an extra boost?&lt;/p&gt;

&lt;p&gt;I hope you liked this blog post, if you did please share it and tell me about it in the comments, if you didn't I would also like to hear about it, as I said, it is a great opportunity for learning 😄&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>motivation</category>
      <category>codenewbie</category>
      <category>career</category>
    </item>
    <item>
      <title>There are others like you out there</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Wed, 24 Feb 2021 19:43:48 +0000</pubDate>
      <link>https://dev.to/patferraggi/there-are-others-like-you-out-there-1jgb</link>
      <guid>https://dev.to/patferraggi/there-are-others-like-you-out-there-1jgb</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2021/feb/communities/" rel="noopener noreferrer"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;One of the things that took me a while to figure out, unfortunately, was that I was not alone out there. &lt;br&gt;
I was a programmer in the wild, walking around catching bugs, reading documentation, and developing geeky products, some of them that people actually liked, still I was feeling quite lonely.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4udgtcr7nnvhoioq4snz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4udgtcr7nnvhoioq4snz.png" alt="image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That changed for the better in the last year and a half, let me tell you why.&lt;/p&gt;




&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;I realized that there was a whole set of people like me, feeling weird when talking about software, some of you probably don't have a group of friends who share the same likes as you do. You share articles that no one cares or you get excited by new tech that any of them have ever heard of, or maybe you are just starting and need some extra guidance or help on some specific issue.&lt;/p&gt;

&lt;p&gt;Well let me tell you, YOU ARE NOT ALONE, there are tons of us out there that live this way, and luckily, there is a way to get to know each other, Dev Communities. The fact that you are reading this blog post here is already a good start, but it is just the beginning.&lt;/p&gt;

&lt;h2&gt;
  
  
  What type of communities?
&lt;/h2&gt;

&lt;p&gt;No, I am not talking about an old shack in the woods where everyone grows their own food and code open source projects, although that doesn't like a bad idea either 🤔.&lt;/p&gt;

&lt;p&gt;There are tons of places where you can meet other folks from the IT field, discuss, related, make relationships. &lt;/p&gt;

&lt;h3&gt;
  
  
  Meetups
&lt;/h3&gt;

&lt;p&gt;Before Corona was a thing I started going to meetups, you know, a few guys and girls seeing a talk, discussing frameworks, and eating pizza. Yes, my friend, that was THE good life, and we didn't know it until it was gone.&lt;/p&gt;

&lt;p&gt;The days of the in-person meetups have long passed, but that doesn't mean meetups are still not out there. The good old &lt;a href="https://www.meetup.com/" rel="noopener noreferrer"&gt;meetup website&lt;/a&gt; still works, a lot of meetups still function although in an online manner. Start small, pick your city and tech you really like.&lt;/p&gt;

&lt;p&gt;Me? I am originally from Buenos Aires, Argentina, and I wanted to relate more with people that knew JavaScript so my choice back then was &lt;a href="https://meetupjs.com.ar/" rel="noopener noreferrer"&gt;Meetup.js Buenos Aires&lt;/a&gt;. After 3 years, I placed another of their official stickers on my new laptop.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1repgy5efkfb74b3zhlf.jpg" 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%2F1repgy5efkfb74b3zhlf.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Maybe by checking my stickers you notice a pattern, &lt;a href="https://www.meetup.com/es-ES/fullstackantwerp/" rel="noopener noreferrer"&gt;Full Stack Antwerp&lt;/a&gt; sounds like a meetup, well it is. Everywhere I go, there will a new meetup to go and new people to meet.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conferences
&lt;/h3&gt;

&lt;p&gt;Conferences are harder to meet people, everyone is super busy rushing for the next talk that you usually don't get to talk to a lot of them, lunch though is a perfect opportunity to do so. &lt;/p&gt;

&lt;p&gt;I know, I know, there are no in-person conferences happening anywhere. Then maybe now is the correct time to assist some online conferences. Get the feeling of how they are and which kind of talks are presented there, do you think you can go to one when everything goes back to normal? now there are more free online conferences than ever, feel free to get your feet in the water without the risk of drowning.&lt;/p&gt;

&lt;p&gt;It is also a great opportunity to get to know, at least by name, the personalities in our industry, maybe a new tech, a new book, something you would miss otherwise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Online Slack and Discord communities
&lt;/h3&gt;

&lt;p&gt;Yeap, can't get more simple than that, a moderated chat where all developers can express their opinions and share their thoughts. I think this is actually the best place to make friends right now. &lt;/p&gt;

&lt;p&gt;A lot of podcasts and topics share their own slacks communities for English speakers. Some are &lt;a href="https://fpchat-invite.herokuapp.com/" rel="noopener noreferrer"&gt;Functional Programming Slack&lt;/a&gt; and &lt;a href="https://completedevelopernetwork.com/" rel="noopener noreferrer"&gt;The Complete Developer Network&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Last year I joined a Discord community for Spanish-speaking techies, if you been following me you probably already heard me mention them once or twice before. It is called &lt;a href="https://frontend.cafe/" rel="noopener noreferrer"&gt;frontendcafe&lt;/a&gt;, but don't let the name trick you, there is a lot more than frontend happening there. Backend, IT, Hardware, Frontend, Linux, English practice, Algorithms, Design, even some healthy habits group and a channel where you can join while working and listen to music (yeap, like a real coworking space).&lt;/p&gt;

&lt;p&gt;Joining this community has helped me meet some fantastic people. Expats like me, scattered around Europe, people from back home that we went together for pizza when I was visiting my parents(and so I could get a frontendcafe sticker of course).&lt;/p&gt;

&lt;p&gt;I have met people that I can talk about tech, about sports, about investing, writing, whatever tickles my brain really. In times like these where relationships are hard to come by, especially being in a different country, this has become priceless to me.&lt;/p&gt;

&lt;p&gt;Not only that but it has brought me a few opportunities that I never had thought I could get. Since I joined I:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I talked about my experience moving to a different country on a Twitch live stream.&lt;/li&gt;
&lt;li&gt;I gave a talk on learning and improving your career through self-mastery for an NGO in Argentina.&lt;/li&gt;
&lt;li&gt;I joined freeCodeCamp as a writer.&lt;/li&gt;
&lt;li&gt;I currently meet with developers that need an extra hand as part of a mentorship program twice a week.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Okay, you know people, what is your point?
&lt;/h2&gt;

&lt;p&gt;This might sound like bragging, but it is not. I am not an extroverted guy, I don't have many friends and I am usually scared of talking with other people outside of the virtual world, but being part of these online communities has helped me realize that there as a lot of folks like me out there, so I am using this as practice.&lt;/p&gt;

&lt;p&gt;Eventually, things will go back to a pre-covid state, and when that happens I will make sure to bring the things I learned while on lockdown to meet new people, and also to get to know all of you in person. You can't go wrong with 🍕, 🍻 and 💻.&lt;/p&gt;




&lt;p&gt;I hope you liked this blog post, if you did, don't forget to share it and tell me about it in the comments.&lt;br&gt;
If you didn't I would also like to hear your input, please do so in the comments, I answer each one of them 🙂&lt;/p&gt;

</description>
      <category>codenewbie</category>
      <category>beginners</category>
      <category>career</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Mistakes come for Juniors and Seniors alike</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Tue, 02 Feb 2021 21:19:13 +0000</pubDate>
      <link>https://dev.to/patferraggi/mistakes-come-for-juniors-and-seniors-alike-41de</link>
      <guid>https://dev.to/patferraggi/mistakes-come-for-juniors-and-seniors-alike-41de</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2021/feb/mistakes-everyone/"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When I first started my career as a software developer over 6 years ago, I was scared, scared about making a mistake, deleting something that I was not supposed to, making dumb code, or missing some important stuff while developing a feature. &lt;/p&gt;

&lt;p&gt;If you were expecting a story where I would tell how none of these things happened and everything was fine and you should not worry, this is not that type of story, there is not gonna be any happy unreal endings here.&lt;/p&gt;




&lt;h3&gt;
  
  
  Some mistakes I made so far
&lt;/h3&gt;

&lt;p&gt;I took my second job as a developer when I had less than a year of experience. On my first week, I successfully broke the production database as a consultant which caused that some employees of the client, and myself, had to stay during the weekend checking the reach of the damage I caused. I spent an entire Saturday fixing broken entries in other systems and restoring database backups. What was I exactly doing with production access on my first week, to this day I still don't know.&lt;/p&gt;

&lt;p&gt;For years I have written code that fails to do the job, produced bugs, and delivered the wrong things. Failing builds, broken environments, blocked other people's work, and delayed releases.&lt;/p&gt;

&lt;p&gt;In my third job (less than 2 years experience) I failed to release to production one feature we have been working on for months, when I finally got it to production it was riddled with bugs, some parts of the workflow were not usable at all.&lt;/p&gt;

&lt;p&gt;In my fourth job (around 3 years experience) I took on the assignment of building a microservice for a feature that our company needed to survive the following years. Although I was in charge of building it I was scared to fail so I left many decisions to someone more technically capable than me, someone with years and years of experience.&lt;br&gt;
Those decisions guided us through an insanely complicated implementation phase with tons of features that we didn't actually need and did nothing more than complicating the code and the deployment. Before I left that company I took care of "Refactoring" that service and heavily simplifying the number of things that it needed to do, the deployment went great and we were very happy with the implementation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Did I learned something?
&lt;/h3&gt;

&lt;p&gt;All these mistakes I made gave me some experiences that I will never forget, and I sure learned from those mistakes. I learned to check 20 times before deploying, I learned how to write unit tests and integration tests, how to smoke test on staging environments, how to make my code resilient so that failures in one feature don't bring the entire system down.&lt;/p&gt;

&lt;p&gt;I learned how to interact with the QA, I got some insights on how they test the product so I can do extra verifications before passing the problem to another person.&lt;/p&gt;

&lt;p&gt;I learned to take responsibility for the code I work on, take ownership for the mistakes and go the extra mile to fix them.&lt;/p&gt;

&lt;p&gt;I learned to question features and not just blindingly build a specification that has been drop to my feet, ask questions and try to solve problems instead of just being a coding monkey.&lt;/p&gt;

&lt;p&gt;It has also taught me what type of senior developer I want to be, do you want to be the guy who screams at the jr developer for making a mistake? (yes, this, unfortunately, does happen) or do you prefer to be the one that understands him and makes him grow? do you see a problem caused by a team member as his/her fault or as a problem caused by a process that WE as a team need to fix?&lt;/p&gt;

&lt;p&gt;Thanks to those mistakes, and the people that have helped me along the way I learned the type of developer I want to be:&lt;/p&gt;

&lt;p&gt;Someone who takes pride in their craft, someone who loves helping others and sees mistakes not as failures but as new opportunities to learn, someone who takes the deliberate care to make sure features are delivered in time with the appropriate quality.&lt;/p&gt;

&lt;h3&gt;
  
  
  You are a senior, now what?
&lt;/h3&gt;

&lt;p&gt;I would love to say that mistakes stop happening when you become a senior, unfortunately, that is not the case, they will never stop happening, the sword of Damocles will always be there hanging on top of your head. &lt;/p&gt;

&lt;p&gt;Even today I almost had a heart attack when for a moment I thought one of my local db scripts was running on the staging database instead of my local docker instance, all just on my second week in a new job.&lt;/p&gt;

&lt;p&gt;Nothing happened, I knew I had the proper configuration file pointing to my local instance, I was checking the database while the script run and took the appropriate measures to revert it if anything would have been wrong, but when I saw error logs on the staging channel let's say I doubted myself a little 😂. In the end, it was just that analytics for development and staging were thrown in the same channel, that is all.&lt;/p&gt;




&lt;p&gt;My point with this blog post is not to scare you, is to let you know that everyone makes mistakes, what differentiates developers is how they take those mistakes and what they do with the lessons learned.&lt;/p&gt;

&lt;p&gt;If you liked this blog post please share it and let me know below in the comments. What mistakes have you made in your career? I would love to hear them so we can laugh together.&lt;/p&gt;

</description>
      <category>career</category>
      <category>motivation</category>
      <category>codenewbie</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Planning my career development for 2021</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Tue, 19 Jan 2021 19:48:53 +0000</pubDate>
      <link>https://dev.to/patferraggi/planning-my-career-development-for-2021-52oo</link>
      <guid>https://dev.to/patferraggi/planning-my-career-development-for-2021-52oo</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish 🇪🇸, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2021/jan/planning/" rel="noopener noreferrer"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hey guys, 2021 is finally here!. It has been a hard year but now so it is time to plan everything again, to write down on paper what I want to learn or do this year.&lt;/p&gt;

&lt;p&gt;If you been following my blog posts for some time you will know that I am a big fan of setting goals, planning, tracking, and of course DOING. &lt;/p&gt;

&lt;p&gt;Last year I focused on too many things and while I accomplished quite a few of the things I proposed to myself, I also noticed the pressure of not reaching what I was expecting was pushing me back. This year I am gonna go a little lighter, in the number of things but not on the effort, let's call it just having a "better" direction.&lt;/p&gt;

&lt;p&gt;Let's start already, shall we?&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Be comfortable writing at least in one functional programming language
&lt;/h2&gt;

&lt;p&gt;Last year I spent quite a lot messing around, going from book to book, looking up languages, talking to people, doing small tests on different environments. For this year I have made the decision to focus on learning &lt;code&gt;Haskell&lt;/code&gt;, at least first. This is gonna be my initial curriculum:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read &lt;a href="https://www.goodreads.com/book/show/25587599-haskell-programming-from-first-principles" rel="noopener noreferrer"&gt;Haskell Book&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read a &lt;a href="https://atypeofprogramming.com/" rel="noopener noreferrer"&gt;Type of programming&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read &lt;a href="http://learnyouahaskell.com/" rel="noopener noreferrer"&gt;Learn you a Haskell for great good&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read &lt;a href="https://bartoszmilewski.com/2014/10/28/category-theory-for-programmers-the-preface/" rel="noopener noreferrer"&gt;Category Theory for programmers&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Do at least one big personal project with Haskell.&lt;/li&gt;
&lt;li&gt;Explore other languages like Elm, PureScript, F#, Clojure.&lt;/li&gt;
&lt;li&gt;Read &lt;a href="https://leanpub.com/fp-oo" rel="noopener noreferrer"&gt;Functional programming for the object-oriented programmer&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Re-Read &lt;a href="https://web.mit.edu/alexmv/6.037/sicp.pdf" rel="noopener noreferrer"&gt;Structure and interpretation of computer programs&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By separating a big goal into smaller concise tasks I don't need to worry about what to do next, I just follow the plan, if something is not going right I solve the issue and continue.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Get better at software architecture and computer science
&lt;/h2&gt;

&lt;p&gt;Last year I didn't focus on this at all, last year I had this idea that I wanted to learn more frontend, so I switched positions at my job and became a frontend developer. That taught me that I not really that interested in the frontend after all haha.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read &lt;a href="https://bigmachine.io/products/the-imposters-handbook/" rel="noopener noreferrer"&gt;The imposter’s handbook series&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read and study &lt;a href="https://www.amazon.com/-/es/Robert-C-Martin-ebook/dp/B075LRM681" rel="noopener noreferrer"&gt;Clean Architecture&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read and study &lt;a href="https://www.amazon.com/-/es/Eric-Evans/dp/0321125215" rel="noopener noreferrer"&gt;Domain Driven Design: Tackling Complexity in the heart of software&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Read and study &lt;a href="https://www.amazon.com/-/es/Vaughn-Vernon/dp/0321834577" rel="noopener noreferrer"&gt;Implementing Domain-Driven Design&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Take on a project at work where I can design a system from scratch.&lt;/li&gt;
&lt;li&gt;Create a personal project using the concepts learned, while diagraming the architecture.&lt;/li&gt;
&lt;li&gt;Participate in architecture discussions at my new position to learn about distributed systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I started the year with a new position, a new job as a Senior Software Developer in a place with some complex architectural decisions and a lot of cools systems to play with. I am gonna use this opportunity to learn as much as I can from my new team members and at the same time try to boost my own knowledge on the subject.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Get better at writing
&lt;/h2&gt;

&lt;p&gt;Last year I wrote a lot of blog posts, even a few that got me on the top of the list at awesome communities like CodeNewbie, but not nearly as much as I would like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fmvzufz2o2i5ka4ctzl2l.jpg" 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%2Fi%2Fmvzufz2o2i5ka4ctzl2l.jpg" alt="CodeNewbie 100k"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I started strong but in the end, the search for a new job, and my other goals got in the way. This year I am aiming to have fewer things to focus on, but do them with maximum effort!.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plan certain dates during the week where I am gonna write.&lt;/li&gt;
&lt;li&gt;Have a list of topics I can write about so I can just pick one from the pile when the time comes.&lt;/li&gt;
&lt;li&gt;Write at least 2 blog posts a week.&lt;/li&gt;
&lt;li&gt;Write about what I am learning to solidify knowledge.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  4. Improve my involvement with the community
&lt;/h2&gt;

&lt;p&gt;This year I joined a community called &lt;a href="https://frontend.cafe/" rel="noopener noreferrer"&gt;FrontendCafe&lt;/a&gt;, awesome people from Argentina and other countries of Latin America (and people from Spain too 😄 ). This year I want to continue meeting developers all over the world but I want to give special attention to people from the Spanish speaking community, specifically those who don't have the means to learn new things or that face some of the problems I faced when I was starting in this industry.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Give more mentorships at &lt;a href="https://frontend.cafe/" rel="noopener noreferrer"&gt;FrontendCafe&lt;/a&gt; and outside the Spanish speaking community.&lt;/li&gt;
&lt;li&gt;Spend more time helping new users and using my role as a Staff member in &lt;a href="https://frontend.cafe/" rel="noopener noreferrer"&gt;FrontendCafe&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Go to meetups (if they come back).&lt;/li&gt;
&lt;li&gt;Give a talk at a local meetup (if they come back).&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;As you may notice some of the things I already said in the planning of 2020 and that is perfectly fine. I didn't reach the level I want to achieve in many topics so this year I am gonna focus even more on those.&lt;br&gt;
Other topics have disappeared completely, that is fine too. After 2020 I learned a few lessons about myself, about what I like, and in which topics I want to invest more of my time on.&lt;/p&gt;

&lt;p&gt;I hope you like my planning for 2021, if so please share it and let me know below in the comments. Do you have a similar plan? I would like to read it, the comments is also the perfect place for that. &lt;/p&gt;

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

</description>
      <category>codenewbie</category>
      <category>career</category>
      <category>beginners</category>
      <category>motivation</category>
    </item>
    <item>
      <title>Learning from 2020</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Fri, 25 Dec 2020 15:04:45 +0000</pubDate>
      <link>https://dev.to/patferraggi/learning-from-2020-1mlb</link>
      <guid>https://dev.to/patferraggi/learning-from-2020-1mlb</guid>
      <description>&lt;p&gt;Hey guys how you been? it has been a while since my last post, a lot has happened in these few months since the last time I come here to share my life with you all and I bet you all have some stories to tell too.&lt;/p&gt;

&lt;p&gt;I usually write my articles both in Spanish and English but since I am on holidays and I don't have access to my own blog I will keep it just in English this time. Let's get to it.&lt;/p&gt;




&lt;p&gt;This pandemic has put my inner strength and motivation to the test. Before everything started I was eager to write, eager to exercise, eat well, and accomplish many things, but being stuck at home for so long has definitely put some mental strain on me.&lt;/p&gt;

&lt;p&gt;For the most part of the year, I did manage to accomplish some of my goals, I am still in shape (though I didn't make any substantial progress from my 2019 physique), I eat healthy (most of the times anyway), I am still learning functional programming focusing specifically on &lt;code&gt;Haskell&lt;/code&gt; and the best of all, I got a new job that is &lt;em&gt;mostly&lt;/em&gt; remote.&lt;/p&gt;

&lt;p&gt;On paper everything looks good right? what is this guy even complaining about? I am not. This year has put some of my beliefs to the test and I want to share them with you, let's take a walk.&lt;/p&gt;

&lt;h3&gt;
  
  
  There is no use in complaining.
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;There are two kinds of things in life, the things you can control and the things you can't control.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you can't control it then there is nothing you can do about it so there is no point in complaining. If, on the other hand, you can control it then why are you expecting someone else to solve your problems? get back to work, and fix them yourself.&lt;/p&gt;

&lt;p&gt;This maxim is something that I had to remember many times. I was stuck at home, there was no getting out, there was nothing under my control that I could do to make this pandemic go away. I had to remember that this was the time to keep composure, don't panic, focus, do the best you can with the hand you have been dealt. I focused on doing exercise at home most days of the week, I focused on applying to jobs and doing long technical interviews that would often take days.&lt;/p&gt;

&lt;h3&gt;
  
  
  Resting is available to all, at any moment
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Men seek retreats for themselves, houses in the country, sea-shores, and mountains. But it is in thy power whenever thou shalt choose to retire into thyself. For nowhere either with more quiet or more freedom from trouble does a man retire than into his own soul. Constantly then give to thyself this retreat, and renew thyself; and let thy principles be brief and fundamental, which, as soon as thou shalt recur to them, will be sufficient to cleanse the soul completely, and to send thee back free from all discontent with the things to which thou returnest.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It is up to us to give us a break, to retreat into our own consciousness to renew our energy and passion. I am building the habit of meditation, thinking about the world that surrounds me, and focus on the principles that guide my life, what do I want to achieve? how do I feel about my progress? is this necessary?. Things can and will go wrong, how I am gonna respond? Every morning I put everything to the test, and check if any of my assumptions could be wrong.&lt;/p&gt;

&lt;p&gt;At night, I review them, I keep a diary to review my actions for the present day, what did I do right? what did I do wrong? is there anything I could have done differently?&lt;/p&gt;

&lt;h3&gt;
  
  
  The obstacle is the way
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The impediment to action advances action. What stands in the way becomes the way.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This one is something that I need to remind myself every day, behind every problem, there is an opportunity in disguise. Sure, we are all stuck at home being forced to deal with our insecurities and having fewer opportunities to clear our heads as we would usually do without the pandemic, but is there something to gain from this? &lt;/p&gt;

&lt;p&gt;Maybe it is time to gain a new habit, something you can do at home every morning before getting to work. &lt;br&gt;
Or you could use this time to be more kind and understanding with your wife, she could be facing this situation in a completely different way.&lt;br&gt;
Remember your investments? markets are crashing, now is probably a good time to remind yourself that acting on panic is never a good investment.&lt;/p&gt;

&lt;p&gt;Every situation can teach us something, even if it is only to exercise temperance or compassion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Don't be so hard with yourself
&lt;/h3&gt;

&lt;p&gt;The human condition revolves around a few steps:&lt;br&gt;
You are born, a lot of things happen to you, you die.&lt;/p&gt;

&lt;p&gt;There is not much to it, it has always been like that and it will remain the same until the last breath of humanity disappears from the earth. &lt;/p&gt;

&lt;p&gt;I am not being tragic, I am not being pessimistic, on the contrary, everything that happens to you has already happened to someone before, it is part of nature, it will soon pass and it will soon be forgotten. Don't be angry, don't waste your time arguing with others or yourself, focus on the thing right in front of you. You will fail many times as many have failed before you. It doesn't matter, the only thing that is important is to remember that your time is precious, the sword of Damocles is hanging on top of your head, use your time wisely, guide your actions and forget about the results; keep pushing forward.&lt;/p&gt;




&lt;p&gt;This was a short post, I need to get back to writing so I didn't want to push it too hard. I hope you like reading it, if you did please share it in the comments and let me know if there is something else this 2020 has taught you. &lt;/p&gt;

&lt;p&gt;If you prefer my technical posts, don't worry, when I get from holidays I will get back to that, believe me, I am missing coding every day.&lt;/p&gt;

</description>
      <category>motivation</category>
      <category>career</category>
      <category>beginners</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Happy Developer Birthday to me!</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Thu, 08 Oct 2020 19:25:52 +0000</pubDate>
      <link>https://dev.to/patferraggi/happy-developer-birthday-to-me-3fnk</link>
      <guid>https://dev.to/patferraggi/happy-developer-birthday-to-me-3fnk</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish 🇪🇸, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2020/oct/happy-birthday-me/"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the 8th of October of 2014 something incredible happened, something that would change my life forever. 6 years ago I started writing code. &lt;br&gt;
Back then I was a 25 years old Economics student working at a bank, instead, I decided to switch to a Software Engineering major and quit my job to attend a one-month Bootcamp give by &lt;code&gt;Accenture&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I had written my first line of code a few months earlier. It was a basic &lt;code&gt;Hello World&lt;/code&gt; written in C, but on that day everything changed, I started learning to program daily, I had focus and intention to become a software developer. It was that day that I found my true calling in life, I noticed that I could do this forever and never get bored. So far this statement has survived the pass of time.&lt;/p&gt;

&lt;p&gt;A little over a month later I was starting a job as a trainee/jr software developer while I was still trying to understand the concepts I read in &lt;a href="https://csharpindepth.com/"&gt;C# in depth from Jon Skeet&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Changed?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  On my career
&lt;/h3&gt;

&lt;p&gt;In these years a lot of things have changed, I had 4 jobs as C# Developer while at the same time contributing to the frontend by learning HTML + CSS + Javascript, then moving over to Angular.js and eventually to Angular. Currently, I work as a full-stack developer focusing on C# and Angular.&lt;/p&gt;

&lt;p&gt;Although I have had a few moments where I focused on other things apart from software development, learning has been a constant in this experience. This career has awakened something inside me that I never felt before, this burning fire and self attained drive to improve. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object-Oriented Programming&lt;/li&gt;
&lt;li&gt;Functional Programming&lt;/li&gt;
&lt;li&gt;Backend development&lt;/li&gt;
&lt;li&gt;Frontend development&lt;/li&gt;
&lt;li&gt;Category theory&lt;/li&gt;
&lt;li&gt;Computer Science&lt;/li&gt;
&lt;li&gt;Software architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I have been all over the place but never ceased to follow the learning process. Hopefully, it will never stop.&lt;/p&gt;

&lt;h3&gt;
  
  
  On my personal life
&lt;/h3&gt;

&lt;p&gt;This career has brought me some amazing people to my life, most of my friends happen to be professionals in one or another area of software development. &lt;/p&gt;

&lt;p&gt;Now I also have the possibility to use my experience to help others, I am a member of various software development communities and often give mentorship in my spare time.&lt;/p&gt;

&lt;p&gt;I grew up in Argentina, the situation there has always been hard. After a little less than 3 years working as a developer in Argentina, I decided to find a job in Europe and moved. Thanks to this career I was able to drastically improve my quality of life, visit countries I had only seen in my dreams, and provide a better life for my wife.&lt;/p&gt;




&lt;p&gt;I know my career is just starting, 6 years probably seems like nothing to the old-timers in the industry. It has been quite a path, one that I pretend to walk until my last day, I can't wait to see what the future will bring and what I will learn tomorrow.&lt;/p&gt;

</description>
      <category>career</category>
      <category>motivation</category>
      <category>birthday</category>
      <category>devlive</category>
    </item>
    <item>
      <title>Do you need Design Patterns in Functional Programming?</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Sun, 06 Sep 2020 19:17:36 +0000</pubDate>
      <link>https://dev.to/patferraggi/do-you-need-design-patterns-in-functional-programming-370c</link>
      <guid>https://dev.to/patferraggi/do-you-need-design-patterns-in-functional-programming-370c</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish 🇪🇸, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2020/sep/design-patterns-fp/" rel="noopener noreferrer"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Since the ending of last year, I have been getting into Functional Programming(FP), I am still very bad at it. &lt;/p&gt;

&lt;p&gt;I find some concepts super hard to understand, things still feel very unnatural but throughout this process, I started noticing a few things we do regularly in Object-Oriented programming(OOP) that are a lot easier to implement in functional programming languages, they require less code and sometimes the implementation comes by default provided by the language itself. &lt;/p&gt;

&lt;p&gt;In a previous article, I talked about how the SOLID Principles apply to FP, you can read it &lt;a href="https://dev.to/patferraggi/do-the-solid-principles-apply-to-functional-programming-56lm"&gt;here&lt;/a&gt;, today I am gonna do a similar analysis but regarding Design Patterns, specifically some of the Design Patterns in the original &lt;a href="https://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional-ebook/dp/B000SEIBB8" rel="noopener noreferrer"&gt;GoF Book&lt;/a&gt;&lt;/p&gt;




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

&lt;p&gt;Let us start with the original definition: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The strategy pattern is a design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use.&lt;br&gt;
Strategy lets the algorithm vary independently from clients that use it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What does this look like? &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhhcos9l7sktc6t2irbs0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhhcos9l7sktc6t2irbs0.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In OOP languages this generally involves separate classes for each strategy which they all implement a common interface, then another class makes use of the strategy interface without actually knowing which strategy implementation has been selected at runtime, with this we separate the concerns of selecting the algorithm and the differences in implementation between strategies while having the possibility of selecting one or the other during runtime.&lt;/p&gt;

&lt;p&gt;In FP this pattern becomes extremely easy to implement and requires much less code, I am gonna use JavaScript but it can be equally easy to implement on full functional languages.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strategy1&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;run strategy 1&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;strategy2&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;run strategy 2&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;consumer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;runStrategy&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="cm"&gt;/*
  Do other stuff
  */&lt;/span&gt;

  &lt;span class="nf"&gt;runStrategy&lt;/span&gt;&lt;span class="p"&gt;();&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;selectedStrategy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;condition&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;strategy1&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;strategy2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;consumer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;selectedStrategy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;As you can see, in FP, the Strategy Pattern becomes just as simple as passing a function as a parameter. There is much less code involve because we don't have to depend on classes or inheritance to achieve the same functionality. &lt;/p&gt;

&lt;h3&gt;
  
  
  Factory Pattern
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The factory method pattern is a pattern that uses methods to deal with the problem of creating objects without having to specify the exact class of the object that will be created. This is done by creating objects by calling a factory method—either specified in an interface and implemented by child classes, or implemented in a base class and optionally overridden by derived classes—rather than by calling a constructor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In OOP languages this generally involves separate classes that encapsulate the business logic of creating objects and that can decide which object create during runtime. This often involves setting specific parameters on the created object depending on what we want to instantiate.&lt;/p&gt;

&lt;p&gt;In FP this pattern becomes extremely easy to implement:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;behavior1&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;do behavior 1&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;behavior2&lt;/span&gt; &lt;span class="o"&gt;=&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;do behavior 2&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;factory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&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="cm"&gt;/*
  Do other stuff
  */&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;condition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;behavior1&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;behavior2&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;As you can see, higher-order functions give us a simple solution again, instead of having behavior being defined by classes an inheritance, we just return a function that encapsulates the desired behavior or object.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decorator Pattern
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The decorator pattern is a design pattern that allows behavior to be added to an individual object, dynamically, without affecting the behavior of other objects from the same class. The decorator pattern is often useful for adhering to the Single Responsibility Principle, as it allows functionality to be divided between classes with unique areas of concern.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In OOP languages you wrap an object into another and provide extra functionality that the original one didn't have, without actually modifying its implementation, furthermore you can choose at runtime which functionality you need to add to the existing object.&lt;/p&gt;

&lt;p&gt;In FP this is achieved by &lt;code&gt;Composition&lt;/code&gt;, one of the core ideas of FP is to separate functionality into small functions that can be composed to form other behaviors, so instead of having a class you wrap around, you take small functions like &lt;code&gt;LEGO&lt;/code&gt; blocks and piece them all together to create new behavior. Let's see an example:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;compose&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(...&lt;/span&gt;&lt;span class="nx"&gt;fns&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;fns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduceRight &lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;isBiggerThanThree&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;mapBoolToHumanOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;yes&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no&lt;/span&gt;&lt;span class="dl"&gt;"&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;biggerThanThreeAndMapOutput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;compose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;mapBoolToHumanOutput&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isBiggerThanThree&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;biggerThanThreeAndMapOutput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;In this example, we define two functions that do one little thing and then compose them to generate new behavior, as long as composition apply we can keep adding more functionality to the mix 😄&lt;/p&gt;

&lt;h3&gt;
  
  
  Observer Pattern
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This pattern relies on the idea of Push vs Pull. Instead of having an object constantly checking if the state of another has changed, the second object notifies all others when its own state has changed.&lt;/p&gt;

&lt;p&gt;In FP this is a super used pattern in the form of Callbacks, Events, and Observers. They are also highly used in libraries like &lt;a href="https://rxjs.dev/" rel="noopener noreferrer"&gt;RX.js&lt;/a&gt; for &lt;code&gt;Reactive Functional Programming&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I am gonna refer to an answer to "What are Callbacks?" in Stack Overflow.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F27vh15dy6nnj2nvuy88v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F27vh15dy6nnj2nvuy88v.png" alt="Callbacks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Singleton Pattern
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;The singleton pattern is a software design pattern that restricts the instantiation of a class to one "single" instance. This is useful when exactly one object is needed to coordinate actions across the system. The term comes from the mathematical concept of a singleton.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In OOP languages this involves creating a static instance of an object to make it available everywhere without instantiation and making sure that if someone tries to instantiate it again, the previous instance is returned.&lt;/p&gt;

&lt;p&gt;In FP this pattern becomes completely unnecessary, there is no global state that needs to be exposed to the entire application since data is fully separated from functions. Also, all functions exist in a global namespace, are always accessible, they take input and produce a result without affecting the outside world.&lt;/p&gt;

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

&lt;p&gt;As you can see, it seems that some of the patterns that have evolved within the OOP world seem to give those languages the benefits that FP gets for free, without losing the things that characterize OOP like control over state and data. &lt;/p&gt;

&lt;p&gt;There are a few other patterns that I didn't mention because they fit into the solutions proposed by the previously mentioned examples.&lt;/p&gt;




&lt;p&gt;As I continue on my journey into functional programming I will probably find more examples and cases that will fit this assumption of mine. If you liked this article please let me know in the comments so I will keep bringing them in.&lt;/p&gt;

&lt;p&gt;Don't forget to share it 😄&lt;/p&gt;

</description>
      <category>functional</category>
      <category>webdev</category>
      <category>oop</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Building a microservice with C#, .NET Core and MongoDB - Part 1</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Tue, 25 Aug 2020 20:47:52 +0000</pubDate>
      <link>https://dev.to/patferraggi/building-a-microservice-with-c-net-core-and-mongodb-part-1-28ca</link>
      <guid>https://dev.to/patferraggi/building-a-microservice-with-c-net-core-and-mongodb-part-1-28ca</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish 🇪🇸, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2020/aug/csharp-mongo/"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hey guys! how have you been? In the latest weeks, I have been on going some interview process for C# Developer positions.&lt;/p&gt;

&lt;p&gt;I work with asp.net core every day which means that when I am at home I don't pick C# as my training language. So the C# code I have in my Github is fairly old and belongs to the early years of my career.&lt;/p&gt;

&lt;p&gt;So I decided to use the coding challenges that employers are giving me to create some newer C# code for my Github and at the same time create a nice guide that you can follow to improve your personal development.&lt;/p&gt;


&lt;h2&gt;
  
  
  What to expect from this tutorial?
&lt;/h2&gt;

&lt;p&gt;At the end of the series, we will have a microservice with the following characteristics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integrated to &lt;code&gt;MongoDB&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Layered architecture with clear separation of concerns&lt;/li&gt;
&lt;li&gt;API documentation&lt;/li&gt;
&lt;li&gt;Docker support for deployment&lt;/li&gt;
&lt;li&gt;Unit tested&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;We have a small business, we sell 💻. Every time a new computer is sold we need to record the order with the amount and client who bought it.&lt;/p&gt;

&lt;p&gt;We are gonna create a small microservice that connects to a &lt;a href="https://www.mongodb.com/"&gt;MongoDB&lt;/a&gt; and allows us to create/read/update/delete orders and also get some extra computation about users spending.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;Order&lt;/code&gt; model will be the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"guid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"guid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"int"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic Definition
&lt;/h2&gt;

&lt;p&gt;We start by creating an ASP.NET Core 3.1 Web Application with the API template and enabled Docker support in Visual Studio 2019.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eoJPKqnt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0sldfc9i411ztnje7t6c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eoJPKqnt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/0sldfc9i411ztnje7t6c.png" alt="ApplicationTemplate" width="880" height="610"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once that is created you will see a model and a controller for &lt;code&gt;WeatherForecast&lt;/code&gt; which is the default template way of showing you that there is an API out of the box.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ST9fQP-h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/20daydhqd7cjp13vhhg6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ST9fQP-h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/20daydhqd7cjp13vhhg6.png" alt="InitialStatus" width="880" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After we delete the default code we start by creating our model and a basic OrdersController. We are gonna start by the &lt;code&gt;Get and Post&lt;/code&gt; endpoints, that way we will be able to test adding and getting orders.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"v1/[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&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;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// Retrieves all orders&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;a list with all the orders available&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// Retrieves the order that matches the id supplied&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;one order model&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{orderId}"&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;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="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// Creates a new order&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;the newly created order&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;OrderCreateUpdate&lt;/span&gt; &lt;span class="n"&gt;orderRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;NotImplementedException&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;In the previous code, we create the &lt;code&gt;GetAll&lt;/code&gt;, &lt;code&gt;Get&lt;/code&gt; and &lt;code&gt;Post&lt;/code&gt; endpoints, we also include comments for the public API and we already versioned our API by using &lt;code&gt;v1/[controller]&lt;/code&gt; naming in the endpoints. If you are paying attention you might have noticed that the &lt;code&gt;Post&lt;/code&gt; has a model we haven't defined yet, &lt;code&gt;OrderCreateUpdate&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;When you are creating items in a database, you should not provide an &lt;code&gt;OrderId&lt;/code&gt;, since the order doesn't exist yet, then it is a good practice to separate the API model in two so they can change independently. This is the model for &lt;code&gt;OrderCreateUpdate&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"guid"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"amount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"int"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;UserId&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Amount&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Connecting to the Database
&lt;/h2&gt;

&lt;p&gt;For now, instead of creating a database or messing with docker from the start, we are gonna use an online database like the ones provided by &lt;a href="https://www.mongodb.com/try"&gt;MongoDBAtlas&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Back in the project, we need to find a way to configure the settings for connecting to our database, we do that by using the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-3.1"&gt;Options Pattern&lt;/a&gt;. We define the following configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersServiceOptions&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;DatabaseConnectionString&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;DatabaseName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;CollectionName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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;Now that we have our configuration ready we can move on to create our first &lt;a href="https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application"&gt;Repository&lt;/a&gt; that will have the responsibility of connecting to our &lt;code&gt;MongoDB&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;This is the code for our &lt;code&gt;OrdersRepository&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersRespository&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="n"&gt;IMongoDatabase&lt;/span&gt; &lt;span class="n"&gt;database&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="n"&gt;IMongoCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;collection&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="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrdersRespository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;OrdersRespository&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrdersProcessingServiceOptions&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;OrdersRespository&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&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;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;configuration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MongoClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseConnectionString&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="n"&gt;database&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DatabaseName&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="n"&gt;collection&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetCollection&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CollectionName&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="n"&gt;logger&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;logger&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;As you can see the &lt;code&gt;Repository&lt;/code&gt; creates the connection with the &lt;code&gt;MongoDB&lt;/code&gt; by using the configuration options we define previously, it also accepts a logger we are gonna use in our methods. Next, we are gonna create the methods we will use for getting and creating &lt;code&gt;Orders&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefaultAsync&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToListAsync&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&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="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;collection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertOneAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;order&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="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;null&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;The 3 methods are very simple, we get a single order by id, we get all orders and we create a new order (with the proper logging if the creation fails). After adding these methods we create an interface of this repository so we can start using the &lt;a href="https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-3.1"&gt;Dependency Injection&lt;/a&gt; that comes with &lt;strong&gt;.NET Core&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IOrdersRespository&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Connecting the pieces
&lt;/h2&gt;

&lt;p&gt;Let's go back to our &lt;code&gt;Controller&lt;/code&gt; and let's make the proper calls to our &lt;code&gt;Repository&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ApiController&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"v1/[controller]"&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;class&lt;/span&gt; &lt;span class="nc"&gt;OrdersController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ControllerBase&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="n"&gt;IOrdersRepository&lt;/span&gt; &lt;span class="n"&gt;ordersRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;OrdersController&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IOrdersRepository&lt;/span&gt; &lt;span class="n"&gt;ordersRepository&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;ordersRepository&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ordersRepository&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// Retrieves all orders&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;a list with all the orders available&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpGet&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetAll&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="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ordersRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAll&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// Retrieves the order that matches the id supplied&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;one order model&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"{orderId}"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status200OK&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status404NotFound&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;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="n"&gt;Guid&lt;/span&gt; &lt;span class="n"&gt;orderId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ordersRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;orderId&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="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;NotFound&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;Ok&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&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;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// Creates a new order&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;the newly created order&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;HttpPost&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status201Created&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;ProducesResponseType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;StatusCodes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Status400BadRequest&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ActionResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;Post&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;FromBody&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="n"&gt;OrderCreateUpdate&lt;/span&gt; &lt;span class="n"&gt;orderRequest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Order&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;Amount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orderRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Amount&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;UserId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;orderRequest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;
            &lt;span class="p"&gt;};&lt;/span&gt;

            &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;ordersRepository&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&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="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;BadRequest&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;StatusCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;201&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;result&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;We add the dependency of the &lt;code&gt;IOrdersRepository&lt;/code&gt; in the constructor and we use it from the endpoints. We also handle different responses depending on the result of &lt;code&gt;Repository&lt;/code&gt; and we explicitly define the possible responses using &lt;code&gt;ProducesResponseType&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Today's result?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;POST&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0a6FM_kL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4idtrl7pjox48hhr8s4p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0a6FM_kL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/4idtrl7pjox48hhr8s4p.png" alt="POST" width="880" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--irbnYzFT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/puhluqh6303n6elif4pj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--irbnYzFT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/puhluqh6303n6elif4pj.png" alt="GET" width="880" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;GET ALL&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QPC8V6Rm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zvr7b6z43jap340sbtx7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QPC8V6Rm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/zvr7b6z43jap340sbtx7.png" alt="GET ALL" width="880" height="1319"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have some experience building modern API's you are probably in shock. Is this guy really gonna use the same model for the API and database? is he gonna call the repository from the controller? why is everything in the same project?&lt;/p&gt;

&lt;p&gt;Don't worry, we will handle everything before this series end, I promise you it is gonna something worth putting in your Github 😄&lt;/p&gt;




&lt;p&gt;That was a lot, I know, I also didn't go into detail of all the application patterns used since it would have been impossible, but on every pattern used there is a link to the official guide on how to implement it in &lt;strong&gt;ASP.NET Core&lt;/strong&gt;, Microsoft tutorials are super good and they will give you the details missing.&lt;/p&gt;

&lt;p&gt;I hope you liked this first part, in the next one we will add the &lt;code&gt;Update&lt;/code&gt;, &lt;code&gt;Delete&lt;/code&gt;, and the combined information endpoint and if there is time we will also start separating concerns better and polish our service.&lt;/p&gt;

&lt;p&gt;As always, if you liked or not please let me know in the comments, and share it 😄&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>csharp</category>
      <category>beginners</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Do the SOLID principles apply to Functional Programming?</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Wed, 29 Jul 2020 19:46:35 +0000</pubDate>
      <link>https://dev.to/patferraggi/do-the-solid-principles-apply-to-functional-programming-56lm</link>
      <guid>https://dev.to/patferraggi/do-the-solid-principles-apply-to-functional-programming-56lm</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish 🇪🇸, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2020/jul/solid-funcional/"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Yesterday I was browsing one of the online developer communities where I usually hang out and I noticed there was this super intense debate about what writing good code is all about. As usual, the terms &lt;a href="https://en.m.wikipedia.org/wiki/Design_pattern"&gt;Design Patterns&lt;/a&gt;, &lt;a href="https://en.m.wikipedia.org/wiki/Robert_C._Martin"&gt;Clean Code&lt;/a&gt;, and &lt;a href="https://en.m.wikipedia.org/wiki/SOLID"&gt;SOLID&lt;/a&gt; where being thrown around a vicious fight of programming terms. It was clear that the audience was mainly Object-Oriented programmers. Suddenly, someone started talking about Functional Programming, me as an OOP programmer who is in his path to absorb as much as I can from the Functional way, I got intrigued.&lt;/p&gt;

&lt;p&gt;This person argued that SOLID and Design Patterns are Object-Oriented Programming(OOP) stuff and they don't relate well with Functional Programming(FP).&lt;/p&gt;

&lt;p&gt;This argument got stuck inside my head so I decided to write about it to express my own personal opinion. Since I have two different opinions on SOLID and Design Patterns, today, I am gonna cover only SOLID, I may cover Desing Patterns in the near future though.&lt;/p&gt;

&lt;p&gt;Let's start with some introductions.&lt;/p&gt;




&lt;h2&gt;
  
  
  What is SOLID?
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible and maintainable&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;They were first introduced by Robert C. Martin in the early 2000s in his paper &lt;a href="https://fi.ort.edu.uy/innovaportal/file/2032/1/design_principles.pdf"&gt;Design Principles and&lt;br&gt;
Design Patterns&lt;/a&gt; and they are the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Single-Responsibility Principle&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open–Closed Principle&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Liskov Substitution Principle&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interface Segregation Principle&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependency Inversion Principle&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How are they used in OOP and FP?
&lt;/h2&gt;

&lt;p&gt;Let's go one by one and let's see how they apply to both paradigms. &lt;/p&gt;

&lt;h3&gt;
  
  
  Single-Responsibility Principle
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"An object should only have a single responsibility, that is, only changes to one part of the software's specification should be able to affect the specification of the object."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Traditionally when people talk about this principle they think about classes (although the original idea comes from UNIX development), they think about extracting behavior into multiple classes and handling a proper separation of concerns. &lt;br&gt;
Although functional programming languages don't have classes the same principle holds true. Functions should be small reusable pieces of code that you can compose freely to create complex behavior.&lt;/p&gt;

&lt;p&gt;This can be extracted to almost anything, once your functions are small, the modules where they are located they should also form a cohesive closure that does only one thing and does it well.&lt;/p&gt;

&lt;p&gt;As long as your function or class or module has only one reason to change then you are applying this principle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Open–Closed Principle
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"Software entities ... should be open for extension, but closed for modification."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This principle is usually instantly related to inheritance. A well-defined parent class that holds functionality and children of this class extend or reuse the mentioned functionality. In reality, it just means that we should be able to reuse and extend code without having to modify the original implementation.&lt;/p&gt;

&lt;p&gt;Instead of using inheritance, Functional Programming achieves this by using two tools. Composition to create new behaviors from previously defined functions and higher-order functions to change functionality at runtime, btw if you are interested in reading more about these topics you can check my series &lt;a href="https://dev.to/patferraggi/functional-programming-for-the-object-oriented-developer-part-0-1bgj"&gt;Functional Programming for the object-oriented developer&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Liskov Substitution Principle
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Again when people generally think about this principle the first idea that comes to their head is that if the parent class has some behavior, their children should not break that behavior, but this is not the only applicable case, LSP also applies in case we use generic or parametric programming where we create functions that work on a variety of types, they all hold a common truth that makes them interchangeable.&lt;/p&gt;

&lt;p&gt;This pattern is super common in functional programming, where you create functions that embrace polymorphic types (aka generics) to ensure that one set of inputs can seamlessly be substituted for another without any changes to the underlying code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interface Segregation Principle
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"Many client-specific interfaces are better than one general-purpose interface."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is an easy one, but many people, including the ones that brought the topic to my attention, get too attached to the word "interface" and they automatically refer to the concept of interfaces in languages like C# or Java, they think that if you don't have interfaces then this principle cannot be applied.&lt;/p&gt;

&lt;p&gt;In reality, every interaction between components is done by an interface. When you use functions from a module, you are using the disposed interface of that module, even if we are in a dynamically typed language, that interface still exists. The point of this is that the way you create modules(or classes or interfaces or API's or whatever) needs to be cohesive, you should provide one clear way of doing things instead of many, and you should expose only what is necessary for the users to perform the specific task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dependency Inversion Principle
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;"One should depend upon abstractions, [not] concretions."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In languages like C#, this is achieved by using two tools. One is to create interfaces to define contracts of a predefined functionality. The other is to use dependency injection so that users of that functionality don't manually instantiate the concrete class, instead, they receive an instance of the interface through their constructor and they just call the appropriate methods on the instance.&lt;/p&gt;

&lt;p&gt;In functional programming, abstractions are the default way of handling code, functions are abstractions too, especially in functional programming where we care more about the "shape" of the data instead of to which specific type they are attached to. This creates the possibility to freely change the implementation at runtime by passing functions as parameters to other functions or even returning functions as results from the computation.&lt;/p&gt;




&lt;p&gt;I hope you liked my take on SOLID and Functional Programming. If you would like to see a direct comparison between implementations of Design Patterns in OOP and FP please let me know below in the comments 😄&lt;/p&gt;

&lt;p&gt;As always, if you liked this post please share it on social media. &lt;/p&gt;

</description>
      <category>functional</category>
      <category>webdev</category>
      <category>oop</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Are you sure you are a professional developer?</title>
      <dc:creator>Patricio Ferraggi</dc:creator>
      <pubDate>Wed, 15 Jul 2020 18:02:55 +0000</pubDate>
      <link>https://dev.to/patferraggi/are-you-sure-you-are-a-professional-developer-1mp1</link>
      <guid>https://dev.to/patferraggi/are-you-sure-you-are-a-professional-developer-1mp1</guid>
      <description>&lt;p&gt;If you are interested in reading this article in Spanish 🇪🇸, check out my blog:&lt;br&gt;
&lt;a href="https://www.patferraggi.dev/blog/2020/jul/sos-un-profesional/"&gt;The Developer's Dungeon&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For many years I believed that the only thing that constituted being a professional was being paid for doing something. I practiced Muay Thai for many years, so being a pro fighter meant being paid for fighting (apart from the fact that you use fewer protections during fights and sometimes rounds are longer).&lt;/p&gt;

&lt;p&gt;In a previous life, in a previous career, one professor told me that a professional would not speak about the things he has no knowledge about, he would not lie. I thought that was a very cool idea so I added it to my definition, curiously the other day a friend told me that I don't speak a lot, but when I do I always say something smart, so that professor might have influenced me more than I have realized at the time.&lt;/p&gt;

&lt;p&gt;Until a few years back I thought I was a professional developer, it wasn't until I read &lt;a href="https://www.amazon.es/Clean-Coder-Conduct-Professional-Programmers/dp/0137081073"&gt;The Clean Coder&lt;/a&gt; by Robert C. Martin AKA "Uncle Bob" that I started analyzing my processes, my actions, mistakes and realized that maybe I wasn't holding myself to the correct standards.&lt;/p&gt;

&lt;p&gt;In this article, I am gonna point out my past mistakes and how I think a real professional should behave.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Fake Professional
&lt;/h2&gt;

&lt;p&gt;For the first 2 years as a "professional" software developer, I worked at multiple consultancy companies, everything had to be done fast, sometimes there was no QA team, sometimes no designers, everything was in a hurry and the situation was pure stress, but those are not excuses. Out of my own lack of self-confidence, I have been pushed around to produce sub-par work, but it was me who let it happened.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Out of laziness, I did knowingly delivered faulty software.&lt;/li&gt;
&lt;li&gt;I didn't write a single unit test in 2 years.&lt;/li&gt;
&lt;li&gt;I didn't produce the best code I could, I went for the fast easy solution multiple times, bringing future bugs and problems.&lt;/li&gt;
&lt;li&gt;I have accepted to 'try' to deliver on certain deadlines even when I knew it was impossible to get it done in that timeframe, even working full weekends multiple times.&lt;/li&gt;
&lt;li&gt;I have been coerced to accept certain solutions from people that were not technically capable enough to understand the real implications.&lt;/li&gt;
&lt;li&gt;Out of my own behavior, I have seen code rotten to the point were application development becomes incredibly slow.&lt;/li&gt;
&lt;li&gt;I have wasted time during working hours.&lt;/li&gt;
&lt;li&gt;I thought that it was the obligation of my employer to teach me the right tools and practices for my job.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During those years I thought this was what working as a developer was like, I mean everyone around me was doing the same thing, the projects had no tests, management called all the shots on how things should be implemented and when. My word as a developer was not respected one bit and now I finally understand why.&lt;/p&gt;

&lt;p&gt;I am pretty sure that I am not the only one in the community that has done this, I have talked to many developers throughout the years to know this is not strange.&lt;/p&gt;

&lt;p&gt;Unfortunately, I am starting to think we don't have a profession. We don't have a set of rules, a set of common practices, ethics that every developer should follow in order to be considered a professional developer. We also don't have a common organization that will take the necessary actions when a developer behaves against our common set of standards.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goals
&lt;/h2&gt;

&lt;p&gt;I don't agree with everything "Uncle Bob" says but I do agree that until this happens we should at least start behaving like professionals. Here are a few rules that he has pointed out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The code that I produce will always be my best work. I will not knowingly allow code that is defective either in behavior or structure to accumulate.&lt;/li&gt;
&lt;li&gt;I will produce, with each release, a quick, sure, and repeatable proof that every element of the code works as it should.&lt;/li&gt;
&lt;li&gt;I will make frequent, small releases so that I do not impede the progress of others.&lt;/li&gt;
&lt;li&gt;I will fearlessly and relentlessly improve my creations at every opportunity. I will never degrade them.&lt;/li&gt;
&lt;li&gt;I will do all that I can to keep the productivity of myself, and others, as high as possible. I will do nothing that decreases that productivity.&lt;/li&gt;
&lt;li&gt;I will continuously ensure that others can cover for me and that I can cover for them.&lt;/li&gt;
&lt;li&gt;I will produce estimates that are honest both in magnitude and precision. I will not make promises without certainty.&lt;/li&gt;
&lt;li&gt;I will never stop learning and improving my craft.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Real Professional
&lt;/h2&gt;

&lt;p&gt;Since those problems became clear for me I have been behaving against a higher set of standards, I have fallen into the 'Software Craftsmanship' community.&lt;/p&gt;

&lt;p&gt;Every piece of code I produce has a set of tests attached to it. Since the project didn't have tests, I started doing tests on my own and improving the code, eventually, the team joined and know we have quite good code coverage.&lt;/p&gt;

&lt;p&gt;When I write a bugfix I don't go for the easy fix, I first come up with the best implementation, sometimes it does happen that the best implementation is not viable because of external constraints, but that decision is made by conscious analysis, not out of laziness.&lt;/p&gt;

&lt;p&gt;If someone that doesn't belong to the development team tries to impose a deadline on me I analyze if that deadline is feasible, if it is not I hold my ground and say that under those requirements that deadline is simply not possible, then I try to find a compromise that can work for both parties.&lt;/p&gt;

&lt;p&gt;During my office hours, I always work. It is my job to do it, I am being paid to do it. Nothing to argue.&lt;/p&gt;

&lt;p&gt;Although there are certain situations where your employer is responsible for paying you to improve yourself (if for instance, you need to learn certain tech so you can implement it in the company), I don't leave my general improvement to my employer, I am in control of my career. &lt;br&gt;
When I go home I read books, I listen to podcasts, I code on other paradigms and languages, it is my responsibility, and also is super fun 😄&lt;/p&gt;




&lt;p&gt;I have to say that so far my career has improved a lot since I changed my mindset, I have been recognized by my peers and coworkers, I have taken responsibility for my triumphs but also for my mistakes. Being a professional is not easy, it is far easier to not have any type of standards for yourself, but there is also no reward in doing it the wrong way.&lt;/p&gt;

&lt;p&gt;I hope you liked the article, please let me know in the comments if you have seen others or even yourself behave like this before, do you think I am missing something? also, let me know in the comments.&lt;/p&gt;

&lt;p&gt;If you like this post please share it 😄&lt;/p&gt;

</description>
      <category>career</category>
      <category>motivation</category>
      <category>ethics</category>
      <category>craftsmanship</category>
    </item>
  </channel>
</rss>
