<?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: Israel Fermín M.</title>
    <description>The latest articles on DEV Community by Israel Fermín M. (@iferminm).</description>
    <link>https://dev.to/iferminm</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%2F29254%2F729363a1-2b7d-4865-9726-f7508a052697.jpg</url>
      <title>DEV Community: Israel Fermín M.</title>
      <link>https://dev.to/iferminm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/iferminm"/>
    <language>en</language>
    <item>
      <title>7 tips to be a more productive engineer</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Wed, 06 Oct 2021 03:20:28 +0000</pubDate>
      <link>https://dev.to/iferminm/7-tips-to-be-a-more-productive-engineer-25ea</link>
      <guid>https://dev.to/iferminm/7-tips-to-be-a-more-productive-engineer-25ea</guid>
      <description>&lt;p&gt;As Software Engineers, we are not measured by how much we know about computer science, data structures and algorithms, at least not after we pass the interview. At the job the story is completely different, we can be the best programmers in the company, we can know our way around the languages we work on and write code with the eyes closed but, none of that matters if we produce no value. Our value comes in many forms, code and working, scalable and robust software is one of those ways, but we can't forget we are part of an engineering team and also keep in mind that &lt;a href="https://iffm.me/software-engineering.html"&gt;Software Engineering is more than writing code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Most of our value comes in the form of working software, performance and resources optimizations, architecture and software design RFCs and so on, these tasks require a high level of concentration which means our ability to produce high value work is constrained by the amount of continuous uninterrupted time we have. Along with that, we also produce value in meetings, by aligning priorities and work with other engineering teams and also within our team when we work with other engineers, by reviewing code and other forms of collaborative work.&lt;/p&gt;

&lt;p&gt;Ideally, we need to maximize the amount of high impact work we do as engineers, this usually has to do with the tasks that require a higher level of focus, but we can't neglect the other kinds of work we need to do as well. To do this, we need to maximize the amount of uninterrupted time we have during our working hours.&lt;/p&gt;

&lt;p&gt;Here are seven practices that have worked for me, hopefully they will work for you too. Let's get it on:&lt;/p&gt;

&lt;h2&gt;
  
  
  Have a daily prioritized list
&lt;/h2&gt;

&lt;p&gt;This looks like a no-brainer, right? and yet, a lot of people seems to fail in using them. I love lists, I make lists for almost everything: my daily work, my personal projects, what I need when I go to the supermarket...&lt;/p&gt;

&lt;p&gt;I keep a daily TODO list and I manage priorities with colors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Red:&lt;/strong&gt; for high impact or urgent work, things that need to be done ASAP or things that, when done, will have a high impact on the projects I'm maintaining&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Yellow:&lt;/strong&gt; for things that will have impact, but not as much and can wait a bit to get some attention, for example, looking into an error that pops out from time to time in the logs or reading about some technology I will need to use some time in the future. It's good to tackle them before they become red.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blue:&lt;/strong&gt; for things with low to no impact but would be fun or nice to do.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I usually mark in &lt;strong&gt;bold&lt;/strong&gt; the ones that require deep focus to be done, these visual conventions help me navigate my list easier than &lt;em&gt;P1&lt;/em&gt;, &lt;em&gt;P0&lt;/em&gt; and &lt;em&gt;P2&lt;/em&gt; or a numeric approach to set priorities.&lt;/p&gt;

&lt;p&gt;I don't finish my TODO list every day, to be honest, there are always a lot of things to tackle and it's impossible to get everything done in one day, plus, every day something new comes up, someone has a new request, someone writes a new RFC I need to read and comment, so, I keep adding tasks to the list as they come up and prioritize them later unless they're explicitly urgent. Whatever I can't finish today gets spilled for &lt;em&gt;tomorrow's&lt;/em&gt; list.&lt;/p&gt;

&lt;p&gt;I also do my lists in advance, I prepare &lt;em&gt;tomorrow's&lt;/em&gt; list &lt;em&gt;today&lt;/em&gt; by end of day, that way I don't have to do it &lt;em&gt;tomorrow&lt;/em&gt; and I can just review it, and get to it after I have my coffee in the morning.&lt;/p&gt;

&lt;p&gt;Of course, you'll need to keep your lists somewhere, for this, really, whatever floats your boat, some people use &lt;a href="https://www.notion.so/"&gt;Notion&lt;/a&gt;, some others prefer &lt;a href="https://evernote.com/"&gt;Evernote&lt;/a&gt;, &lt;a href="https://keep.google.com"&gt;Google Keep&lt;/a&gt; also seems to be a very popular option. At &lt;a href="https://careem.com/careers"&gt;Careem&lt;/a&gt;&lt;br&gt;
we use &lt;a href="https://www.atlassian.com/software/confluence"&gt;Confluence&lt;/a&gt; internally as a knowledge base solution for all things documentation, the thing I like about &lt;a href="https://www.atlassian.com/software/confluence"&gt;Confluence&lt;/a&gt; is that it gives every user a &lt;em&gt;personal&lt;/em&gt; space, I keep my daily TODO in my personal space as private notes for myself, it's very convenient because I don't have to have yet another tool, it's work and it's protected by all the security measures&lt;br&gt;
we have at &lt;a href="https://careem.com/careers"&gt;Careem&lt;/a&gt; and I'm usually logged in.&lt;/p&gt;

&lt;p&gt;This system helps me keep focused and by creating a new page every day, I can look back and keep track of everything I've worked on and when while also making sure I focus only on unfinished tasks and remove the noise of finished tasks from&lt;br&gt;
my view.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be intentional with your time
&lt;/h2&gt;

&lt;p&gt;Have you ever wondered how it is possible to deliver so much stuff at school or uni and why we're not able to deliver as much at work?, the answer is, we had a routine, more or less. We knew every day we were going to have Calculus I from 10:00 to 12:30, then Algorithms II from 13:00 to 14:30, then 3 hours free, then back to classes from 18:00 to 19:45, it was predictable, we would use those 3 hours to study, work on a project, have lunch, socialize or a combination of those, every day was planned and we could schedule in advance what to do. At work it's a bit more difficult, we have 8 hours of semi-random activities. When I realized this, I thought it makes sense to give some order to that chaos and make a routine for myself so that I could use my time in a more predictable manner.&lt;/p&gt;

&lt;p&gt;One book that changed the way I think and reason about time is [Master your time master your life (&lt;a href="https://www.goodreads.com/book/show/31287110-master-your-time-master-your-life"&gt;https://www.goodreads.com/book/show/31287110-master-your-time-master-your-life&lt;/a&gt;) by productivity coach &lt;a href="https://www.goodreads.com/author/show/22033.Brian_Tracy"&gt;Brian Tracy&lt;/a&gt;. In this book, Tracy mentions that there are multiple types of time in life and one needs to be able to identify what kind of time you have at the moment to know how you should use it as well as what kind of time a task requires in order to know when to do it.&lt;/p&gt;

&lt;p&gt;At &lt;a href="https://careem.com/careers"&gt;Careem&lt;/a&gt; we have what we call &lt;em&gt;focus time&lt;/em&gt;, which are blocks where no group meetings are allowed, only pairing for problem-solving or making progress on a task, we also have a no-meetings day, so, I schedule all my high-focus work at those times. Before we had these policies, I used to schedule 2 hours every day where I didn't accept any meetings or interruptions, muted all notifications and just focused on that type of tasks, whether it was writing code, working on some architecture or designing a solution to implement it later, I just focused on that during the time I blocked for this high focus work.&lt;/p&gt;

&lt;p&gt;Now, I do all my collaborative work on the rest of the time I have, we usually have some time in-between meetings so I use that to read RFCs, review code and sometimes socialize.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be defensive with time
&lt;/h2&gt;

&lt;p&gt;Do you often find yourself attending more meetings than you feel you should?, or stuck in a meeting having no idea why you're there?. Learning to say &lt;em&gt;no&lt;/em&gt; is a skill you need to master, I had some hard time mastering this skill for many reasons, our inner nature is to help others, at least mine, I used to say no very rarely and as a result I was usually swamped with work, meetings and other commitments. Now, if I find a reason to say &lt;em&gt;no&lt;/em&gt;, I say &lt;em&gt;no&lt;/em&gt;. It's usually for a reason. I have a limited amount of time every day and I have to use it wisely.&lt;/p&gt;

&lt;p&gt;For meetings, if I have a clashing event, I directly reject the invitation. All my current commitments take precedence with respect to new requests. If the meeting doesn't have a clear objective or agenda I ask for it to be added, if it's not added, and I have no way to know what's expected in the meeting, I let the organizer know I won't attend. If the meetings are spilling, I call that into attention and leave if I have other things to do. This might seem rude as attending meetings is part of the job but so it organizing and running them, if a meeting has no information about what to expect, it means someone is not doing their job organizing it. If the meeting is spilling, it means someone is not doing their job running it effectively.&lt;/p&gt;

&lt;p&gt;Remember, as an IC (Individual Contributor) your time is your most valued resource, don't give it to everyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Learn your tools
&lt;/h2&gt;

&lt;p&gt;This might seem an obvious one, but It's incredible the number of people I know who just know the basics of everything they use. I spend most of my time... well...&lt;br&gt;
writing, so, my text editor is where I spend most of my productive time. It doesn't matter what editor you use, whether it's vim or Emacs, vs-code or an IDE, learn how to use the advanced features. I use vim for most of the things that has to do with text: coding, writing docs in markdown, notes, etc. I'm constantly improving my vim config so that I can write code faster and navigate projects more efficiently. For larger codebases I'm not very familiar with, I do use an IDE, we have an IntelliJ license through Careem, so, that's the IDE I use until I'm familiar with the project so that I can navigate my way through the code, it's convenient to learn the key shortcuts.&lt;/p&gt;

&lt;p&gt;The other thing I spend most of my time now is the office chat, we use Slack, so, it's also worth learning how to use it properly, all the key shortcuts as well as learning to use the search, it's very powerful and you can find almost anything you can by using the search box instead of navigating through the chats.&lt;/p&gt;

&lt;p&gt;By becoming a power user of all the things you use, you can then create systems to help you become more productive, for example, I often mark slack messages with reactions I can later search for, or set reminders on Slack about something&lt;br&gt;
a colleague said so that I can take action about it. Investing some time in becoming a power user at work often pays off.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take breaks
&lt;/h2&gt;

&lt;p&gt;This might seem counterintuitive but taking breaks makes you more productive just because you give your brain some chance to breath, what does this mean?. Have you ever been working on a feature, debugging an issue and felt blocked? like, you don't know what to do, what else to try or that the next step should be?, this is usually because you're locked inside the problem you're trying to solve, think of it as a box, it's very difficult to find something when you're inside the box, it's better to take some distance and look at it from a different perspective that lets you see what you're searching for. It's very difficult to find a failure anywhere if you're looking at it too closely, you might be looking at the wrong place, taking some distance and looking at it from afar makes it easier to spot anomalies and then just zoom-in there again.&lt;/p&gt;

&lt;p&gt;That's exactly what happens when you take a break, you take some distance from the problem, allowing your brain to look at it from afar, your unconscious mind will continue working on the problem while you drink a cup of coffee or read some other material or (if you work from home and have kids) go change some diapers. Once you come back to the thing you were working on, it will be more clear or, at least, you'll have some hints on where to go next.&lt;/p&gt;

&lt;p&gt;As I mentioned &lt;a href="https://iffm.me/working-from-home-with-kids.html"&gt;on a previous post&lt;/a&gt;, I often use the &lt;a href="https://en.wikipedia.org/wiki/Pomodoro_Technique"&gt;pomodoro technique&lt;/a&gt;&lt;br&gt;
on my day to day work, I set a timer and I commit to work on a task for, say, 30-40 minutes, I focus on the task at hand and only on that, when the time is finished, I take a 5min break and then come back to the task for another 30-40min block, this way I make taking breaks part of my work routine and avoid dawning myself in a problem.&lt;/p&gt;

&lt;p&gt;This also applies to taking vacations, at &lt;a href="https://careem.com/careers"&gt;Careem&lt;/a&gt; we have unlimited vacations policy, this is great because I can take 1 or 2 days off whenever I feel I'm burnt out and come back refreshed to work. When you're too tired or burnt out by work, your motivation decreases and your work doesn't come out as easy or with the same quality, this is also when you consider switching jobs. Taking a couple of days off to rest and disconnect from work when a weekend is not enough to recover is a wise time investment, for me, after one of those hard-deadline, time-sensitive, critical projects I try to take extend the weekend, at least 1 day, then I come back fresh and ready for another round. I'm not saying you should abuse these kind of policies, rather use them for your well-being and mental sanity, take a break when you feel you need it, your body and your employer will thank you for it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get the most out of meetings
&lt;/h2&gt;

&lt;p&gt;This one might sound odd, if you want to be productive you should actually avoid meetings, right? as long as I'm sitting on a meeting I'm not doing my job, hence, I'm not producing value. We can agree on part of the statement for sure but it's not entirely true, meetings are an essential part of the job, we work with other fellow humans to tell machines what to do, so meeting with other people is essential to create alignment and decide on further steps, and make decisions about the underlying tech we are working on.&lt;/p&gt;

&lt;p&gt;Meetings can't be avoided for sure, we can reduce them as much as we want/need but some kinds of meetings are just unavoidable and we need to learn to live with that. Not everything is lost, now that we accepted meetings are part of our life, we can choose to get the most out of them and make them efficient so that we don't have to meet too many times to discuss the same topics over and over again.&lt;/p&gt;

&lt;p&gt;This might take a bit of discipline and agreement with your team, but with a few general practices in your meetings you can make them more efficient:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start and finish on time, don't wait for late joiners, if you're on-time, you're late by German standards.&lt;/li&gt;
&lt;li&gt;Have a clear meeting objective and agenda shared previously, this helps everyone know what will be discussed and prepare accordingly. If you receive a meeting invitation without an agenda or at least a description, reject it right away&lt;/li&gt;
&lt;li&gt;Keep the conversation on-topic, call out side tracks and bring everyone again to the main topic&lt;/li&gt;
&lt;li&gt;Take notes and share them, this avoids the back and forth after the meetings and the traditional questions such as "who was going to do X?", "did we decide A or B?"&lt;/li&gt;
&lt;li&gt;Share pre-reads in advance and, if you receive a pre-read for a meeting, make sure you read it before joining&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Meetings are a necessary evil, but with discipline you can tame the monster and make them more effective.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start and stop on time
&lt;/h2&gt;

&lt;p&gt;Yes, this is the most important advice. We often see Engineers working until late evening, it's not about the hours, it's about the quality of the time you put into everything you do, I'd rather work 20min on something but really focused than 4 hours but all over the place.&lt;/p&gt;

&lt;p&gt;Work will always be there, it never ends, if you start and stop working on time you're not doing anything wrong, it's just the way it should be. Working remotely this is especially tricky because you don't have the pressure of commuting, you can stretch a few minutes to wrap up, but that's it!, when it's time, close your laptop and go to your family, otherwise working after-hours becomes a habit and you won't be productive during office hours because you'll be thinking on finishing after-hours.&lt;/p&gt;

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

&lt;p&gt;Time management is vital and a very difficult soft skill to develop, it's all about routines and rituals to me, it takes a lot of will power and discipline to actually put these personal processes in place but, in my own experience, it's totally worth the effort, if I miss doing my TODO list one day, I feel bad and a bit lost and I'm not fully productive that day because I don't have a clear picture of the&lt;br&gt;
priorities. Writing everything down helps you take it out of your system and take the tasks one by one without the fear of forgetting something.&lt;/p&gt;

&lt;h1&gt;
  
  
  Recommended readings
&lt;/h1&gt;

&lt;p&gt;Head to the &lt;a href="https://iffm.me/7-tips-to-be-a-more-productive-engineer.html"&gt;original post&lt;/a&gt; for a list of recommended readings and don't forget to &lt;a href="https://twitter.com/iferminm"&gt;follow me on twitter&lt;/a&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>The best language I've learned to grow in my career</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Mon, 13 Sep 2021 09:12:07 +0000</pubDate>
      <link>https://dev.to/iferminm/the-best-language-i-ve-learned-to-grow-in-my-career-4g99</link>
      <guid>https://dev.to/iferminm/the-best-language-i-ve-learned-to-grow-in-my-career-4g99</guid>
      <description>&lt;h1&gt;
  
  
  English
&lt;/h1&gt;

&lt;p&gt;If you're reading this, chances are you speak it already, if you're not a native speaker improve it, study it and master it. Practice your pronunciation and increase your vocabulary.&lt;/p&gt;

&lt;p&gt;This has proven to have much more value to my career than any programming language I know.&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>Work for a company that puts people first</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Thu, 15 Apr 2021 07:38:53 +0000</pubDate>
      <link>https://dev.to/iferminm/work-for-a-company-that-puts-people-first-8f6</link>
      <guid>https://dev.to/iferminm/work-for-a-company-that-puts-people-first-8f6</guid>
      <description>&lt;p&gt;The title says it all, easier said than done right? the truth is that it takes a lot of time for some people (and not so long for some others) to find a place where they feel welcomed and belonging, it's a quite cool feeling when people appreciate you and makes an effort in making you feel comfortable at work in every aspect by always taking into account what's important to you and helping you with that.&lt;/p&gt;

&lt;p&gt;For me, I've been working in the software industry since I was studying, and I have a lot of stories. Most companies value the business first, and that's completely valid, if the business is OK, everyone is getting paid and everyone is happy. But I feel I don't last long in this type of companies, I value flexibility, every company has its rules and every manager has their values and also set of rules they use to run their teams, but I believe everything needs to be evaluated in a case by case basis, not everyone has the same conditions or priorities in life and this is where this approach fails. Let me share a brief story of my professional life until now and why I've left some of the companies I worked for.&lt;/p&gt;

&lt;h1&gt;
  
  
  My first job
&lt;/h1&gt;

&lt;p&gt;My first official job, and by official I mean, for a company, with a contract and not doing something kinda freelance for a friend, was with an online news hub, they scrapped news websites and presented all the headlines from different sources in a single place, people could customize which sources they preferred for certain topics and filter based on that. My job there was to build bots to scrape multiple sources, extract the content and store it in our system. I was still doing my undergraduate courses so it was a part-time thing.&lt;/p&gt;

&lt;p&gt;Everything was going great! salary always on time for about 3 months, then...&lt;/p&gt;

&lt;p&gt;By the end of the fourth month, I didn't see the salary being credited to my account, I didn't pay too much attention, maybe there's a delay with the bank or they didn't process the payroll on time or whatever, I emailed my manager and I got an auto-response that he was on vacation, half-way into the month I email my manager's manager asking what happened...&lt;/p&gt;

&lt;p&gt;The answer was yes, you didn't get paid because you're not working with us anymore , I was a bit shocked because no one told me I was let go, they conveniently forgot to tell me that little detail, wait a minute, this gets way better, I highlighted exactly that and the answer was amazing: well, Israel, if you see the contract it says any party can end the employment agreement. It doesn't explicitly mention any notice, technically we didn't do anything wrong . Long story short, I had to threat them with going to the labor authority and report the issue in order to get my last salary... almost 3 months after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson learned
&lt;/h2&gt;

&lt;p&gt;There's very bad people owning and managing companies, I know I was undergraduate but they even used that fact to imply I should be thankful about them paying me for my work because, and I quote textually, a lot of students would work for free just to get the experience , well, I wasn't one of those students...&lt;/p&gt;

&lt;h1&gt;
  
  
  My internship, great! until it wasn't
&lt;/h1&gt;

&lt;p&gt;My first professional work experience was on my internship, I did it with a small local OpenSource consultancy firm, I learned A LOT!, the work environment was great and fun, workmates were cool, smart and the kind of people who knows what they're doing. The only bad thing was salary, as I was an intern, my salary was low, but I was OK, at least I was doing things I was into and learning quite a lot.&lt;/p&gt;

&lt;p&gt;When I finished my internship, they offered me a permanent position which I accepted, they were aware I was still having academic commitments and they were OK with that. I had to work on my thesis project so, after some time I asked for some time off to do that, they offered me a room at the office where I could lock myself up for up to 3 hours a day to fully focus on my thesis, this was awesome but the only bad thing was it was respected for a bit over a week, after that I started getting constantly interrupted to work on other things, we went back and forth with this for a little over 2 months until I decided to quit so I could focus on my thesis.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson learned
&lt;/h2&gt;

&lt;p&gt;Sometimes your priorities and the organization's priorities are not aligned, and this is fine, when this happens the best thing to do is to part ways. Maybe if I was given that time off to complete my thesis as I initially requests I would still be working there. The company, the projects and the team were awesome.&lt;/p&gt;

&lt;h1&gt;
  
  
  Fast forward to my first job in Dubai
&lt;/h1&gt;

&lt;p&gt;I won't be talking about how I got a job in Dubai and how I got here, &lt;a href="https://iffm.me/new-grads-survival-guide.html"&gt;I wrote about it before&lt;/a&gt;, I won't write about how cool it was because &lt;a href="https://iffm.me/working-at-dubizzle.html"&gt;I already did it&lt;/a&gt; but I'll dig a bit deeper on the real reasons behind me leaving that company. I wrote an &lt;a href="https://iffm.me/bye-bye-dubizzle-hello-careem.html"&gt;article before about it&lt;/a&gt;, but I wasn't completely honest about why I actually left because I didn't think it was appropriate at that time. By now, I know people have changed and switched places, and everything is different so I won't be at risk of exposing anyone.&lt;/p&gt;

&lt;h2&gt;
  
  
  The end of the honeymoon
&lt;/h2&gt;

&lt;p&gt;In October 18th 2016 my first daughter was born, and it was also the day that marked the beginning of the end for me at that company. See, here in the UAE, the paternity leave policy at that time was 1 week off, that company gave 2 weeks and nothing more. Everyone knew my wife and I are here alone, the nearest relatives we have are in Spain so we were becoming parents all by ourselves, which is a lot of work, paternity leave is not vacation it's time to support your wife who just pushed a human being out of her body and now has to breastfeed, which is very energy-consuming and demanding.&lt;/p&gt;

&lt;p&gt;So, 2 weeks are not enough, 40 days is the recommended resting time for new moms, I literally had to beg for my line manager to approve 2 extra weeks off from my annual leave and coming back, everything was changed.&lt;/p&gt;

&lt;p&gt;My line manager started making my life impossible, I got a terrible performance review, which I felt was not fair because an incident from over a year and a half ago was brought up as the reason even though I fixed it in less than 1hr since the bug affecting subscriptions experience was reported.&lt;/p&gt;

&lt;p&gt;Then, my in-laws visited in November, they were staying with us in Dubai for three months, until January, so, I applied for 2 weeks off in December so that we could spend some time around Christmas and New Year together and show them around. In December, the guy announces the following: guys!, there's a lot to do, so I won't be approving any vacations this month , my time off request was rejected and then I got to know another colleague got it approved to go back home for a relative's wedding and another colleague was also traveling the same month. I didn't get to spend too much time around either because there was always something to do, one day, at around 17:30, the guy in question starts packing to leave and says Israel!, please make sure you close all the zendesk tickets before leaving . After he left, I checked our support dashboard... over 30 tickets pending for resolution. I was effectively being given all the crappy tasks no one else wanted to work on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then I was moved to a different team
&lt;/h2&gt;

&lt;p&gt;Yup, I thought things were going to improve, and they did for a bit, in 2017 I spoke in 2 conferences and several meetups, mostly about things I was working on and trying to attract more talent for the company as well. Before one of the conferences I got a task on a very short notice before traveling, so, I made it clear I might not be able to finish it before flying, but I would complete what I could and leave pointers on how to finish it so someone else could pick it up and I did exactly that, the night before flying I wrote a very comprehensive email explaining the approach I was following and detailing which classes needed to be changed, which methods and why, even left some test cases written to validate the functionality worked correctly. Coming back from the conference, my new manager calls me for a meeting, I thought it was something related to the talk I gave in the conference, but nope... not even close...&lt;/p&gt;

&lt;p&gt;He hands me a warning letter, on which grounds?, because I failed to finish a task and left for a week , and he also mentioned your team mates say you're unreliable and they avoid working with you , I was shocked, no one ever told me anything like that. A few days after that meeting I asked my colleagues for feedback and everything I got was positive, so, I figured, either my line manager was lying to me or my colleagues were not professional enough to speak to me directly about work-related things they were not happy about with me. In both cases, I think that's unacceptable in a professional environment, I thought I left all that "talking behind your back" thing back in high school.&lt;/p&gt;

&lt;p&gt;Anyways, the performance review time comes and I'm called for the performance evaluation meeting, to my surprise, there's my line manager and my old manager sitting behind the table which I found strange, what was even more strange was that the person delivering the performance evaluation was my old manager and, guess what, it wasn't a good one and quite old things from over 2.5 years ago were brought up, I have to admit I lost my cool in the middle stopped the evaluation, told my manager You'll have my resignation email in a few minutes and left the room, that's when I wrote an email to HR CCing my line manager to start my notice period.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lesson learned
&lt;/h2&gt;

&lt;p&gt;The minute you feel something is not right, speak up, complain, talk to people, highlight it... if you feel it isn't right, then it isn't right, you don't have take crap from anyone and if someone is giving you a hard time for no apparent reason, the best thing to do is to part ways, to be honest, looking back I feel I took too long to leave.&lt;/p&gt;

&lt;h1&gt;
  
  
  And I joined Careem
&lt;/h1&gt;

&lt;p&gt;I already wrote about joining Careem and why I joined, so, I won't repeat myself here, but I will point out that I had my second daughter recently (2020) and I was super scared about it, this didn't go too well with my previous employer and I have to confess I started interviewing with several companies at the time, had 2 very good offer letters in my hands and was on the final stages for another 2 openings.&lt;/p&gt;

&lt;h2&gt;
  
  
  Things were different this time
&lt;/h2&gt;

&lt;p&gt;Well, the only thing which was the same was the paternity leave time, only 2 weeks, I spoke to my manager about getting an extended paternity leave because of COVID, no family was going to be able to come over, airports were closed (it was by the end of 2020) and forget about traveling to Spain and working from there for a while... you know... because COVID... and also because my wife's passport was expiring. Nothing like this was ever proposed at Careem and he was quite new in this being a manager thing so, he did what any new manager would do, he asked me to go to HR and he would be OK with whatever they decide and, if they said no , we would find a way.&lt;/p&gt;

&lt;p&gt;So... I went to HR and explained everything, they were super supportive, they said hey, there's no such thing as an extended paternity leave, but you can request time off your annual leave as we have unlimited vacations policy and we will leave a note highlighting this was for paternity extension . I did just that, not only HR and my manager were super supportive, but also my whole team. I got a bit over a full month to spend at home supporting my wife and taking care of our 4yo who was staying at home because of the pandemic so that my wife could breastfeed peacefully, also doing a lot of diaper changes.&lt;/p&gt;

&lt;p&gt;Then, coming back to work was super flexible, they gave me quite flexible timing to continue supporting at home while we got back into the routine. I even got a great performance review, I am beyond happy about all of this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about the interviews
&lt;/h2&gt;

&lt;p&gt;Well, I understood that very few companies are like this, so... I ended up rejecting the offers and canceling the last interview rounds.&lt;/p&gt;

&lt;h1&gt;
  
  
  My take about everything
&lt;/h1&gt;

&lt;p&gt;A job is a job, and there's nothing you can do about it, you have it today, tomorrow no one knows. But not all companies are the same, there are some which puts the business first. For example, the first company I worked for... maybe they needed someone cheap to complete the mechanical work of implementing web scrapers to extract the content from those websites and they just stopped caring after it was done, I don't know. The one where I did my internship, well, they had projects to finish for the clients, so, they needed me to work on that, so my thesis and my graduation goal wasn't a priority for them. My first job in Dubai, well, I don't know what happened there, but if they had a "people first" kind of philosophy nothing of that would had happened. Of course, I understand, if the business comes first, it runs, it generates value and revenue and people gets paid.&lt;/p&gt;

&lt;p&gt;Then, on the other hand, we have companies like Careem, maybe supporting my wife is not their business or priority, but it was something I needed to do so, they supported me on that. Then, coming back to work and get back into the routine might be their priority, and also mine, but also family comes first, so... if something was happening at home, I had to solve that first and then comes the work. They could have rushed me into work, but they didn't, we went step by step and I took only non-critical tasks for a while until everything was settled both at home and work. They understand that if you put your people first, they will care for the business as if it was their own, and that's exactly what I do. I want to work on a place like this for a very long time, and it's my job to contribute to its success so I can continue here.&lt;/p&gt;

&lt;p&gt;Thank you Careem for being Careem.&lt;/p&gt;

</description>
      <category>career</category>
    </item>
    <item>
      <title>Choreography and Orchestration in Microservices Architecture</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Sun, 14 Mar 2021 09:44:23 +0000</pubDate>
      <link>https://dev.to/iferminm/choreography-and-orchestration-in-microservices-architecture-4fg1</link>
      <guid>https://dev.to/iferminm/choreography-and-orchestration-in-microservices-architecture-4fg1</guid>
      <description>&lt;p&gt;On a &lt;a href="http://iffm.me/my-take-on-microservices.html"&gt;previous article&lt;/a&gt; on &lt;em&gt;microservices&lt;/em&gt;, we went through the best practices I've seen, which doesn't mean those are the only ones, it only means that those are the ones I've seen work for me and the ones I've tried.&lt;/p&gt;

&lt;p&gt;This time, I would like to focus on &lt;strong&gt;Choreography over Orchestration&lt;/strong&gt; and &lt;strong&gt;Rely on data, not services&lt;/strong&gt; because I feel I didn't develop enough on these ones and those are really important these are also the two &lt;em&gt;principles&lt;/em&gt; that will help you &lt;em&gt;avoid sync calls&lt;/em&gt;, which is usually a good practice for inter-service communication.&lt;/p&gt;

&lt;p&gt;But first:&lt;/p&gt;

&lt;h2&gt;
  
  
  Internal &lt;em&gt;REST&lt;/em&gt; services, why not?
&lt;/h2&gt;

&lt;p&gt;Don't get me wrong, I love &lt;em&gt;REST&lt;/em&gt;, I like building &lt;em&gt;API*s and I enjoy using a well designed one for sure, but for internal communication I prefer to avoid it unless the communication **needs&lt;/em&gt;* to be synchronous, there are some cases where you can't help it and it's not always because of a bad design, sometimes the use case itself enforces that restriction.&lt;/p&gt;

&lt;p&gt;If you find yourself using network calls most of the time, something will most likely go wrong. Network is not 100% reliable and, &lt;strong&gt;always&lt;/strong&gt; remember, &lt;em&gt;if something can fail, it will fail&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Increases overall response time
&lt;/h3&gt;

&lt;p&gt;Take a look at the following figure: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_XxmHFpp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/k261ik209fporvr/service_down.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_XxmHFpp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/k261ik209fporvr/service_down.png" alt="Services map"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Response times are not taking into account the wait time while the downstream services respond. This means, &lt;em&gt;service 1&lt;/em&gt; queries &lt;em&gt;service 2&lt;/em&gt;, it does &lt;em&gt;something&lt;/em&gt; and takes 10ms to respond. Also, &lt;em&gt;Service 1&lt;/em&gt; queries &lt;em&gt;Service 3&lt;/em&gt; which queries &lt;em&gt;Service 4&lt;/em&gt; and &lt;em&gt;Service 5&lt;/em&gt;. &lt;em&gt;Service 4&lt;/em&gt; does &lt;em&gt;something&lt;/em&gt; and takes 300ms to respond and &lt;em&gt;Service 5&lt;/em&gt; queries &lt;em&gt;Service 6&lt;/em&gt; which takes 1000ms to respond, then &lt;em&gt;Service 5&lt;/em&gt; does &lt;em&gt;something&lt;/em&gt; and takes another 1200ms to come back to &lt;em&gt;Service 3&lt;/em&gt;, which has been waiting 2200ms to get all the data it needs to do &lt;em&gt;some stuff&lt;/em&gt; which takes 300ms. By this time, &lt;em&gt;Service 1&lt;/em&gt; has been waiting 2500ms for all the data it needs to do a 120ms &lt;em&gt;something&lt;/em&gt; and return back to the upstream caller, which could be another service waiting or the end user. &lt;/p&gt;

&lt;p&gt;Note that the above flow paralelizes all the needed downstream calls per service, so in this case, the total response time will be constrained by the slowest call chain. If you were using a stack where doing multiprocessing or async programming is not an easy option, you'll have to add up the response time for all of the downstream calls because in reality the service in question is being blocked while waiting for the network call to finish and, only then, making the second call and blocking until it comes back and so on.&lt;/p&gt;

&lt;p&gt;There are several ways you can keep the same setup, you can add several levels of cache in between services, you can add a timeout to the network calls but everything comes at a cost. If you're keeping a synchronous approach to answer certain questions it's because you need your data as fresh as possible, so, the more cache you add the more stale your data could be. You could also add a timeout to your calls but, if one of them times out, you'll fail in responding to the upstream caller and it will look like the system is down.&lt;/p&gt;

&lt;h3&gt;
  
  
  What if someone is down?
&lt;/h3&gt;

&lt;p&gt;Let imagine &lt;em&gt;Service 6&lt;/em&gt; is down because we had a buggy release.&lt;/p&gt;

&lt;p&gt;This means, &lt;em&gt;Service 1&lt;/em&gt; will have to wait 1500ms before returning an error upstream, you can mitigate this with a [circuit breaker (&lt;a href="https://www.martinfowler.com/bliki/CircuitBreaker.html"&gt;https://www.martinfowler.com/bliki/CircuitBreaker.html&lt;/a&gt;) approach or returning a  cached response for the query you're trying to answer but, again, unless you really need this to be synchronous, you'd be adding more complexity to an already complex system.&lt;/p&gt;

&lt;p&gt;Also, what if it isn't a &lt;em&gt;read&lt;/em&gt; operation, what if we're actually &lt;em&gt;writing&lt;/em&gt; downstream and the last write fails because of &lt;em&gt;reasons&lt;/em&gt;. You'll be half way a transaction and you'll have to deal with it somehow, either queuing that last write and hoping &lt;em&gt;Service 6&lt;/em&gt; comes back soon or rolling back the whole transaction which would mean deleting from the other services and returning an error, there are ways to solve this, but usually it doesn't need to be this hard.&lt;/p&gt;

&lt;h3&gt;
  
  
  When should I go synchronous?
&lt;/h3&gt;

&lt;p&gt;In my opinion, it will depend on the use case you're implementing and how critical it is to return the exact data at the moment the request was done, usually there's some tolerance to return slightly stale data, but things like &lt;em&gt;credit accounting&lt;/em&gt;, &lt;em&gt;warehouse availability&lt;/em&gt; or anything that was to do with resources being consumed in real time are good candidates for sync calls and all the complexity they involve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choreography vs Orchestration
&lt;/h2&gt;

&lt;p&gt;There's a good analogy in the &lt;em&gt;microservices&lt;/em&gt; world and how they handle &lt;em&gt;things&lt;/em&gt; happening within the system, let's call those things &lt;em&gt;events&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Let's say there are two types of &lt;em&gt;events&lt;/em&gt;, those which make the system &lt;em&gt;do&lt;/em&gt; something, for example, in an e-commerce website it could be a user bought something, and those which make the system &lt;em&gt;change&lt;/em&gt; its status, for example, update some records in the database o send a request to another service. The first ones, let's call them &lt;em&gt;external events&lt;/em&gt; because they're triggered by an external actor, maybe the user or an external system consuming our API, these &lt;em&gt;external events&lt;/em&gt; are the ones triggering the second ones, let's call them &lt;em&gt;internal events&lt;/em&gt; because it's the system updating itself. So, &lt;em&gt;external events&lt;/em&gt; trigger &lt;em&gt;internal events&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Now, there are two ways of handling &lt;em&gt;events&lt;/em&gt;, we can either do it via &lt;em&gt;orchestration&lt;/em&gt;, where we have a service which acts as the &lt;em&gt;master&lt;/em&gt; of the transaction, telling all the other services involved in it what to do, what to update. Just like a Conductor does in an Orchestra, it tells all the other musicians (services) when to play they part, how to play it and so on. The other way is more like a &lt;em&gt;choreography&lt;/em&gt;, where given an &lt;em&gt;event&lt;/em&gt; every service knows how to handle it and how to react to it, just like dancers who know how and where to move or what do do when a certain part of the song is played.&lt;/p&gt;

&lt;p&gt;Good architectures are a mix of both approaches and good architects know when to use either of those depending on the business needs and the use case they're modeling. Unfortunately there's no recipe to decide, gaining experience designing systems and making mistakes are the only way to learn, although reading about others experience, having clear concepts on how distributed systems and networks work and a good understanding of the problem at hand we're solving are a good starting point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rely on data, not services
&lt;/h2&gt;

&lt;p&gt;We spoke about &lt;em&gt;low coupling and high cohesion&lt;/em&gt; in &lt;em&gt;microservices&lt;/em&gt; in a previous article, relying on a service to be up in order for some other service to be able to do what it's supposed to do is some form of &lt;em&gt;coupling&lt;/em&gt;, you are letting an independent system fail because another is feeling unwell.&lt;/p&gt;

&lt;p&gt;For services to be independent, every service should have a copy of the data they need to answer at least basic queries, this doesn't mean you'll directly update the copies, you need to define which service is going to be your &lt;em&gt;source of truth&lt;/em&gt; for a specific piece of data and perform all the write operations for it to &lt;strong&gt;that&lt;/strong&gt; service and then, somehow, update the copies. You can rely on &lt;em&gt;internal events&lt;/em&gt; to do this, every time an &lt;em&gt;external event&lt;/em&gt; triggers an update on the &lt;em&gt;source of truth&lt;/em&gt; for a give piece of data, you can fire up an &lt;em&gt;internal event&lt;/em&gt; to make the services keeping a copy update their local copies.&lt;/p&gt;

&lt;p&gt;By doing this you can still serve a read-only version of the data for some use cases even if the source of truth is down, if it's, for example, an e-commerce and the source of truth for the catalog is, for example, the &lt;em&gt;Inventory Service&lt;/em&gt;, you can still serve the catalog even though the users won't be able to purchase anything, they still can save them to their &lt;em&gt;wishlist&lt;/em&gt; and browse the website, this lets you gracefully degrade your system if there are problems with some services, you just show an error message or hide the options or have alternate workflows until the systems supporting the degraded use case are back up and running.&lt;/p&gt;

&lt;p&gt;What if a service is down and misses some updates from the source of truth?, well, depending on how you propagate the updates, you can do several things. You can use a queuing system like &lt;em&gt;ZeroMQ&lt;/em&gt; or &lt;em&gt;RabbitMQ&lt;/em&gt; to propagate the updates, so, if a service is down, the updates will be waiting on the queue to be consumed once the service is up, if you're using HTTP calls, you can have your worker retry the failed requests after a &lt;em&gt;back-off&lt;/em&gt; time or write the payload to a given location so, when the other service comes up, an &lt;em&gt;init&lt;/em&gt; script checks that location, reads whatever is there and marks those messages as &lt;em&gt;consumed&lt;/em&gt;, there are multiple ways to deal with this problem, most of them will depend on the technology you're using.&lt;/p&gt;

&lt;h3&gt;
  
  
  Eventual consistency
&lt;/h3&gt;

&lt;p&gt;When you deal with distributed systems and distributed information, chances are, some copies will be stalled for a period of time, this means, information will always be flowing through the &lt;em&gt;pipes&lt;/em&gt; of your system, the only way you will have total consistency is if you stop writing and wait some time. Even in monolithic systems, what you show to the user is stale most of the time, let's say, for example, a website listing used articles for sale, when the search page is served to the user, depending on the traffic, there will be probably 10ths or hundreds of new articles the user won't see unless they refresh the page or we have a pushing mechanism in place. So, how important is it really to show the most updated information available to the user?, truth is, is not that critical in most cases.&lt;/p&gt;

&lt;p&gt;For building reports though, you should always query from your sources of truth, this could be tricky on a distributed system where your source of truth varies depending on the information you're looking for and it's not a single database where you can run a SQL query and join everything together. You could rely also on &lt;em&gt;internal events&lt;/em&gt; to build a reporting database while the relevant events are happening instead of querying everything when a report is requested, this way you'll always have relevant business data to produce reports on top of.&lt;/p&gt;

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

&lt;p&gt;There's no silver bullet to solve the problems that come with distributed computing, however, there are strategies to help you discover the best way to deal with certain problems for your specific use case, try to use choreography where possible and orchestrate the flows that need to be completely synchronous, always try to find the easiest solution, keep in mind that sometimes the easiest way to solve a problem is the hardest to implement, but benefits will be seen in the future, when you need to debug a failure or scale, or even extend your system with more features or plugging more microservices in.&lt;/p&gt;

&lt;p&gt;Also, always prefer choreography and async communication when possible instead of orchestration and sync calls between services, this doesn't mean you should avoid it at all cost as there are use cases that need that approach. A good architect knows that the best way to solve a problem is not following strictly one and only one approach, it's combining different concepts and ways around it and adapting them to the specific problem to achieve an efficient and elegant solution. &lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended readings
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://amzn.to/2KgY6qh"&gt;Building Microservices&lt;/a&gt; by &lt;a href="https://samnewman.io/"&gt;Sam Newman&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.martinfowler.com/bliki/CircuitBreaker.html"&gt;Circuit Breaker&lt;/a&gt; by Martin Fowler &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://specify.io/concepts/microservices"&gt;Introduction to Microservices&lt;/a&gt; by Oliver Wolf &lt;/li&gt;
&lt;li&gt;
&lt;a href="http://blog.christianposta.com/microservices/why-microservices-should-be-event-driven-autonomy-vs-authority/"&gt;Why Microservices Should be Event Driven&lt;/a&gt; by Christian Posta &lt;/li&gt;
&lt;li&gt;
&lt;a href="https://blog.bernd-ruecker.com/event-command-transformation-in-microservice-architectures-and-ddd-dd07d5eb9656"&gt;Event command transformation in microservice architectures and DDD&lt;/a&gt; by Bernd Rücker
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://iffm.me/my-take-on-microservices.html"&gt;My take on Microservices&lt;/a&gt; by me :-)&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>microservices</category>
      <category>architecture</category>
      <category>systemsdesign</category>
      <category>coding</category>
    </item>
    <item>
      <title>Internal Open Source</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Sun, 28 Feb 2021 06:35:13 +0000</pubDate>
      <link>https://dev.to/iferminm/internal-open-source-5bed</link>
      <guid>https://dev.to/iferminm/internal-open-source-5bed</guid>
      <description>&lt;p&gt;OpenSource software has been out there for quite a long time, the idea of people around the world volunteering part of their time to work on free software is very exciting, but also maintaining those projects is very hard. Keeping everyone on the same page so that there's no duplicated work, agreeing on the road-map and what's going or needs to be done, prioritizing bugs, reviewing code, merging and then, everyone updating their local repos or forks. OpenSource software development is a huge human distributed system which, most of the time, uses async communication due to the inability to get every single developer working on the software in a room or, at least, a virtual call for obvious reasons: timezone, everyone works on different schedules so everyone is free at different times and most of the people also work full time for software companies, most of the time on other projects.&lt;/p&gt;

&lt;p&gt;OpenSource projects and free software development has tons of limitations in the way they can coordinate and communicate with the entire team, and yet OpenSource projects has higher standards and a higher bar than most close-source projects or corporate-internal software built in-house. This is why, whenever I need to do something at work, whenever I need to research for best practices in how to manage a project, how to manage or coordinate a team, how to do anything with tech, I refer to how the team behind my favorite OpenSource project&lt;br&gt;
at the moment is doing things and borrow as many ideas as possible and see how to adapt them to what I'm working on or the team I'm working with. OpenSource has very complex people problems, team members are scattered all around the globe, if their strategies, policies and practices help them solve their problems, they should also work at a smaller scale in private companies building software.&lt;/p&gt;

&lt;h1&gt;
  
  
  The cathedral and the bazaar
&lt;/h1&gt;

&lt;p&gt;The Cathedral and the Bazaar is an essay written by Eric Raymond, in this essay he examines two different approaches to Software Development by two different OpenSource projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Cathedral:&lt;/strong&gt; where the source code is available for each release, this is only the stable code, all the code in between releases and all the work done on top of it is private to the contributors only. In the essay the author cites GCC and GNU Emacs as examples for this approach.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The Bazaar:&lt;/strong&gt; where all the code and the development process is public to all of the internet, in the essay, Raymond cites Linux Torvalds as the inventor of this approach and the Linux Kernel Development as an example of a project built under this method as well as the Fetchmail project.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I won't go deep into the essay as I think it is a must read for every Software Engineer, so, I'll leave some links so that everyone can have a look at it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;TL;DR; you can check the main points on the essay in its &lt;a href="https://en.wikipedia.org/wiki/The_Cathedral_and_the_Bazaar"&gt;Wikipedia page&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;You can also find the full version at the &lt;a href="http://www.catb.org/~esr/writings/cathedral-bazaar/"&gt;official website&lt;/a&gt; along with other interesting writings by Eric Raymond&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key points
&lt;/h2&gt;

&lt;p&gt;The key highlights from the article, also mentioned in the Wikipedia page, are summarized in the following 19 lessons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Every good work of software starts by scratching a developer's personal itch.&lt;/li&gt;
&lt;li&gt;Good programmers know what to write. Great ones know what to rewrite (and reuse).&lt;/li&gt;
&lt;li&gt;Plan to throw one [version] away; you will, anyhow. (Copied from Frederick Brooks' The Mythical Man-Month)&lt;/li&gt;
&lt;li&gt;If you have the right attitude, interesting problems will find you.&lt;/li&gt;
&lt;li&gt;When you lose interest in a program, your last duty to it is to hand it off to a competent successor.&lt;/li&gt;
&lt;li&gt;Treating your users as co-developers is your least-hassle route to rapid code improvement and effective debugging.&lt;/li&gt;
&lt;li&gt;Release early. Release often. And listen to your customers.&lt;/li&gt;
&lt;li&gt;Given a large enough beta-tester and co-developer base, almost every problem will be characterized quickly and the fix obvious to someone.&lt;/li&gt;
&lt;li&gt;Smart data structures and dumb code works a lot better than the other way around.&lt;/li&gt;
&lt;li&gt;If you treat your beta-testers as if they're your most valuable resource, they will respond by becoming your most valuable resource.&lt;/li&gt;
&lt;li&gt;The next best thing to having good ideas is recognizing good ideas from your users. Sometimes the latter is better.&lt;/li&gt;
&lt;li&gt;Often, the most striking and innovative solutions come from realizing that your concept of the problem was wrong.&lt;/li&gt;
&lt;li&gt;Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away. (Attributed to Antoine de Saint-Exupéry)&lt;/li&gt;
&lt;li&gt;Any tool should be useful in the expected way, but a truly great tool lends itself to uses you never expected.&lt;/li&gt;
&lt;li&gt;When writing gateway software of any kind, take pains to disturb the data stream as little as possible—and never throw away information unless the recipient forces you to!&lt;/li&gt;
&lt;li&gt;When your language is nowhere near Turing-complete, syntactic sugar can be your friend.&lt;/li&gt;
&lt;li&gt;A security system is only as secure as its secret. Beware of pseudo-secrets.&lt;/li&gt;
&lt;li&gt;To solve an interesting problem, start by finding a problem that is interesting to you.&lt;/li&gt;
&lt;li&gt;Provided the development coordinator has a communications medium at least as good as the Internet, and knows how to lead without coercion, many heads are inevitably better than one.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  My own views
&lt;/h1&gt;

&lt;p&gt;While Eric Raymond's essay covers different approaches to open source development which can be also used in the industry, inside software companies,&lt;br&gt;
I see something very common within open source projects, they all produce high quality documentation, not only because they want people to use it&lt;br&gt;
but also because they want people to be able to collaborate and contribute without taking too much time from active developers who are volunteering&lt;br&gt;
to work on the project. This approach to on-boarding new contributors is very powerful and can benefit a lot any team working on software projects&lt;br&gt;
in any company.&lt;/p&gt;

&lt;p&gt;Having high quality documentation can help mainly in two things:&lt;/p&gt;

&lt;h2&gt;
  
  
  On-boarding new team members
&lt;/h2&gt;

&lt;p&gt;How many times have you repeated yourself over and over and over again when a new engineer joins your team, walking them through&lt;br&gt;
the architecture, the code, setup the local development environment and then helping them ramp up on the tools used in the team.&lt;/p&gt;

&lt;p&gt;This walk-through can be easily delegated to documentation pages maintained and updates by the team, just the same way OpenSource projects&lt;br&gt;
do it, they have a section on their docs specialized in helping new contributors getting started, it also explains how to update the docs, so&lt;br&gt;
that if any new contributor finds a mistake, something that's not up to date or something that needs to be documented, they can just edit&lt;br&gt;
the wiki and fix it or add whatever is needed. This way the next person to be on-boarded won't face those issues.&lt;/p&gt;

&lt;h2&gt;
  
  
  Empower other teams to contribute
&lt;/h2&gt;

&lt;p&gt;It's a common case to have internal services which are only used by other services maintained by other teams, these are called platform services,&lt;br&gt;
they commonly abstract underlying resources needed by public-facing services, also, it's common to have public services relying on each other or&lt;br&gt;
exposing endpoints so that other services request or update transactional data, which means, other teams might require features to be&lt;br&gt;
built in other services by other teams for internal consumption.&lt;/p&gt;

&lt;p&gt;In a normal scenario, both teams will have to coordinate and align on deliverable, prioritize and iterate over and over again, often, priorities&lt;br&gt;
change and everything needs to be reevaluated. If you follow any inner source pattern, whether you give access to the stable code or all of it,&lt;br&gt;
plus high quality documentation for new contributors, the other team can easily contribute to the service in question and build the feature they need&lt;br&gt;
by themselves. Of course, you need to also make it easier for them by providing clear guidelines and policies on how to contribute, the code&lt;br&gt;
conventions used in your team's project and making sure the team knows them and enforce them, after all they'll be the ones maintaining that code&lt;br&gt;
after it gets merged.&lt;/p&gt;

&lt;p&gt;I've implemented this in some of my teams and the relieve of flipping the responsibilities to support internal use cases to the team requesting the&lt;br&gt;
features is amazing. We've only had to give them links to our docs, help them update it wherever it was not and have them add whatever they thought&lt;br&gt;
could be useful, then, during development it only requires code review, 80% of the effort relies on the team building the feature they need on the&lt;br&gt;
service your team maintains while you only support them with code review and, maybe, QA, but if the feature is with them their QA team should be thew&lt;br&gt;
one having more clarity on the use case and, hence, the test cases needed to be covered.&lt;/p&gt;

&lt;p&gt;It's very convenient, it unblocks other teams which need custom features for internal consumption to be built as they don't need to wait for your team&lt;br&gt;
to be free to do it, risking their deadlines on priority changes on your end while also lets your team focus on whatever priorities are there for&lt;br&gt;
them. It only requires some time to put the documentation in place and review the code being pull requested by the contributing team.&lt;/p&gt;

&lt;p&gt;Does this sound like something you might want to try?&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>documentation</category>
      <category>career</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Guiding principles to build scalable microservices architectures</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Mon, 08 Feb 2021 03:46:03 +0000</pubDate>
      <link>https://dev.to/iferminm/my-take-on-microservices-4jod</link>
      <guid>https://dev.to/iferminm/my-take-on-microservices-4jod</guid>
      <description>&lt;p&gt;There's been a lot of stuff going on these days on &lt;em&gt;Software Engineering&lt;/em&gt;, it's hard to catch up on everything I would like to. I try to go one topic at a time and now, also because we are working with this at the office, I'm hooked into microservices.&lt;/p&gt;

&lt;p&gt;Microservices is a new word for an old concept, a concept I thought I will never see or play with in real life  back in my University years, I remember my &lt;em&gt;Software Engineering&lt;/em&gt; and &lt;em&gt;Distributed Systems&lt;/em&gt; professors talking about web services and &lt;em&gt;API*s and huge systems at IBM, Sun Microsystems and Oracle, SOAP and REST interfaces and how they interacted with each other and, also, the mighty Enterprise Service Bus with producers and consumers in Java, BPEL and C#, a very abstract concept for me to grasp at that time and I thought **the only place&lt;/em&gt;* you could see that was working at &lt;strong&gt;huge&lt;/strong&gt;, corporate companies like the ones I mentioned above.&lt;/p&gt;

&lt;p&gt;Nowadays, &lt;strong&gt;any&lt;/strong&gt; internet &lt;em&gt;startup&lt;/em&gt; can grow at a &lt;strong&gt;huge scale&lt;/strong&gt; and you can play around with this kind of technologies if you're lucky enough to be part of one of those projects.&lt;/p&gt;

&lt;p&gt;I was lucky to be part of the &lt;em&gt;dubizzle&lt;/em&gt; team, a classifieds website that operates at a &lt;strong&gt;massive scale&lt;/strong&gt; here in the middle east, the architecture is a huge legacy &lt;strong&gt;monolithic application&lt;/strong&gt; with all of the core functionality and several satellite services surrounding this legacy app. These services are, in my opinion, mostly &lt;strong&gt;poorly integrated&lt;/strong&gt; and fault tolerance &lt;strong&gt;is not the rule&lt;/strong&gt;, sometimes error responses are silenced and bypassed which is quite bad. Also, the integration goes over &lt;em&gt;HTTP&lt;/em&gt;, which could be very unreliable even within the internal network and gives you a lot of headaches when you need to integrate more and more services. But the whole point of migrating to &lt;em&gt;microservices&lt;/em&gt; is to solve all those issues and have a better engineered platform to keep both product and tech as happy as possible and be able to move faster at the same time.&lt;/p&gt;

&lt;p&gt;We dedicated some time now to study &lt;strong&gt;best practices&lt;/strong&gt; for implementing a microservices based architecture and built some proof of concepts and deployed one of them to production here are some of my key learning and good practices taken from what I've read and personal experience actually building stuff at &lt;em&gt;dubizzle&lt;/em&gt; and playing around with technology on my personal projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  APIs should be business bounded
&lt;/h2&gt;

&lt;p&gt;It's a common mistake to build APIs as simple &lt;em&gt;CRUD&lt;/em&gt; interfaces for &lt;em&gt;domain entities&lt;/em&gt;. This means, all the &lt;em&gt;business logic&lt;/em&gt; must be written and rewritten in the &lt;em&gt;clients&lt;/em&gt;, so, if you have, for instance, a &lt;em&gt;web client&lt;/em&gt;, a &lt;em&gt;desktop application&lt;/em&gt;, an &lt;em&gt;Android&lt;/em&gt; and an &lt;em&gt;iPhone&lt;/em&gt; mobile apps, well, you can count yourself how many times you'll have to write the &lt;em&gt;business logic&lt;/em&gt; surrounding those &lt;em&gt;data models&lt;/em&gt; with a &lt;em&gt;CRUD API&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You have to build your API to encapsulate business processes, not just the objects creation and manipulation, so a single &lt;em&gt;API&lt;/em&gt; call, triggers all the needed processes to fulfill the request or the query the client just gave to the server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Services must be independent units
&lt;/h2&gt;

&lt;p&gt;This means, &lt;strong&gt;you must think&lt;/strong&gt; of each &lt;em&gt;microservice&lt;/em&gt; as a project or a &lt;em&gt;product&lt;/em&gt; on its own, this means each &lt;em&gt;service&lt;/em&gt; has its own &lt;em&gt;box&lt;/em&gt; and its own &lt;em&gt;release pipeline&lt;/em&gt; and its own &lt;em&gt;life cycle&lt;/em&gt;, but also, they don't rely on each other to function. This means, if your &lt;em&gt;invoicing service&lt;/em&gt; is down, your &lt;em&gt;payment service&lt;/em&gt; &lt;strong&gt;don't need to suffer&lt;/strong&gt; because of this, you can always accept payments from your users and send the invoices later, when your &lt;em&gt;invoicing service&lt;/em&gt; comes up again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Rely on data, not services
&lt;/h2&gt;

&lt;p&gt;In the previous example you might be thinking "dude, but if the &lt;em&gt;invoicing service&lt;/em&gt; is down when the &lt;em&gt;payment service&lt;/em&gt; hits it, how will it know it needs to send an invoice to a user?". Well, you need some way to let it know once it wakes up, some &lt;em&gt;data sharing&lt;/em&gt; mechanism like a shared database (which is in general a bad idea because it creates &lt;em&gt;coupling&lt;/em&gt; between our services) or some sort of &lt;em&gt;caching&lt;/em&gt; on the services that needs to &lt;em&gt;consume&lt;/em&gt; that data.&lt;/p&gt;

&lt;p&gt;In our example, we could make the &lt;em&gt;payment service&lt;/em&gt; and the &lt;em&gt;invoicing service&lt;/em&gt; share the same database, or, have a good separation of concerns and lower the &lt;em&gt;coupling&lt;/em&gt; and, since &lt;em&gt;invoicing&lt;/em&gt; needs to know about &lt;em&gt;payments&lt;/em&gt; but, &lt;em&gt;payments&lt;/em&gt; have no need to know about &lt;em&gt;invoicing&lt;/em&gt;, we can just have a &lt;em&gt;caching&lt;/em&gt; mechanism in place in our &lt;em&gt;invoicing service&lt;/em&gt; and have a copy of the needed data about &lt;em&gt;payments&lt;/em&gt; in order to generate &lt;em&gt;invoices&lt;/em&gt;, of course, this will add some complexity to our system because we need to be fault tolerant and make sure the data still reaches the &lt;em&gt;cache&lt;/em&gt; if the &lt;em&gt;invoicing service&lt;/em&gt; is down and we need to put some cache update processes in order to keep it up to date.&lt;/p&gt;

&lt;h2&gt;
  
  
  High cohesion, low coupling
&lt;/h2&gt;

&lt;p&gt;This is a principle borrowed from &lt;em&gt;Object Oriented Programming&lt;/em&gt;, let's remember what they mean&lt;/p&gt;

&lt;h3&gt;
  
  
  Coupling
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;coupling&lt;/strong&gt; is the degree of interdependence between software modules.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;This means, if two &lt;em&gt;modules&lt;/em&gt;, &lt;em&gt;functions&lt;/em&gt; or &lt;em&gt;services&lt;/em&gt; rely too much on each other, chances are if I make a change on one, I'll have to make a change on the other one to compensate, this makes our code and architecture less orthogonal, which means exactly that, a change in one part of the system, will affect other unrelated parts, just like driving a helicopter.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cohesion
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;cohesion&lt;/strong&gt; refers to the degree to which the elements inside a module belong together.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Wikipedia&lt;/p&gt;
&lt;/blockquote&gt;


&lt;/blockquote&gt;

&lt;p&gt;This means, it's a measure of how much the &lt;em&gt;elements&lt;/em&gt; inside a &lt;em&gt;module&lt;/em&gt; belong together, not necessarily they rely on each other, but they all &lt;strong&gt;work together&lt;/strong&gt; towards a common objective.&lt;/p&gt;

&lt;p&gt;In general &lt;em&gt;cohesion&lt;/em&gt; is increased if:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;All the &lt;em&gt;elements&lt;/em&gt; in the &lt;em&gt;module&lt;/em&gt; have much in common. This means, access the same set of data, for example.&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;elements&lt;/em&gt; in the &lt;em&gt;module&lt;/em&gt; carry out a &lt;strong&gt;small&lt;/strong&gt; number of &lt;strong&gt;related&lt;/strong&gt; activities. This means, each member of the module does one and only one thing related to the task without side effects
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By keeping &lt;strong&gt;related functionality&lt;/strong&gt; together, we are automatically increasing &lt;em&gt;cohesion&lt;/em&gt; and lowering &lt;em&gt;coupling&lt;/em&gt;, and this is exactly what we want.&lt;/p&gt;

&lt;h3&gt;
  
  
  What does this mean in microservices?
&lt;/h3&gt;

&lt;p&gt;Well, it's easy to think of &lt;em&gt;coupling&lt;/em&gt; and &lt;em&gt;cohesion&lt;/em&gt; withing the same computer program or the same code base, but in &lt;em&gt;microservices&lt;/em&gt; this means exactly the same, &lt;strong&gt;keep related functionality together&lt;/strong&gt; so you don't have that logic spread all over the place and duplicated in more than one service. This also mean, keep services using similar or related data together, either logically or physically.&lt;/p&gt;

&lt;h2&gt;
  
  
  One hit, one transaction
&lt;/h2&gt;

&lt;p&gt;This means, avoid distributed transaction at all costs, they are difficult to implement and even more difficult to debug if something goes wrong, ideally one &lt;em&gt;write&lt;/em&gt; operation to your system should directly affect &lt;strong&gt;one&lt;/strong&gt; service, what happens &lt;em&gt;offline&lt;/em&gt; could be a different story. For example, we could have our &lt;em&gt;payments service&lt;/em&gt; which deals with a third party payment gateway to charge our users' credit cards, to keep things under &lt;em&gt;Single Responsibility Pattern&lt;/em&gt; (SRP), we will have a separate &lt;em&gt;invoicing service&lt;/em&gt; which handles generating and sending invoices to the users (I know, we could separate things even more by having a separate &lt;em&gt;notification service&lt;/em&gt; that handles sending the emails but let's keep it at this level for the sake of simplicity). &lt;/p&gt;

&lt;p&gt;So, the only thing my client needs to know is &lt;em&gt;I need to make a payment&lt;/em&gt;, whatever happens afterwards it's not my client's problem, it only needs to hit the &lt;em&gt;payments service&lt;/em&gt; with the needed &lt;em&gt;payload&lt;/em&gt; and get the response to show it to the user. What happens under the hood is my &lt;em&gt;payments service&lt;/em&gt;'s problem, it needs to &lt;em&gt;somehow&lt;/em&gt; notify the &lt;em&gt;invoicing service&lt;/em&gt; that it needs to email an invoice to a specific user, this has to happen &lt;em&gt;offline&lt;/em&gt;, either we start a separate &lt;em&gt;thread&lt;/em&gt; or use a message queue for it and we notify either generating an &lt;em&gt;event&lt;/em&gt; or via an &lt;em&gt;HTTP&lt;/em&gt; call, but this needs to happen offline and be fault tolerant so we don't keep the &lt;em&gt;client&lt;/em&gt; waiting for something that is &lt;em&gt;our&lt;/em&gt; internal process, as well as updating the inventory, generating accounting ledger entries, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choreography over orchestration
&lt;/h2&gt;

&lt;p&gt;This is, to me, one of the most important best practices I've learned then it comes to microservices oriented architecture, when we think of distributed transactions we often have some sort of &lt;em&gt;director&lt;/em&gt; or &lt;em&gt;conductor&lt;/em&gt;, which is the service that initiated the transaction, it will know, what needs to happen and in which order, also, it will be the responsible to roll everything back if any part of the transaction fails, transactions need to be &lt;em&gt;Atomic&lt;/em&gt;, right?. This is a very dangerous approach because, if something goes wrong while performing the transaction, nothing can guarantee something won't happen while rolling it back, leaving the system in an inconsistent state and giving us lots of headaches down the road when having to debug some weird behavior in our system.&lt;/p&gt;

&lt;p&gt;The best way to implement these kind of &lt;em&gt;distributed&lt;/em&gt; transactions, i.e., business processes that need to update more than one service is through &lt;em&gt;Choreography&lt;/em&gt;, if you think about a &lt;em&gt;choreography&lt;/em&gt;, there's no &lt;em&gt;conductor&lt;/em&gt;, everyone knows what they need to do, where they need to go, the only signal is the music. This means, in &lt;em&gt;microservices&lt;/em&gt;, we just need to &lt;em&gt;notify&lt;/em&gt; everyone &lt;em&gt;something&lt;/em&gt; happened, and the concerning &lt;em&gt;services&lt;/em&gt; will react accordingly, either updating their database, emitting another &lt;em&gt;event&lt;/em&gt; or sending a notification to the user.&lt;/p&gt;

&lt;p&gt;In order to properly implement &lt;em&gt;choreography&lt;/em&gt; we need to build &lt;em&gt;resilient&lt;/em&gt; services by putting in place fault tolerance logic or processes so, if some service fails to react, it can heal itself or someone gets notified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't rely on HTTP
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/L._Peter_Deutsch"&gt;Peter Deutsch&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/James_Gosling"&gt;James Gosling&lt;/a&gt; wrote about the&lt;br&gt;
&lt;em&gt;8 fallacies of distributed computing&lt;/em&gt; and the first one was&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The network is reliable&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A million things can happen when you rely on the network, maybe the requests times out, maybe there's a broken link, maybe subnet permissions were changed maybe the host we are trying to reach is unavailable, maybe a rat ate a network cable, lots of things can happen and we are not in control of all of them, even within our own private network.&lt;/p&gt;

&lt;p&gt;What I'd recommend instead is to have a &lt;em&gt;communication layer&lt;/em&gt; in the form of a &lt;em&gt;message bus&lt;/em&gt;, it can be a &lt;em&gt;queue&lt;/em&gt; like &lt;a href="https://www.rabbitmq.com/"&gt;RabbitMQ&lt;/a&gt; or a &lt;em&gt;data streaming pipeline&lt;/em&gt; like &lt;a href="https://kafka.apache.org/"&gt;Apache Kafka&lt;/a&gt; of course there will be a bit of network communication between your services and the communication layer, or your services and the database system, but that's being taken care of by the corresponding drivers or libraries or deal with those, so, you can assume they're fault tolerant and the data will reach its destination.&lt;/p&gt;

&lt;p&gt;There will be cases where you can't avoid rely on &lt;em&gt;HTTP&lt;/em&gt; or any network protocol, for example, you need to serve your website somehow, and you need to query your services somehow too, so, in this case I'd recommend to go for a &lt;em&gt;REST API&lt;/em&gt; or whatever protocol you prefer for external communication (third party services and &lt;em&gt;client-server&lt;/em&gt;) and using a &lt;em&gt;message bus&lt;/em&gt; for inter-service communication.&lt;/p&gt;

&lt;h3&gt;
  
  
  A note about the fallacies
&lt;/h3&gt;

&lt;p&gt;Some people will say that the &lt;em&gt;8 fallacies of distributed computing&lt;/em&gt; are obsolete nowadays because there are tools already that handle everything for us, replication, secure networking, authentication, networks are sophisticated so, latency is not a problem anymore but, just because &lt;em&gt;someone&lt;/em&gt; is taking care of &lt;em&gt;something&lt;/em&gt; for us, doesn't mean that &lt;em&gt;something&lt;/em&gt; isn't there, imagine building a system without these tools, you'll have to face them anyways, besides, there are countries where the computer networks are not as good as in the US or Europe for example, so, I wouldn't say these &lt;em&gt;fallacies&lt;/em&gt; are becoming irrelevant. Even if you're not implementing replication or security yourself, you need to think about it and use &lt;em&gt;something&lt;/em&gt; that handles that for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recommended readings
&lt;/h2&gt;

&lt;p&gt;Check the post in by blog to find out where to go to know more about microservices.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://iffm.me/my-take-on-microservices.html"&gt;http://iffm.me/my-take-on-microservices.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>microservices</category>
      <category>architecture</category>
      <category>coding</category>
      <category>systemsdesign</category>
    </item>
    <item>
      <title>Scaling django: measuring your django app's performance</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Mon, 01 Feb 2021 11:27:14 +0000</pubDate>
      <link>https://dev.to/iferminm/scaling-django-2-profiling-your-django-app-4in6</link>
      <guid>https://dev.to/iferminm/scaling-django-2-profiling-your-django-app-4in6</guid>
      <description>&lt;p&gt;It's been a while since the &lt;a href="https://iffm.me/making-django-scale-pt1.html" rel="noopener noreferrer"&gt;first post&lt;/a&gt; about scaling web applications using &lt;em&gt;django&lt;/em&gt;, last time we spoke about some basic concepts about scalability, buzz words we hear everyday and we also use but always struggle when we need to give a formal definition to someone.&lt;/p&gt;

&lt;p&gt;Once we have clear basic concepts about scalability, performance and we are familiar with the Pareto Principle, we are ready to start optimizing and improving our system's performance, right?. Not so fast cowboy!, if you remember the Pareto Principle most of the negative performance impact is coming for 20% of the negative impacters. We need to manage somehow to solve that 20% so we are sure we are making a significant improvement.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You can't manage what you don't measure&lt;/em&gt; - Peter Ducker&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means, we need to gain visibility inside our system to be able to detect those bottlenecks and  work on solving or easing them. For that, we will need a set of tools to monitor and profile our application.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tools
&lt;/h2&gt;

&lt;p&gt;There are a lot of monitoring tools for Linux and for &lt;em&gt;django&lt;/em&gt; out there, you can use the ones you like the most, but I'm going to showcase some here as a starting point. I'm not going to go deep into how to install them and set them up or customize them because it's out of the scope of this post, but I might post some individual howtos later, here I'll just point you to the corresponding documentation.&lt;/p&gt;

&lt;h3&gt;
  
  
  django debug toolbar
&lt;/h3&gt;

&lt;p&gt;This is my all time favorite, it's a pip-installable module for &lt;em&gt;django&lt;/em&gt; and you'll need to add some settings variables and a template tag and you're done.&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%2Fdl.dropboxusercontent.com%2Fs%2Fbykbb9iryv1m6io%2Fdjango_debug_toolbar.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%2Fdl.dropboxusercontent.com%2Fs%2Fbykbb9iryv1m6io%2Fdjango_debug_toolbar.png" alt="Image of django-debug-toolbar"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see on the screenshot it will give you a lot of relevant information about what happened under the hood to serve that request, it will tell you the missed cache hits, which static files and templates are being served, the current request headers and request parameters but my favorite feature is the SQL viewer, it will show you the queries that ran on that view, with a timeline and their run time so you get to see which ones are taking long time and take action, it gives you also the option to see an &lt;code&gt;EXPLAIN&lt;/code&gt; of the query to check what the query planner did.&lt;/p&gt;

&lt;p&gt;To install it and use it, you can refer to the &lt;a href="https://django-debug-toolbar.readthedocs.io/en/stable/" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  vprof
&lt;/h3&gt;

&lt;p&gt;This is a visual profiler for &lt;em&gt;Python&lt;/em&gt;, although it isn't made for &lt;em&gt;django&lt;/em&gt;, you can plug it in and take advantage of all the cool graphs it will draw for you out of the box.&lt;/p&gt;

&lt;p&gt;A profiler will measure how your code is behaving and tell you where the hot points are as well as your call stack, vprof will give you an insight also on how much memory your program is consuming so it's easier to detect memory leaks.&lt;/p&gt;

&lt;p&gt;Here are some of the graphs &lt;em&gt;vprof&lt;/em&gt; will produce for you&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flame diagram to allow you see your function call stack
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdl.dropboxusercontent.com%2Fs%2Flvi3sxxhgmjccax%2Fvprof_flame_diagram.png" alt="*vprof* flame diagram"&gt;
&lt;/li&gt;
&lt;li&gt;Memory profiler
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdl.dropboxusercontent.com%2Fs%2Fzv1o87ebms7humr%2Fvprof_mem_profiler.png" alt="*vprof* memory profiler"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To set it up you can refer to the &lt;a href="https://github.com/nvdv/vprof" rel="noopener noreferrer"&gt;official docs&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  CProfile
&lt;/h3&gt;

&lt;p&gt;Setting up &lt;em&gt;vprof&lt;/em&gt; for &lt;em&gt;django&lt;/em&gt; might be tricky depending of your application architecture and setup, &lt;em&gt;CProfile&lt;/em&gt; is pretty much the defacto standard on &lt;em&gt;Python&lt;/em&gt; profilers, it will produce an output on an standard format you can plug into any profiling reporting tool such as &lt;em&gt;SnakeViz&lt;/em&gt; to produce cool graphs that will help you understand what's going on.&lt;/p&gt;

&lt;p&gt;You can easily set it up in &lt;em&gt;django&lt;/em&gt; by using &lt;em&gt;&lt;a href="https://github.com/omarish/django-cprofile-middleware" rel="noopener noreferrer"&gt;django-cprofile-middleware&lt;/a&gt;&lt;/em&gt; this app will also add one endpoint any &lt;em&gt;staff&lt;/em&gt; user can hit to get data about the performance and, also, &lt;em&gt;CProfile&lt;/em&gt; can produce an output file you can pipe into &lt;em&gt;&lt;a href="http://jiffyclub.github.io/snakeviz/" rel="noopener noreferrer"&gt;SnakeViz&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This is how &lt;em&gt;SnakeViz&lt;/em&gt; graphs would 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%2Fdl.dropboxusercontent.com%2Fs%2F0uxf12rxx562t6z%2Fsnake_list_view.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%2Fdl.dropboxusercontent.com%2Fs%2F0uxf12rxx562t6z%2Fsnake_list_view.png" alt="*SnakeViz* list view"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdl.dropboxusercontent.com%2Fs%2Fhx9cfdxvn1dqq4o%2Fsnake_sun_diagram.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%2Fdl.dropboxusercontent.com%2Fs%2Fhx9cfdxvn1dqq4o%2Fsnake_sun_diagram.png" alt="*SnakeViz* sunburst diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  StatsD
&lt;/h3&gt;

&lt;p&gt;This is an external stats collecting system built by &lt;em&gt;Etsy&lt;/em&gt;, they &lt;a href="https://codeascraft.com/2011/02/15/measure%20anything-measure-everything/" rel="noopener noreferrer"&gt;blogged&lt;/a&gt; about it and how it works and it's also &lt;a href="https://github.com/etsy/statsd" rel="noopener noreferrer"&gt;open source&lt;/a&gt;, you can set it up in &lt;em&gt;django&lt;/em&gt; through a third party app called &lt;a href="http://django-statsd.readthedocs.io/en/latest/" rel="noopener noreferrer"&gt;django-statsd&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Using this is a bit manual, you will need to send out your stats the same way you use log statements to add entries with messages about what your system is going. In this case what StatsD will do is keep a log on counts and timing of the events you are sending stats about.&lt;/p&gt;

&lt;p&gt;The coolest thing about &lt;em&gt;StatsD&lt;/em&gt; is that you can set it up to periodically flush data to &lt;a href="http://graphiteapp.org/" rel="noopener noreferrer"&gt;&lt;em&gt;Graphite&lt;/em&gt;&lt;/a&gt; where you can then produce this kind of graphs on top of &lt;em&gt;StatsD&lt;/em&gt;'s data&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%2Fdl.dropboxusercontent.com%2Fs%2Fmns9m1htvqvxr5k%2Fgraphite.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%2Fdl.dropboxusercontent.com%2Fs%2Fmns9m1htvqvxr5k%2Fgraphite.jpg" alt="*Graphite* dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Use the logging subsystem
&lt;/h3&gt;

&lt;p&gt;Logging can save you a lot of time if you do it right, it can also clutter your code with &lt;code&gt;logger.info()&lt;/code&gt; statements everywhere if you over do it, you need to log everything so you know what your app is doing at each step of the different processes it performs, but log even more on the critical ones.&lt;/p&gt;

&lt;p&gt;These log files need to go somewhere, maybe you're familiar with &lt;a href="https://syslog-ng.org/" rel="noopener noreferrer"&gt;syslog&lt;/a&gt; to concentrate your logs in a single server so you have only one place to go when you need to do some text-processing-fu with &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, &lt;code&gt;sort&lt;/code&gt; and &lt;code&gt;grep&lt;/code&gt;, but as your system grows and also the amount of different loggers storing messages, it will get trickier and trickier to keep track of every action across all the different modules of your system, an &lt;em&gt;ELK&lt;/em&gt; system can help you to ease the search through your log files and also generate reports and graphs on top of your log data using &lt;em&gt;Kibana&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You can read more about the &lt;em&gt;ELK&lt;/em&gt; or &lt;em&gt;Elastic&lt;/em&gt; stack &lt;a href="https://www.elastic.co/webinars/introduction-elk-stack" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  newrelic
&lt;/h3&gt;

&lt;p&gt;If you have some budget to invest on this, &lt;a href="http://newrelic.com" rel="noopener noreferrer"&gt;&lt;em&gt;newrelic&lt;/em&gt;&lt;/a&gt; will give you most of these features out of the box just by installing and setting up their &lt;em&gt;Python&lt;/em&gt; tracker, it will start pushing data to &lt;em&gt;newrelic&lt;/em&gt; and you can see your system's performance in real time, it will show you data such as the average response time as well as response time in percentiles, average throughput, average error rate, error data and even transaction data like the one you get from &lt;em&gt;django-debug-toolbar&lt;/em&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;newrelic&lt;/em&gt;'s main dashboard&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdl.dropboxusercontent.com%2Fs%2Fzs0m9ozgktnhl1n%2Fnewrelic_main.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%2Fdl.dropboxusercontent.com%2Fs%2Fzs0m9ozgktnhl1n%2Fnewrelic_main.png" alt="*newrelic* main dashboard"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transactions dashboard&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdl.dropboxusercontent.com%2Fs%2Fvuxlqnexow0srj8%2Fnewrelic_transactions.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%2Fdl.dropboxusercontent.com%2Fs%2Fvuxlqnexow0srj8%2Fnewrelic_transactions.png" alt="*newrelic* transactions dashboard"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Errors dashboard&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdl.dropboxusercontent.com%2Fs%2Fiw0zhoum8hv60xw%2Fnewrelic_errors.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%2Fdl.dropboxusercontent.com%2Fs%2Fiw0zhoum8hv60xw%2Fnewrelic_errors.png" alt="*newrelic* errors dashboard"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have the budget, &lt;em&gt;newrelic&lt;/em&gt; is a &lt;em&gt;no-brainer&lt;/em&gt; it will be a valuable tool for you and your team and save you a lot of time when you need to debug a live issue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final words
&lt;/h2&gt;

&lt;p&gt;Before you even think of optimizing anything, you need to measure, there is no point in blindly going through the code and, for example, indexing fields in your models if you don't know the impact of that, if any at all. The tools mentioned here are not a definitive guide to profiling &lt;em&gt;django&lt;/em&gt; applications but they provide a nice starting point to begging playing with them and choosing which ones work for you and which ones doesn't so you can improve your tool belt, your stack and the quality of the products you're building.&lt;/p&gt;

&lt;p&gt;Monitoring and measuring shouldn't be an optional thing, it should be there if not since day one, at least added within the first months of life of your project, that's the only way you get to see inside your application, detect bottlenecks and potential bugs, debug them, measure their impact, prioritize them and be sure that by rolling out the optimizations you will have an improvement of ~X percent in your performance.&lt;/p&gt;

</description>
      <category>django</category>
      <category>scalability</category>
      <category>python</category>
      <category>coding</category>
    </item>
    <item>
      <title>Scaling django: basic concepts</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Mon, 25 Jan 2021 06:36:06 +0000</pubDate>
      <link>https://dev.to/iferminm/scaling-django-part-1-basic-concepts-3a25</link>
      <guid>https://dev.to/iferminm/scaling-django-part-1-basic-concepts-3a25</guid>
      <description>&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=k520PnB-xHox"&gt;I gave a talk on PyCon Balkan&lt;/a&gt; scaling django, obviously on a 35min talk you don't have enough time to outline all the strategies and go deeper, so I thought it might be a cool idea to write a series of blog posts  about this topic, not only to help someone who needs to optimize his django app, but also to help myself have it for future reference.&lt;/p&gt;

&lt;p&gt;There are a lot of django apps out there, in most cases the default setup and basic deployment strategy would be fine, and your application will perform OK, but in some cases you will need to make it scale to serve thousands or millions of requests per day. There's no recipe for optimization or scalability, but there are a lot of technology or stack agnostic strategies you can use to make your systems scale well, here I'll show how to implement them with django.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic concepts
&lt;/h2&gt;

&lt;p&gt;First things first, we need to have clear and solid concepts in mind, we use these words on a daily basis if we're Software Engineers but when we need to say what they mean we sometimes struggle, so, I'll write them down here for future reference.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Scalability is the capability of a system or process to handle a growing amount of work or its potential&lt;br&gt;
to be enlarged to accommodate it&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wikipedia&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;What this means is the amount of work processed by a system must grow in proportion to how much it is enlarged, for example, if I have a cashier at a bank, and that cashier is able to serve 10 people per minute, if I add one more cashier to my system, it should be able to serve rightly 20 people per minute depending on the training of the other cashier and some other conditions. Luckily, servers are more homogenize than people's abilities, for servers or applications, if I have a service that handles 1000 requests per minute, if I add another instance of the same service I should be able to handle 2000 requests per minute.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Computer performance&lt;/em&gt; is the amount of work accomplished by a computer system.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Wikipedia&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;You usually want to measure performance by some metric, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Response time:&lt;/em&gt; which you want to minimize&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Throughput:&lt;/em&gt; throughput is the rate of processing work, this one you want to maximize&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Resource utilization:&lt;/em&gt; which you want to minimize, you want to accomplish more with less&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Availability:&lt;/em&gt; you want to maximize your uptime&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The performance metrics are relative to the type of system you're building, for web applications you usually go for low response time and high throughput.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pareto principle
&lt;/h3&gt;

&lt;p&gt;This isn't actually a concept, but it is incredible how things always turn out like this. The Pareto principle states what follows:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;For many events, roughly 80% of the effects come from 20% of the causes&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, 80% of the work will be done in 20% of the time, the other 80% will be spent on small issues or small tangential work not directly related to the main objective. 80% of the bugs is caused by 20% of the code and, in this case, 80% of the performance impact is caused by 20% of the issues.&lt;/p&gt;

&lt;p&gt;This is interesting because it makes you see that not all issues affect your system's performance the same way, there are some issues that are more serious and not necessarily the same issue on a different project will impact it the same way. Find that 20% and gain an 80% on performance, sounds easy, right?, but it isn't.&lt;/p&gt;

&lt;h3&gt;
  
  
  Takeaways
&lt;/h3&gt;

&lt;p&gt;As a Software Engineer, sometimes I become so obsessed about performance I sometimes write things &lt;em&gt;already optimized&lt;/em&gt;, this is a big fallacy and a huge mistake, premature optimization is bad because you don't know if what you're doing is actually going to have a significative impact on your system's performance, blind optimization is worse, because you might have some ways to get data or an insight on how your program is running but you're just too naive or lazy to go get it.&lt;/p&gt;

&lt;p&gt;In the following posts, I'll recommend some tools to measure and later on some strategies to make your django site scale, so, what you'll see in part 2 will be a set of tools to monitor your app's health.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;My talk in PyCon Balkan: &lt;a href="https://www.youtube.com/watch?v=k520PnB-xHox"&gt;https://www.youtube.com/watch?v=k520PnB-xHox&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't forget to follow me, I'm also in twitter: &lt;a href="https://twitter.com/iferminm"&gt;https://twitter.com/iferminm&lt;/a&gt;&lt;/p&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>scalability</category>
      <category>concepts</category>
    </item>
    <item>
      <title>Quick and easy user registration with django</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Thu, 21 Jan 2021 17:18:00 +0000</pubDate>
      <link>https://dev.to/iferminm/quick-and-easy-user-registration-with-django-2ka6</link>
      <guid>https://dev.to/iferminm/quick-and-easy-user-registration-with-django-2ka6</guid>
      <description>&lt;p&gt;What does 99% of the projects we work on have in common?, what's usually the first or the last thing we start working on when building something, a personal project perhaps?. If you said &lt;em&gt;dealing with users&lt;/em&gt;, that's right. On each and every project we find ourselves writing different registration or authentication flows, sometimes we use third party authentication services like &lt;em&gt;Google&lt;/em&gt; or &lt;em&gt;facebook&lt;/em&gt; via their *API*s, but most of the times I'd say we start by asking our user's to register using their &lt;code&gt;email&lt;/code&gt; and a &lt;code&gt;password&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common approaches
&lt;/h2&gt;

&lt;p&gt;There are several approaches to user registration, we can do it on a single step, or we can do it on 2 steps with a confirmation email being sent to the given address. There are several ways you can structure your registration flow, either two simple questions (&lt;code&gt;email&lt;/code&gt; and &lt;code&gt;password&lt;/code&gt;) or multiple questions through several pages, you name it, we always write user registration flows.&lt;/p&gt;

&lt;p&gt;If you ask me, I've always preferred to write a simple one, ask for an &lt;code&gt;email&lt;/code&gt; and a &lt;code&gt;password&lt;/code&gt; and ask for the rest of the information I need on a separate &lt;em&gt;User Profile&lt;/em&gt; page, things like name, date of birth, country, city, mobile number or other stuff I might need. But you want as less friction as possible on the registration process, especially if you're trying to get your first users, that's why I don't even send confirmation emails when I just launched something. I start asking for confirmation when I already got some users and I have people constantly signing up, otherwise, it's not worth the effort or the network traffic, plus the complexity of sending it asynchronously with a message queue.&lt;/p&gt;

&lt;p&gt;Those are the reasons why I thought of writing a reusable django app to solve this, build an app to have django create users and just use it in all my projects. I was working on it for a while, taking the good parts of all the registration flows I've written, until I found &lt;code&gt;django-registration&lt;/code&gt; and just switched to that library.&lt;/p&gt;

&lt;h2&gt;
  
  
  User registration flows with django-registration
&lt;/h2&gt;

&lt;p&gt;This is way better that anything I could have written myself, it's being used by many people, has an active maintainer, works out of the box and supports single and two steps registration flows so, why &lt;em&gt;reinventing the wheel&lt;/em&gt; if it's already there?, I'm using it for a couple of personal projects I'll be launching in the upcoming months (or not... you know...) and it's incredible how easy it makes it to implement user registration in django, allowing me to start working on actual features and functionality in almost no time.&lt;/p&gt;

&lt;p&gt;Let's get started&lt;/p&gt;

&lt;h3&gt;
  
  
  Installing django-registration
&lt;/h3&gt;

&lt;p&gt;To install it, you just need to &lt;code&gt;pip&lt;/code&gt; it as any usual &lt;em&gt;Python&lt;/em&gt; module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;django-registration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the simple &lt;em&gt;one step&lt;/em&gt; registration flow or the &lt;em&gt;HMAC Based&lt;/em&gt; workflow, you don't need to do anything else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registration workflows
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;django-registration&lt;/em&gt;, supports three different workflows:&lt;/p&gt;

&lt;h4&gt;
  
  
  One step user registration flow
&lt;/h4&gt;

&lt;p&gt;This workflow consists of as few steps as possible, the user signs up by filling the registration form, after submitting, the account is created without any intermediate verification and the user is logged in automatically.&lt;/p&gt;

&lt;h4&gt;
  
  
  HMAC-based user registration flow
&lt;/h4&gt;

&lt;p&gt;It's a two steps registration workflow that doesn't store any verification key, it sends instead a timestamped HMAC verified value to the user via email in order to verify the account.&lt;/p&gt;

&lt;h4&gt;
  
  
  Model-based user registration flow
&lt;/h4&gt;

&lt;p&gt;To use this workflow, you'll have to add &lt;code&gt;registration&lt;/code&gt; to your &lt;code&gt;INSTALLED_APPS&lt;/code&gt; as you will need to install one model to perform the verification step. If you need a two steps account creation because you require email verification, the recommended way is to use the &lt;em&gt;HMAC&lt;/em&gt; flow.&lt;/p&gt;

&lt;p&gt;The basic &lt;em&gt;one step&lt;/em&gt; registration flow is the easiest way to register new users, if you're just deploying something for fun&lt;br&gt;
and it's intended mostly for your personal use but want to allow other people to use it, I don't think you need to verify&lt;br&gt;
email and go through all that hassle unless you get serious about it, so in my case, the intended user for my project is just myself, but if someone else wants to use it, I'm OK with that, I assume if you want to use something you'll just provide a legit email because it's on your own interest.&lt;/p&gt;
&lt;h3&gt;
  
  
  Setting up django-registration
&lt;/h3&gt;

&lt;p&gt;I decided to go for a &lt;em&gt;one step&lt;/em&gt; flow, as I don't really care if anyone provides an nonexistent email, I'm the one who will mostly be using this, so, I guess it's OK, &lt;em&gt;django-registration&lt;/em&gt; allows me to restrict new accounts from being created just by adding  &lt;code&gt;REGISTRATION_OPEN = False&lt;/code&gt; on my &lt;code&gt;settings.py&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Each registration flow comes with its own set of views and urls and you'll have to create your custom template and form if you needed, you'll most probably end up customizing some behavior, but it's really easy to do, most of the core, boring and repetitive work of creating the registration workflow is done for you and works out of the box.&lt;/p&gt;

&lt;p&gt;In this case, for the &lt;em&gt;one step&lt;/em&gt; all I had to do was the following:&lt;/p&gt;
&lt;h4&gt;
  
  
  1. Include the URLs for django-registration
&lt;/h4&gt;

&lt;p&gt;Include &lt;code&gt;registration.backends.simple.urls&lt;/code&gt; in my urls configuration&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;

&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# Some url patterns
&lt;/span&gt;    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s"&gt;'accounts/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'registration.backends.simple.urls'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="c1"&gt;# More url patterns
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Allow creating new user accounts
&lt;/h4&gt;

&lt;p&gt;Set &lt;code&gt;REGISTRATION_OPEN = True&lt;/code&gt;, this is the default value, but &lt;em&gt;better explicit than implicit&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Setup redirections after user creation
&lt;/h4&gt;

&lt;p&gt;By default, after successful registration the user will be redirected to &lt;code&gt;/&lt;/code&gt;, but you can customize this behavior by&lt;br&gt;
subclassing &lt;code&gt;registration.backends.simple.views.RegistrationView&lt;/code&gt; and overriding the method &lt;code&gt;get_success_url()&lt;/code&gt;, in my case, redirecting to &lt;code&gt;/&lt;/code&gt; is fine.&lt;/p&gt;
&lt;h4&gt;
  
  
  4. Customize the user registration form
&lt;/h4&gt;

&lt;p&gt;By default, &lt;em&gt;django-registration&lt;/em&gt; will use &lt;code&gt;registration.forms.RegistrationForm&lt;/code&gt;, this can be overridden by supplying your own &lt;code&gt;form_class&lt;/code&gt; argument when adding the default &lt;code&gt;RegistationView&lt;/code&gt; to the &lt;code&gt;urlpatterns&lt;/code&gt; or by subclassing it and setting the &lt;code&gt;form_class&lt;/code&gt; attribute or implementing &lt;code&gt;get_form_class()&lt;/code&gt;. In my case, I opted for passing an argument to the &lt;code&gt;as_view()&lt;/code&gt; method when adding the corresponding &lt;code&gt;url&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;registration.backends.simple.views&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;RegistrationView&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;django.conf.urls&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;.forms&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;UserRegistrationForm&lt;/span&gt;


&lt;span class="n"&gt;urlpatterns&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;# Some url patterns
&lt;/span&gt;    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s"&gt;'accounts/register/$'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;RegistrationView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;as_view&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;form_class&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;UserRegistrationForm&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;r&lt;/span&gt;&lt;span class="s"&gt;'accounts/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'registration.backends.simple.urls'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
    &lt;span class="c1"&gt;# More url patterns
&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  5. Customize the registration template
&lt;/h5&gt;

&lt;p&gt;Customize the registration template, this flow only needs one template called &lt;code&gt;registration/registration_form.html&lt;/code&gt; and it will pick it up automatically, the &lt;code&gt;RegistrationView&lt;/code&gt; will add the &lt;code&gt;form&lt;/code&gt; variable to the &lt;code&gt;context&lt;/code&gt; and it will contain a &lt;code&gt;RegistrationForm&lt;/code&gt; instance, all for free.&lt;/p&gt;

&lt;p&gt;Using django-registration can save a lot of time, setting up the HMAC-based user registration flow is also super easy if you need to, I'd recommend you ro refer to the official docs, linked below, if you want to dig deeper into this django module.&lt;/p&gt;

&lt;h1&gt;
  
  
  Resources
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://django-registration.readthedocs.io/en/3.1.1/"&gt;https://django-registration.readthedocs.io/en/3.1.1/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>django</category>
      <category>python</category>
      <category>coding</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Working easier with legacy databases</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Tue, 19 Jan 2021 16:12:02 +0000</pubDate>
      <link>https://dev.to/iferminm/working-easier-with-legacy-databases-1kn</link>
      <guid>https://dev.to/iferminm/working-easier-with-legacy-databases-1kn</guid>
      <description>&lt;p&gt;This will be a short article, recently at work I had to build few reports on top of two legacy databases, to be honest, the whole architecture and the way the data is stored, in my opinion, is not optimal, a lot of things need to change but, as usual, features and business take precedence over technical debt.&lt;/p&gt;

&lt;p&gt;The whole stack is based on nodejs on top of typescript, which makes a bit more enjoyable the fact that I'm now working in JavaScript. All the databases were generated using knexjs so, these databases were there already and I only had to connect to them.&lt;/p&gt;

&lt;p&gt;I didn't want to spend too much time on the connection and mapping part, so I wanted to see if an ORM would be of use here&lt;/p&gt;

&lt;h2&gt;
  
  
  The overall idea
&lt;/h2&gt;

&lt;p&gt;Since we will be integrating with other internal tools to generate these reports the implementation I came up with is temporary, so I wanted to make as few changes as possible in the current codebase for several reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Once you add something temporary, it will be difficult to clean it up after it's not needed anymore, the chances of someone building on top of it  is high.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I don't like working with typescript, or JavaScript in general so if I could get away with writing in some other language it could be more fun.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The current application is a monolith and the logic is complex, adding more would take longer than implementing something from scratch.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, I decided to implement the report generating logic in a Lambda function which will be executed periodically, this meant I had to setup the connections to the databases from scratch and map to my domain classes and types in order to have a clean architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter Sqlalchemy
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.sqlalchemy.org/"&gt;Sqlalchemy&lt;/a&gt; is the database Swiss army knife in python, it makes it very easy to work with databases by mapping tables to domain classes, but it also works the other way around by introspecting the database's schema metadata and generating stub classes to deal with them in Python.&lt;/p&gt;

&lt;h3&gt;
  
  
  Automap
&lt;/h3&gt;

&lt;p&gt;Sqlalchemy has an Automap extension, which lets you connect to an existing database and generate a domain model from the existing database schema and operate with it from Python, trigger queries and use Sqlalchemy normally as if the schema was generated by you.&lt;/p&gt;

&lt;p&gt;It's very easy and it doesn't take 30 lines of code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;

&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy.ext.automap&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;automap_base&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy.orm&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;sqlalchemy&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;


&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'DB_URL'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Base&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;automap_base&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;engine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;create_engine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bind&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reflect&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can access the classes with the table name as it is in the database let's say you have a &lt;code&gt;user_profile&lt;/code&gt; database, then you can access it as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_profile&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Trigger queries as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;UserProfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;classes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_profile&lt;/span&gt;

&lt;span class="n"&gt;profile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;UserProfile&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nb"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;UserProfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;123123&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="n"&gt;fist&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you're good to go.&lt;/p&gt;

&lt;p&gt;Of course, code conventions in SQL and Python are different, if you want your code to look more pythonic and have &lt;code&gt;Base.classes.*&lt;/code&gt; to be in PascalCase as well, you can write a function to override the table naming when the automap is performed, it will add few lines but still below 20 lines in general&lt;/p&gt;

&lt;p&gt;It looks something like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;snake_to_pascal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tablename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;table&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;''&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;capitalize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;w&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tablename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'_'&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course, that assumes your tables are named as &lt;code&gt;this_is_a_table&lt;/code&gt; and will be converted to &lt;code&gt;ThisIsATable&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;You can use that function when you call &lt;code&gt;Base.prepare&lt;/code&gt; as follows&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;Base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;prepare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;engine&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;reflect&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;classname_for_table&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;snake_to_pascal&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. :-)&lt;/p&gt;

&lt;p&gt;If you want to know more about SqlAlchemy, you can always refer to the official docs: &lt;a href="https://www.sqlalchemy.org/library.html"&gt;https://www.sqlalchemy.org/library.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>coding</category>
      <category>python</category>
      <category>database</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>New grads survival guide</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Mon, 18 Jan 2021 11:31:30 +0000</pubDate>
      <link>https://dev.to/iferminm/new-grads-survival-guide-28nk</link>
      <guid>https://dev.to/iferminm/new-grads-survival-guide-28nk</guid>
      <description>&lt;p&gt;OK, OK... I'm sorry, I lied on the title, but please, don't stop reading. I know... I know, we started bad our relationship already but, I can explain it, I swear.&lt;/p&gt;

&lt;p&gt;Yes, it says "survival guide", but it's not like that, I'm not going to tell you a recipe to get the job you want, in the company you like and the country you dream, that's impossible, as programmer we all know there is no silver bullet, and it applies not only on software, also in day by day life problems.&lt;/p&gt;

&lt;p&gt;What I'm going to share with you, is what worked and still working for me, let me give you some context. I'm a Software Engineer from Venezuela, yes, I know... we're famous for good baseball players, beautiful women and, most recently and sadly, thanks to this guy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OwLb_J29--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/8v0mswsxcdii5pd/chavez.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OwLb_J29--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/8v0mswsxcdii5pd/chavez.jpg" alt="Hugo Chávez, worst Venezuelan&amp;lt;br&amp;gt;
president..."&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this other guy...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K2okuXqr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/2yqy0xbwldnwth4/maduro.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K2okuXqr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dl.dropboxusercontent.com/s/2yqy0xbwldnwth4/maduro.jpg" alt="Nicolás Maduro... even worse that&amp;lt;br&amp;gt;
Chávez"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My country is, obviously, a 3rd world country, we're facing huge and very serious economic and political issues and it's quickly getting worse thanks to those guys, my family is not rich so I couldn't travel or go to another country to study until things get better and, by now, I'm living in Dubai, paying my rent and brought my wife abroad so we have some hope of having the quality of life we dreamed together and have 2 kids, how I did it?, my job is my flight ticket and my passport.&lt;/p&gt;

&lt;p&gt;I managed to get out of Caracas, one of the most violent and dangerous cities in the world, and come to Dubai in 2014. Obviously this wasn't with money from my own pocket, a local company hired me and covered my relocation expenses. I'm going to share with you some things I did and still doing, this is not guaranteed to give you the job you want, but certainly will help you increase your chances.&lt;/p&gt;

&lt;h2&gt;
  
  
  Set up a decent LinkedIn profile
&lt;/h2&gt;

&lt;p&gt;No joke, this helps, a lot of recruiters and companies in LinkedIn, don't underestimate that tool, it's really powerful and you don't need to pay for the pro or premium version to get something out of it. A good LinkedIn profile includes a picture, a description of each job you had, and by description I mean responsibilities and key achievements and responsibilities in that position.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have a public GitHub account
&lt;/h2&gt;

&lt;p&gt;And actually &lt;em&gt;use it!&lt;/em&gt;, I'm not telling you to contribute to a lot of open source projects or to start yet another social auth library or JS framework, just experiment with new tools, build some cool hello-world style projects and upload the code to GitHub, this will show that you're actively learning new stuff all the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Have a StackOverflow account
&lt;/h2&gt;

&lt;p&gt;And, again, &lt;em&gt;use it&lt;/em&gt;, answer some questions and ask some questions, it's useful and it will help you, trust me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be passionate
&lt;/h2&gt;

&lt;p&gt;Love your career, you studied it for a reason. Learn new stuff, experiment with a new language or framework, show everybody the cool stuff you're working on, get ideas from other people and learn from them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Be pragmatic
&lt;/h2&gt;

&lt;p&gt;Yes, when it comes to work, you have to let your knowledge and logic guide your decisions, not your emotions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose your weapon
&lt;/h2&gt;

&lt;p&gt;And do it early, it's good to be versatile, you're a programmer, not a user of a programming language. But you need a battle ax, the one that helps you solve any problem faster and you feel more comfortable with.&lt;/p&gt;

&lt;p&gt;And finally, the one I consider the most important.&lt;/p&gt;

&lt;h2&gt;
  
  
  Choose your first job carefully
&lt;/h2&gt;

&lt;p&gt;Yes, I mean it, don't let the job choose you, you have to enjoy your job because it's where you will spend most of the day and, trust me, your first job will define your career. If you start developing J2EE applications, people will hire you to do so, because that's the experience you have. Don't be afraid to say no to an offer you're not totally convinced of taking. &lt;/p&gt;

&lt;p&gt;In my case, when I was looking for an internship, I turned down an offer from Microsoft in Venezuela because I've always been an Open Source enthusiast and a Linux user, I didn't really saw myself programming in ASP.NET, I decided to take an offer from Vauxoo, a local small company that developed open source modules for OpenERP (now Odoo) and I'm very happy I took that road, I learned Python in that job, which is my battle ax and my main tool by today.&lt;/p&gt;

&lt;p&gt;So... yeah!, not a recipe, but some tips I hope will help you on your first years as a professional.&lt;/p&gt;

</description>
      <category>career</category>
      <category>advice</category>
      <category>codenewbie</category>
      <category>newgrad</category>
    </item>
    <item>
      <title>Choosing which languages to learn</title>
      <dc:creator>Israel Fermín M.</dc:creator>
      <pubDate>Wed, 13 Jan 2021 14:48:28 +0000</pubDate>
      <link>https://dev.to/iferminm/which-languages-should-i-learn-5g</link>
      <guid>https://dev.to/iferminm/which-languages-should-i-learn-5g</guid>
      <description>&lt;p&gt;There are millions of articles and blog posts out there trying to tell you what to learn next or which language or technologies are worth your attention, things like &lt;em&gt;Top 10 programming languages&lt;/em&gt; or &lt;em&gt;Learn one of these languages and you'll be done&lt;/em&gt; with some statistics about language popularity but the truth is, none of those make sense. No one can tell you what to learn and you don't need to study whatever is popular out there all the time.&lt;/p&gt;

&lt;p&gt;The truth is, while popular languages are widely used, also, supply is high, hence, salaries will tend to be lower, on the other hand, if you learn the not-so-popular ones, salaries would be higher but you'll end up most likely having a hard time finding a job.&lt;/p&gt;

&lt;h1&gt;
  
  
  Trends come and go
&lt;/h1&gt;

&lt;p&gt;Whatever is popular today, might be considered terrible in the future as well as what's not so popular today, might be widely used in future, you just have to see the growth trends in whatever languages or technologies you're into.&lt;/p&gt;

&lt;p&gt;Few years back, for example, JavaScript was used only for frontend development and JQuery was the best thing out there for it, now almost no one uses JQuery directly, everyone is using react, angular or vue and now you can even find JavaScript on the backend (not that that's a good thing IMO...).&lt;/p&gt;

&lt;p&gt;The point is, we should not chase the top 10 most popular technologies, we should try to find a balance, otherwise we won't really fully learn nor master anything.&lt;/p&gt;

&lt;h1&gt;
  
  
  My view
&lt;/h1&gt;

&lt;p&gt;I think that, the first thing we need to do is, work on what's paying your bills. Few years back, for example, Python was the one paying my bills and it happened to be the first language I worked with after graduating, I became passionate about it,&lt;br&gt;
to the point that I organized meetups and conferences back home in Caracas - Venezuela and after that, I only looked for jobs in Python, it was gaining popularity and growing a lot, I know, I was lucky, but it also makes a point, I was focused on becoming better on a single thing which were the technologies I was working with at that point in time, the full stack was Python, Postgres and OpenERP (now it goes by Odoo).&lt;/p&gt;

&lt;p&gt;I think everyone should start by that, just become better and learn more about the stack you're currently working with. My last 100% Python job was at my previous company (dubizzle/OLX), when I joined Careem the stack I worked with changed to Java, Springboot and MySQL mainly, so I started over, learning a new framework and a not-so-new language to me. Then, I switched teams and the stack was Python, Jenkins (groovy) and Terraform, again, learning new things. Then, after almost 2 years, I again switched teams and the stack was Typescript, Express, Node, and both MySQL and Postgres and after few months I was changed to a different team again, the stack also changed and now, this team works on PHP and Go for the most part and MySQL. Whenever your stack at work changes, focus on learning and mastering that.&lt;/p&gt;

&lt;p&gt;Once you master whatever is helping you pay your bills, you can use your spare time to learn whatever you want, in my opinion you need to know at least one of those popular languages just to make sure if something unexpected happens &lt;br&gt;
to your current job, you can find a new one quick. In my case, maybe I've been just lucky, I know Python, Java and JavaScript and those are three of the most popular languages out there today. But I also know their popularity won't last forever and that some less popular languages might pay better salaries because supply is less and the skills are more rare.&lt;/p&gt;

&lt;p&gt;Everyone is free to learn whatever they want, but this is how I think about it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start by what pays your bills:&lt;/strong&gt; this is important, you need to be efficient at your work and the only way to achieve it is by learning how to use your tools effectively. This will help you do more in less time.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;One popular language:&lt;/strong&gt; well, at least one, if you like more than one, go for it, why learning the popular ones?, this will open the door for more job opportunities, you never know what will happen and it's better to be prepared to hunt (or be hunted) for a new role on a different company.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;One high level language:&lt;/strong&gt; the higher level, the best, I'd go for a language with a dynamic but strong type system, why? to build things quick. Usually high level dynamic languages have a huge ecosystem of libraries and frameworks you can leverage your work on and achieve more writing less code.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;One lower level language:&lt;/strong&gt; you never know when you'll need either more speed or write something at system level or even have more control over how the program will manage memory. Truth is, not all use cases are covered by a High Level object oriented language.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's not too hard to achieve that, you can mix and match languages in all those buckets, for example, in most of the cases what pays your bills will be a popular high level language, that covers the first three, then you'll only need to learn a lower level programming language to be all setup.&lt;/p&gt;

&lt;p&gt;Once you cover that, you can explore other paradigms and incorporate more patterns and practices from those paradigms and other languages into your every day programming style, by learning, understanding and practicing is the only way we become better software engineers.&lt;/p&gt;

&lt;p&gt;In my case, as I know JavaScript/Typescript, Python and Java because of previous jobs, maybe not all of them at an expert level but at least a general understanding so that I can tackle most of the day-to-day tasks using them. I'm focusing on learning Rust, it's a language which is growing and implements interesting concepts and I've toyed around with Smalltalk and Haskell to see what's there to learn and incorporate new practices into my coding. &lt;/p&gt;

&lt;p&gt;What's currently on your learning list? let me know on the comments box.&lt;/p&gt;

</description>
      <category>career</category>
      <category>programming</category>
      <category>learning</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
