<?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: Simple Thread</title>
    <description>The latest articles on DEV Community by Simple Thread (@simple_thread).</description>
    <link>https://dev.to/simple_thread</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%2F72462%2Fcb59b54d-a70b-4d20-aaad-931c7150f171.jpg</url>
      <title>DEV Community: Simple Thread</title>
      <link>https://dev.to/simple_thread</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/simple_thread"/>
    <language>en</language>
    <item>
      <title>Your Text Editor Plugins Belong in a Lock File</title>
      <dc:creator>Simple Thread</dc:creator>
      <pubDate>Tue, 11 Jun 2019 13:00:42 +0000</pubDate>
      <link>https://dev.to/simple_thread/your-text-editor-plugins-belong-in-a-lock-file-52id</link>
      <guid>https://dev.to/simple_thread/your-text-editor-plugins-belong-in-a-lock-file-52id</guid>
      <description>&lt;p&gt;I just updated all of your text editor plugins. What’s your reaction? Something like this?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EgQylMjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/06/cry.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EgQylMjv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/06/cry.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s been years since you’ve updated all those plugins, hasn’t it? Who cares about those new features, bug fixes, or performance and security improvements? Just cross your fingers and hope your laptop doesn’t die forcing you to upgrade. Better yet, you’ve got a full image backup, right? That way you can keep those crusty old plugins forever.&lt;/p&gt;

&lt;p&gt;It’s understandable to wince at the thought of updating those plugins. Most developers have been burned for one reason or another. Besides, who has time for that crap? After you update you run into some obscure conflict between plugins, or the author pushed a beta version. Even worse, that fancy new version of the plugin is a real performance bottleneck.&lt;/p&gt;

&lt;p&gt;And of course the issues never seem to crop up immediately after doing the update but instead at the most inopportune time. It’s several days later and you’ve got a deadline approaching. You don’t have an easy way to revert your update. Heck you don’t even know which plugin is the culprit. Now you have to make a choice. Do you slog through debugging your editor or disable plugins, continuing your work with one hand tied behind your back?&lt;/p&gt;

&lt;p&gt;Updating your plugins doesn’t have to be this painful though. Wouldn’t it be nice if your editor plugins had a lock file like your application dependencies do? (You lock your application dependencies, don’t you?) Then you could add that file to version control. Going back to your old setup would be like snapping your fingers. Just checkout the previous commit and run the install command. Sounds obvious in hindsight, right?&lt;/p&gt;

&lt;p&gt;I’ve kept my plugins in a plugin.lock file for about a year now, and it has been wonderful. It works exactly like you would expect. I update my plugins every couple months. If I run into an issue and don’t feel like dealing with it immediately then I can quickly revert. For debugging, I can do a quick git diff to see which plugins were recently updated. If one plugin is misbehaving I pull the old version from my git history and continue on my way. If I’m desperate to determine which plugin is misbehaving I can even do a binary search (Recursively revert half the versions and check if the problem still exists).&lt;/p&gt;

&lt;p&gt;Creating and using your very own plugin.lock file is really easy. I have a few examples below for popular editors.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;VIM&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Using the popular VIM plugin manager &lt;a href="https://github.com/junegunn/vim-plug"&gt;vim-plug&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create your lock file…&lt;br&gt;&lt;br&gt;
&lt;code&gt;:PlugSnapshot plugin.lock&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Restore from your lock file…&lt;br&gt;&lt;br&gt;
&lt;code&gt;:source plugin.lock&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Atom&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Create your lock file…&lt;br&gt;&lt;br&gt;
&lt;code&gt;apm list --installed --bare | xargs -L 1 echo apm install &amp;gt; plugin.lock&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Restore from your lock file…&lt;br&gt;&lt;br&gt;
&lt;code&gt;sh plugin.lock&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;VS Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;a href="https://code.visualstudio.com/insiders/"&gt;insiders&lt;/a&gt; version of Visual Studio Code Supports this.&lt;/p&gt;

&lt;p&gt;Disable auto extension updating (if you haven’t done so already)&lt;br&gt;&lt;br&gt;
 &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P4RJACgt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/06/disable_auto_update.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P4RJACgt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/06/disable_auto_update.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Create your lock file…&lt;br&gt;&lt;br&gt;
&lt;code&gt;code-insiders --list-extensions --show-versions | xargs -L 1 echo code-insiders --install-extension &amp;gt; plugin.lock&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Restore from your lock file…&lt;br&gt;&lt;br&gt;
&lt;code&gt;sh plugin.lock&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;———————-&lt;/p&gt;

&lt;p&gt;If you have instructions for creating a plugin.lock in other editors please let me know in the comments!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://www.simplethread.com/editor-plugins-belong-in-lock-file/"&gt;Your Text Editor Plugins Belong in a Lock File&lt;/a&gt; appeared first on &lt;a href="https://www.simplethread.com"&gt;Simple Thread&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>misc</category>
      <category>productivity</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Was MongoDB Ever the Right Choice?</title>
      <dc:creator>Simple Thread</dc:creator>
      <pubDate>Tue, 26 Mar 2019 15:06:05 +0000</pubDate>
      <link>https://dev.to/simple_thread/was-mongodb-ever-the-right-choice-p59</link>
      <guid>https://dev.to/simple_thread/was-mongodb-ever-the-right-choice-p59</guid>
      <description>&lt;p&gt;I was reading a post recently about&lt;a href="https://www.redhat.com/en/blog/red-hat-satellite-standardize-postgresql-backend"&gt;Red Hat removing MongoDB support from Satellite&lt;/a&gt; (and yes, some folks say it is because of the license changes). It made me think how often over the last few years I’ve seen&lt;a href="http://www.sarahmei.com/blog/2013/11/11/why-you-should-never-use-mongodb/"&gt;post&lt;/a&gt; after&lt;a href="http://cryto.net/~joepie91/blog/2015/07/19/why-you-should-never-ever-ever-use-mongodb/"&gt;angry post&lt;/a&gt; about how terrible MongoDB is and how no one should ever use. However, in all this time, MongoDB has become a much more mature product. So what happened? Did all of the hate truly come from mistakes made in the early implementation/marketing of MongoDB? Or is the problem that people are blaming MongoDB for their own lack of efforts when evaluating if it was a good fit?&lt;/p&gt;

&lt;p&gt;If you’re finding yourself at this point foaming at the mouth because it appears that I’m defending MongoDB, please jump to the end of this post and read my disclaimer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trendspotting
&lt;/h2&gt;

&lt;p&gt;I’ve been working with software for more years at this point than I like to admit, but even then I’ve only experienced a tiny fraction of the trends that have buffeted our industry. I’ve witnessed the rise and fall of 4GL, AOP, Agile, SOA, Web 2.0, AJAX, blockchain… the list never ends. Every year there are new trends that pop up in the world of software engineering. Some fizzle quickly, while others fundamentally change the way software development is performed.&lt;/p&gt;

&lt;p&gt;With any new innovation that starts to gain traction, you’re going to see a general excitement appear around it as people start to pile on board, or see the buzz being generated by others and decide that they too want to get in on the action. This process was codified by Gartner with its&lt;a href="https://en.wikipedia.org/wiki/Hype_cycle"&gt;hype cycle&lt;/a&gt;, which (while controversial) is a decent approximation of what happens with technologies that are eventually found to be valuable.&lt;/p&gt;

&lt;p&gt;But every once in a while, a new innovation appears (or in this case reappears) that is driven by one particular implementation of that innovation. In the case of the NoSQL movement, it was driven heavily by the appearance, and meteoric rise, of MongoDB. MongoDB didn’t start the movement, it was the data challenges at large internet companies that really drove the return to non-relational databases. Projects like Google’s Bigtable and Facebook’s Cassandra kicked it off, but MongoDB was the most visible and accessible implementation of a NoSQL database that most developers had access to.&lt;/p&gt;

&lt;p&gt;Aside: You might be thinking right now that I’m conflating document databases with columnar databases, key/value stores, or any of the numerous other datastore types that fall under the generic NoSQL banner. And you are correct. But this was happening wildly at the time. Everyone was jumping into the NoSQL craze and they knew that they &lt;strong&gt;absolutely&lt;/strong&gt; needed NoSQL, but didn’t really understand the different technologies involved. To many people, MongoDB &lt;strong&gt;was&lt;/strong&gt; NoSQL.&lt;/p&gt;

&lt;p&gt;And developers pounced on it. The idea of a schema-less database that magically scaled to meet any challenge was quite alluring. Around 2014 or so, it seemed like everywhere you looked someone was implementing MongoDB in a place where just a year earlier a relational database like MySQL, Postgres, or SQL Server would have been used. When asked why Mongo was being used there were responses ranging from the banal “it’s web scale” to the more thoughtful “my data is very loosely structured and fits well into a schema-less database”.&lt;/p&gt;

&lt;p&gt;It is important to remember that MongoDB, and document databases in general, solve a number of problems people had with traditional relational databases:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Strict Schema&lt;/strong&gt; – With a relational database, if you had dynamically shaped data you were forced to either create a bunch of random “miscellaneous” data columns, shove data in as a blob of data, or use an&lt;a href="https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model"&gt;EAV&lt;/a&gt; setup… all of which had significant downsides.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Difficult Scalability&lt;/strong&gt; – With a relational database, if your data was so large that you couldn’t fit it easily into one server MongoDB had built in mechanisms for allowing you to scale that data across multiple machines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Difficult Schema Modifications&lt;/strong&gt; – No migrations! With a relational database, changing the structure of the database can be a huge challenge (especially once your data gets really big). MongoDB promised to make this dramatically more simple. And it made it soooo easy to get started, you could just keep updating your schema and move really quickly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Write Performance&lt;/strong&gt; – MongoDB’s performance was good, especially when configured in certain ways. MongoDB’s out-of-the-box write configuration, which is one of the big things it was criticized for, allowed it to put up some impressive performance numbers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Caveat Emptor
&lt;/h2&gt;

&lt;p&gt;The potential benefits MongoDB provided were huge, especially for people facing certain classes of problems. Reading the list above without context, or experience, would lead you to believe that it truly was a game-changer when it came to database systems. The only problem was that the benefits listed above came with a number of caveats, some of which I’ve listed below.&lt;/p&gt;

&lt;p&gt;To be fair, no one at 10gen/MongoDB Inc. would claim the items below aren’t true, they are just tradeoffs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loss of transactions&lt;/strong&gt; – Transactions are a core feature of many relational databases (no, not all, but most). Having a transaction means that you can perform multiple operations atomically and you can ensure that your data will stay consistent. Sure, with a NoSQL database you can have a transaction within a single document, or you can use tactics like two-phase commits to get transaction-like semantics. But the point is you have to do this work yourself… and it can be challenging and labor intensive to get right. Often you don’t realize how much you’re giving up here until you start seeing data in your database get into invalid states because you couldn’t guarantee the atomicity of operations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Loss of relational integrity (foreign keys)&lt;/strong&gt; – If your data has relationships, then you’re going to have relations. Almost all data has some kind of relations, and if your database doesn’t enforce them, then your application is going to have to. Having a database enforce these relationships can offload a lot of work from your application, and therefore from your engineers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lack of ability to enforce data structure&lt;/strong&gt; – Strong schemas might be a pain in the ass sometimes, but they can also be a powerful mechanism for ensuring that your data is well structured. If you leverage them appropriately, it provides a powerful mechanism for ensuring your data is in the shape you expect. Document databases like MongoDB allow an incredible amount of flexibility around the schema, but that flexibility offloads the responsibility onto the maintainer to keep their data clean. If you don’t put in that effort, then you end up putting a lot of code into your application to account for data that might not be in the shape you expect. As we often like to say at Simple Thread… your app is going to be rewritten one day, your data will live forever.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Custom query language/Loss of tooling ecosystem&lt;/strong&gt; – SQL was an absolute revolution when it came out, and nothing has changed since then. SQL is an incredibly powerful language, but one that can also be challenging. Having to query a database using a custom query language composed of JSON snippets would be considered a big step backwards by folks experienced with SQL. There is a whole world of tools that interoperate with SQL databases. Everything from IDEs to reporting tools. Moving to a database that doesn’t support SQL means you can’t use most of these tools, or you have to find a way to get your data into a SQL database so that these tools can be used, and this can be harder than you think.&lt;/p&gt;

&lt;p&gt;Many developers who reached for MongoDB didn’t deeply understand the tradeoffs they were making, and often they dove in head-first by using it as the primary datastore for their applications. This meant that is was often incredibly costly to go back on this decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  What could have been done differently?
&lt;/h2&gt;

&lt;p&gt;Not everyone jumped in head first and slammed into the bottom of the deep end. But enough did that there will be projects for years to come removing MongoDB from places where it just didn’t fit. If many of these organizations had taken a bit of time to think methodically about the technology choices they were making, it is likely that many of them wouldn’t have made the decisions they did.&lt;/p&gt;

&lt;p&gt;So how do you decide what technology makes sense for your use case? There have been a few attempts at creating systematic frameworks for evaluating technologies such as “&lt;a href="http://www.wohlin.eu/spi96.pdf"&gt;A Framework for Technology Introduction in Software Organizations&lt;/a&gt;” and “&lt;a href="https://pdfs.semanticscholar.org/4268/30dd5dd944d3b75ec56b2a3b151c18afbaf9.pdf"&gt;A Framework for Evaluating Software Technologies&lt;/a&gt;”, but I don’t think it needs to be that complicated.&lt;/p&gt;

&lt;p&gt;Many technologies can be reasonably evaluated by asking just two main questions, but &lt;strong&gt;the challenge is finding individuals who can responsibly answer them, dedicate time to answering them, and answer them without bias.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you’re not facing some kind of problem, you don’t need a new tool. Full stop.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Question 1: What problems am I trying to solve?
&lt;/h2&gt;

&lt;p&gt;If you’re not facing some kind of problem, you don’t need a new tool. Full stop. Don’t look for solutions and then back into problems. If you’re not facing a problem that a new technology doesn’t solve significantly better than your existing technology, then your decision is over. If you’re considering using this technology because you’ve seen others using it, it might be useful to think about what problems they are facing, and ask yourself if you’re facing the same problems. It is often easy to reach for a technology because you see another company using it, the difficulty is in determining whether or not you’re facing the same challenges.&lt;/p&gt;

&lt;h2&gt;
  
  
  Question 2: What am I giving up?
&lt;/h2&gt;

&lt;p&gt;This is definitely the harder of the two questions to answer, because you have to dig in and have a good understanding of both the old technology and the new technology. Sometimes you can’t really understand a new technology until you’ve built something with it, or have access to someone who has spent significant time with the technology.&lt;/p&gt;

&lt;p&gt;If you don’t have either, then you should be considering what is the smallest investment you can make to determine if this tool is valuable. And if you make the investment, how hard would it be to undo the decision?&lt;/p&gt;

&lt;h2&gt;
  
  
  Humans Always Messing Things Up
&lt;/h2&gt;

&lt;p&gt;One thing you’ll have to keep in mind is that you’re going to be fighting human nature when you’re trying to answer these questions as unbiased as possible. There are a number of cognitive biases that must be overcome in order to effectively evaluate a technology, but just to name a few:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Bandwagon_effect"&gt;&lt;strong&gt;Bandwagon effect&lt;/strong&gt;&lt;/a&gt; – Everyone knows this, and yet it is still hard to fight against. Just make sure that you’re choosing a technology because it solves real needs for you, not because the cool kids are doing it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://mindmodeling.org/cogsci2015/papers/0177/index.html"&gt;Mere newness bias&lt;/a&gt;&lt;/strong&gt; – Many software developers tend to undervalue technologies they have worked with for a long time, and overvalue the benefits of a new technology. This isn’t specific to software engineers, everyone has the tendency to do this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pigeon.psy.tufts.edu/avc/dittrich/fepef.htm"&gt;&lt;strong&gt;Feature-positive effect&lt;/strong&gt;&lt;/a&gt; – We tend to see what is present, and overlook what isn’t there. This can wreak havoc when working in concert with the “Mere newness bias”, since not only are you inherently putting more value on the new technology, but you’re also overlooking the gaps of the new tech.&lt;/p&gt;

&lt;p&gt;Looking at things objectively is a challenge, but understanding the biases that may affect you will help you make more rational decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;When a new innovation appears (or reappears), we need to be very careful in answering two questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does this tool solve a real problem for us?&lt;/li&gt;
&lt;li&gt;Do we thoroughly understand the tradeoffs?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you can’t confidently answer those two questions, take a few steps back and reevaluate.&lt;/p&gt;

&lt;p&gt;So was MongoDB ever the right choice? Yes, of course it was; like most things in engineering, it depends. For teams that answered those two questions, many found value and continue to find value in MongoDB. For those who didn’t, hopefully they learned a valuable, not-too-painful lesson about navigating the hype cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;I want to clarify that I neither love nor hate MongoDB. I simply haven’t run into many problems that I thought it would be the best fit for. I know that 10gen/MongoDB Inc. didn’t do themselves any favors early-on by setting unsafe defaults and promoting MongoDB everywhere (especially at hackathons) as the be-all end-all solution for every data need. Yes these were probably bad decisions, but I think it backs up the point I’m making here because these were issues that could be uncovered very quickly with even a cursory evaluation of the technology.&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://www.simplethread.com/was-mongodb-ever-the-right-choice/"&gt;Was MongoDB Ever the Right Choice?&lt;/a&gt; appeared first on &lt;a href="https://www.simplethread.com"&gt;Simple Thread&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>mongodb</category>
      <category>webdev</category>
      <category>discuss</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Great Scott! Timing Attack Demo for the Everyday Webdev</title>
      <dc:creator>Simple Thread</dc:creator>
      <pubDate>Tue, 05 Mar 2019 13:45:39 +0000</pubDate>
      <link>https://dev.to/simple_thread/great-scott-timing-attack-demo-for-the-everyday-webdev-53ch</link>
      <guid>https://dev.to/simple_thread/great-scott-timing-attack-demo-for-the-everyday-webdev-53ch</guid>
      <description>

&lt;p&gt;One of the more insidious ways your web application’s data can be comprised is through a timing attack. The time it takes your app to serve a request can reveal more information than you might think. While certain ingredients need to be present for a successful timing attack, the surface area is large and we can’t depend on a library to protect us against all cases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9obae4yu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/cookies-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9obae4yu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/cookies-1.png" alt="timing attack cookie"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After you understand the ins and outs of a timing attack, you might be surprised at what you find auditing your own web application. What follows below is a complete walk through extracting secret data from a vulnerable demo application.&lt;/p&gt;

&lt;p&gt;The scripts are written in Ruby, and &lt;a href="https://dev.to/simple_thread/railsconf-2018--top-10-favorite-talks-4i90-temp-slug-2005596"&gt;while we love it&lt;/a&gt; if that’s not your language don’t worry!  Written explanations are provided for each code snippet.&lt;/p&gt;

&lt;p&gt;The demo app and all code in this timing attack walkthrough can be found &lt;a href="https://github.com/simple-thread/great_scott"&gt;here&lt;/a&gt; on the Simple Thread Github page.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo App Overview
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pd62EraM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/Untitled2-1.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pd62EraM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/Untitled2-1.gif" alt="timing attack hello world"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before we get to the good stuff, here is the vulnerable demo app, which we will call Great Scott, a standard CRUD blog. Any user that visits the site can search posts by title (case insensitive) or author. When you log in as an admin you have the ability to create and publish posts. Only the admin can see unpublished blog posts.&lt;/p&gt;

&lt;p&gt;The timing attack vector will be abusing the search feature to grab the title of unpublished blog posts by measuring the time it takes for the server to respond.&lt;/p&gt;

&lt;h2&gt;
  
  
  Minimal Proof
&lt;/h2&gt;

&lt;p&gt;As the attacker, the easiest place to start is creating a minimal test to see if a timing attack is possible. The goal of a minimal test isn’t to fully extract the secret title. We’re going to pass two search queries and measure the results. One will match a piece of the title and the other won’t.&lt;/p&gt;

&lt;p&gt;Let’s set up our lab environment to remove as many variables as possible for the timing attack. We’ll be running our exploit scripts and app server on the same box so jitter caused by going over the open internet won’t be an issue. Also we’ll kill any resource hungry processes. Finally we want only one blog post to exist in our application and it should be unpublished. The rest of the guide assumes the title of this post is “Great Scott! We Must Get Back to the Future”&lt;/p&gt;

&lt;p&gt;Before running any scripts yourself make sure you only have a single unpublished post! Additional posts adds “noise” and we’ll discuss overcoming that later. You can run the setup commands listed in the &lt;a href="https://github.com/simple-thread/great_scott/blob/master/README.md"&gt;README&lt;/a&gt; to reset the database and create this single unpublished post.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--5Kqir19i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/image5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--5Kqir19i--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/image5.jpg" alt="timing attack marty doc"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To start we’ll build a simple method to wrap the search route. For all intents and purposes this is basically curl.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Next we want to measure how long it takes for the server to respond. We’ll wrap our &lt;code&gt;get&lt;/code&gt; method above with a benchmark to measure the time it takes for the server to respond in milliseconds:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Now we’re ready to actually build our test case. We’ll test two search terms: ‘scott,’ and ‘blake’. ‘scott’ is in the unpublished post’s title while ‘blake’ is not. We’ll run 100 trials each by passing the term into the previously defined &lt;code&gt;benchmark_get&lt;/code&gt; method. The &lt;code&gt;results&lt;/code&gt; variable contains the search term and an array of runtimes.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/simple-thread/great_scott/blob/master/hackz0r/basic_compare.rb"&gt;See full script here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally let’s do some number crunching on the results.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Term: scott&lt;br&gt;
Trials: 100&lt;br&gt;
Min: 87.3&lt;br&gt;
Max: 135.3&lt;br&gt;
Mean: 95.7&lt;br&gt;
Standard Deviation: 6.7&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Term: blake&lt;br&gt;
Trials: 100&lt;br&gt;
Min: 75.6&lt;br&gt;
Max: 161.1&lt;br&gt;
Mean: 84.7&lt;br&gt;
Standard Deviation: 11.5&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;( Results will vary )&lt;/p&gt;

&lt;p&gt;The first thing to note is that there is a noticeable gap between the averages. “Scott” took ever slightly longer to run. Approximately 10ms longer to run then “blake”. That’s seems like a positive result but how can we be sure? Request times can vary after all, just take a look at the minimum and maximum result for each term. Maybe if we ran this script again “blake” might come back with a higher average? Maybe this was just dumb luck?&lt;/p&gt;

&lt;p&gt;Rephrasing those questions in a more scientific way: how do we know the results are statistically significant? That’s where computing a confidence interval comes in.  A confidence interval gives us a range that likely includes the true mean. You can read more about how this value is computed &lt;a href="https://en.wikipedia.org/wiki/Confidence_interval"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Term: scott&lt;br&gt;
Confidence Interval 95%: [94.3, 96.9]&lt;br&gt;
Confidence Interval 99%: [93.9, 97.4]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Term: blake&lt;br&gt;
Confidence Interval 95%: [82.4, 87.0]&lt;br&gt;
Confidence Interval 99%: [81.6, 87.7]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For “scott” we are 99% sure that our confidence interval of 93.9ms to 97.4ms contains the true mean.  For “blake” we are 99% sure that our confidence interval of 81.6ms to 87.7ms contains the true mean. Since there is a gap between the low end of scott’s range and the high end of blake’s range we can draw a reasonable conclusion. Yes there indeed is a measurable difference when a search query contains text from an unpublished post title.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extracting Title Length
&lt;/h2&gt;

&lt;p&gt;Now that we’ve established that there’s a measurable difference, how do we extract the full title? We could just start by feeding single characters into a query. Doing so would allow us to confirm there’s say one or more ‘A’ characters somewhere in the title but we wouldn’t know the location. Also how would we know when we’ve extracted the full title and can stop? Wouldn’t it be nice if we could determine the length of the secret title first?&lt;/p&gt;

&lt;p&gt;Take a closer look at those search options. “Use a ‘?’ for single character wildcards” Let’s put it to good use.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/simple-thread/great_scott/blob/master/hackz0r/find_digits.rb"&gt;See full script here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We feed in a series of queries with an increasing number of question marks. e.g. “?”, “??”, “???”&lt;/p&gt;

&lt;p&gt;Let’s chart the mean:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OKsVSG6W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-20-at-10.16.36-AM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OKsVSG6W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/Screen-Shot-2019-02-20-at-10.16.36-AM.png" alt="timing attack response time"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our title is “Great Scott! We Must Get Back to the Future” which is 43 characters. Notice the dip in results between between passing queries with 43 and 44 question marks? We’ve determined the character length of the secret blog post from the attacker’s perspective.&lt;/p&gt;

&lt;p&gt;There’s an additional benefit to extracting the title length first. When we move out of the lab environment and have multiple posts in the system, then published posts will add processing time and thus help “cover up” unpublished posts. As the attacker, being able to filter by title length means an unpublished post with a unique character count is ripe for the picking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coup De Grâce
&lt;/h2&gt;

&lt;p&gt;To get the first letter of our hidden post title we can iterate from ‘a’ to ‘z’ with 42 wildmark characters (question marks). That makes 43 characters total.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Let’s chart the mean result for each letter:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cbwLYh7z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/image3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cbwLYh7z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/image3.png" alt="timing attack search term response"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice the “g” stands out? We’ve extracted the first letter of the post. Before we go adding a loop and calling it a day we should consider two additional things.&lt;/p&gt;

&lt;p&gt;First is that we are only querying for alphabetic letters. What happens when our script hits the “!” character? We need a way to differentiate when the character we’re scanning for doesn’t exist in our list. Ultimately we can skip these characters and come back after extracting the alphabetic characters with a list of educated guess characters.&lt;/p&gt;

&lt;p&gt;If the leading result doesn’t stand out then we can conclude that the character doesn’t exist in our list. An easy way to check this is to calculate the difference (delta) between the leading character’s mean and mean of all results. In our algorithm we’ll set a delta threshold value that determines whether we accept the winning result or leave the character as a wildcard “?” and continue on.&lt;/p&gt;

&lt;p&gt;The second issue is the huge number of requests this is going to take. So far we’ve been using 100 trials/requests per a query term. The minimal proof script resulted in 200 requests total. Extracting the title length took 6,000 requests. If you’ve been following along with the repo you will have noticed a significant jump in time to run those two scripts. Now if we stay our current course it’s going to take us 111,800 requests. (43 characters in the title * 26 characters * 100 trials )&lt;/p&gt;

&lt;p&gt;Can we dial back the number of requests we’re running per character? Well, as we decrease the number of requests the outlying results are going to have a greater impact. Take a look back at the results for the initial proof of concept test. “blake” actually had the higher maximum result even though it’s average was significantly less than “scott”. Over 100 trials this result was “smoothed” over by a series of typical results into a mean that was less than “scott”. As we decrease the number of trials we’re going to get less of this smoothing effect and our mean will include more noise.&lt;/p&gt;

&lt;p&gt;One way of working with less data is checking whether the data is tightly grouped or contains big outliers. If the data contains huge outliers we can throw out the results and try again. We can use standard deviation for this but that value will scale as the run time changes and we would need to keep constantly adjusting our threshold. We can normalize this value as a percentage by dividing the standard deviation against the mean. This is called &lt;a href="https://en.wikipedia.org/wiki/Coefficient_of_variation"&gt;Coefficient of Variation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;By doing this check we can reduce the number of trials per character to 10. Sometimes the winning character isn’t going to be clear. In those cases we’ll have to throw out the results and try again. Even so, this is going to come out to considerably less requests than sticking with 100 trials each for our upcoming timing attack.&lt;/p&gt;

&lt;p&gt;Let’s put it all together in the final code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/simple-thread/great_scott/blob/master/hackz0r/coup_de_grace.rb"&gt;See final code here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note that depending on your environment you may need to tweak the constants at the top of the script.  Here’s a snippet of output:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Trial 1 of 10&lt;br&gt;
Trial 2 of 10&lt;br&gt;
Trial 3 of 10&lt;br&gt;
Trial 4 of 10&lt;br&gt;
Trial 5 of 10&lt;br&gt;
Trial 6 of 10&lt;br&gt;
Trial 7 of 10&lt;br&gt;
Trial 8 of 10&lt;br&gt;
Trial 9 of 10&lt;br&gt;
Trial 10 of 10&lt;br&gt;
Exporting results to csv...&lt;br&gt;
tmp/1548447356.csv&lt;br&gt;
Delta: 16.7114306526752&lt;br&gt;
Coefficient Variation: 9.705968406065965&lt;br&gt;
Current Secret: great sc*??????????????????????????????????&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Additional Optimizations
&lt;/h2&gt;

&lt;p&gt;There’s plenty more you could do to optimize this further.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The attacking script could be optimized by short circuiting after one character’s result has an anomaly.&lt;/li&gt;
&lt;li&gt;The attacker could use letter frequencies to start with more likely characters instead of iterating A-Z.&lt;/li&gt;
&lt;li&gt;For performing the attack over a network, the demo app freely gives out the the &lt;code&gt;X-RUNTIME&lt;/code&gt; header which reports how long the server took to process the request. The attacker can use that header instead of benchmarks to get jitter-free results over a network.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  DE—FENSE!
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Fundamentally there are three ways to mitigate a timing attack.&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Eliminate or decrease the time difference between conditional branches that depend on private information.&lt;/li&gt;
&lt;li&gt;Decrease number of requests an attacker can make.&lt;/li&gt;
&lt;li&gt;Increase variance which forces the attacker to make more requests to overcome additional variance. (e.g. Adding jitter with &lt;code&gt;sleep rand&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ultimately if the response time from the server is the same regardless of private information then a timing attack is not possible. Increasing jitter should not be considered effective by itself, because jitter can be cancelled out through statistical means.&lt;/p&gt;

&lt;p&gt;Specific to our demo application here’s the culprit code:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/simple-thread/great_scott/blob/master/app/controllers/posts_controller.rb#L7-L10"&gt;More Context Here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First let’s note that this is poorly written code for the sake of demonstration.  We collect a list of posts filtered by title. This is done using a SQL query, so it’s fast. Then we inefficiently iterate over each individual post to filter by author. Finally we decide whether the posts should be visible if the post is published or if the user is logged in as an admin.&lt;/p&gt;

&lt;p&gt;This code can be optimized to use a single query instead of iterating — which avoids those extra milliseconds of delay the attacker needs.  If we absolutely must iterate then we should swap the order of these filters. Gather a list of published posts first, then filter by title. Doing so avoids iterating over hidden posts by their title and thus can’t reveal information about the title.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;  &lt;/div&gt;

&lt;p&gt;Running our minimal test from earlier results in:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Name: scott&lt;br&gt;
Trials: 100&lt;br&gt;
Min: 76.8&lt;br&gt;
Max: 111.9&lt;br&gt;
Mean: 82.3&lt;br&gt;
Standard Deviation: 4.8&lt;br&gt;
Confidence Interval 95%: [81.38422898750433, 83.26669763389363]&lt;br&gt;
Confidence Interval 99%: [81.07523792180912, 83.57568869958884]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Name: blake&lt;br&gt;
Trials: 100&lt;br&gt;
Min: 74.0&lt;br&gt;
Max: 109.4&lt;br&gt;
Mean: 81.8&lt;br&gt;
Standard Deviation: 5.7&lt;br&gt;
Confidence Interval 95%: [80.72481552206241, 82.96866577575187]&lt;br&gt;
Confidence Interval 99%: [80.35650676830025, 83.33697452951404]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This is a good sign.  &lt;/p&gt;

&lt;p&gt;The confidence intervals no longer have a gap like they did prior to our server side change. However, this does not definitively prove that a timing attack is impossible.&lt;/p&gt;

&lt;p&gt;For the attacker, a gap between two search terms is a positive result but lack of a gap isn’t necessarily a negative result. As the number of trials increases the confidence interval will get narrower.  It’s possible that the attacker could run a higher number of trials and then there would be a statistically significant gap.&lt;/p&gt;

&lt;p&gt;100 requests is a rather small amount.  Let’s bump that up:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Name: scott&lt;br&gt;
Trials: 100000&lt;br&gt;
Min: 69.6&lt;br&gt;
Max: 8226.2&lt;br&gt;
Mean: 94.5&lt;br&gt;
Standard Deviation: 197.6&lt;br&gt;
Confidence Interval 95%: [93.30207952605443, 95.7513753943521]&lt;br&gt;
Confidence Interval 99%: [92.91469089382367, 96.13876402658285]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Name: blake&lt;br&gt;
Trials: 100000&lt;br&gt;
Min: 68.6&lt;br&gt;
Max: 5974.0&lt;br&gt;
Mean: 94.1&lt;br&gt;
Standard Deviation: 200.2&lt;br&gt;
Confidence Interval 95%: [92.81101468120839, 95.2932841341303]&lt;br&gt;
Confidence Interval 99%: [92.41841083916462, 95.68588797617407]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Even with 100,000 requests there still is no statistically significant finding.  At this point the attacker would be entering DoS territory. In order to call our demo app “fixed” we should add a request throttling library.  (In the Ruby world that would be &lt;a href="https://dev.to/scottw/rack-attack-rack-middleware-for-blocking--throttling-5024"&gt;rack-attack&lt;/a&gt;) Thus even if an attack is theoretically possible with a higher number of requests it becomes impractical because of the limited throughput.&lt;/p&gt;

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

&lt;p&gt;Most people either don’t understand a timing attack, or see them as an esoteric issue with which they don’t need to concern themselves. I hope that with this post you now see that innocent decisions made during an application’s implementation could lead to potential data leaks vulnerable to a timing attack, and give you some ideas on how to address one.&lt;/p&gt;

&lt;p&gt;Drop me a line, or submit a pull request if you want to dive in further!&lt;/p&gt;

&lt;p&gt;The post &lt;a href="https://www.simplethread.com/great-scott-timing-attack-demo/"&gt;Great Scott! Timing Attack Demo for the Everyday Webdev&lt;/a&gt; appeared first on &lt;a href="https://www.simplethread.com"&gt;Simple Thread&lt;/a&gt;.&lt;/p&gt;


</description>
      <category>security</category>
      <category>webdev</category>
      <category>ruby</category>
      <category>timingattack</category>
    </item>
    <item>
      <title>A Fictional Account of How I Invented React: A Simplified Perspective of How React Works</title>
      <dc:creator>Simple Thread</dc:creator>
      <pubDate>Tue, 19 Feb 2019 13:30:36 +0000</pubDate>
      <link>https://dev.to/simple_thread/a-fictional-account-of-how-i-invented-react-a-simplified-perspective-of-how-react-works-4hc1</link>
      <guid>https://dev.to/simple_thread/a-fictional-account-of-how-i-invented-react-a-simplified-perspective-of-how-react-works-4hc1</guid>
      <description>&lt;p&gt;This past year I decided to catch up on the latest in JavaScript frameworks and learn React. Actually, it was it bit more than just learning React as I also was eager to pick up ES6 and Node. Anyway, after experiencing the complexities of Angular, Backbone, Ember, and Knockout, I found React’s clarity amazing. That said, I did, however, think that the couple books and dozens of articles I read overly complicated the &lt;a href="https://dev.to/simple_thread/software-complexity-is-killing-us-5fcp-temp-slug-8295388"&gt;simplicity&lt;/a&gt; of React.&lt;/p&gt;

&lt;p&gt;I adopted a technology comprehension strategy from a mentor, Eduardo Ross (VP of Technology at &lt;a href="http://asna.com"&gt;ASNA&lt;/a&gt;), who said: “&lt;em&gt;I consider how I might have coded it. And, if it’s well designed, I’m usually right.&lt;/em&gt;” Anyway, as I began to read more about the intricacies of React that were developed to handle edge cases my mind began to create a simplified view of how React works. I began to ignore these added features and instead develop a simplified perspective of why React was created and how it was implemented.&lt;/p&gt;

&lt;p&gt;The following is a work of fiction but it is based on the elegance of the React framework. The story is false but the method names and behaviors are real — names of the innocent were not changed to protect them.&lt;/p&gt;

&lt;h2&gt;
  
  
  One Language and No Salad Dressing
&lt;/h2&gt;

&lt;p&gt;I’ve been at this Web thing since before Perl scripts, PHP, and the Java Servlet API. I’ve been an author and trainer and, I’ll tell you, this mix-and-match of HTML and &lt;em&gt;INSERT_LANGUAGE_HERE&lt;/em&gt; in Java Server Pages (JSP) or Groovy Server Pages (GSP) or Embedded RuBy (ERB) was madness. Then LiveScript came out (sorry, JavaScript) and things got yet more complicated. Using multiple languages in one file is like mixing oil and vinegar — in that they don’t mix.&lt;/p&gt;

&lt;p&gt;Actually, that’s salad dressing, but, to make it palatable, you have to add zest and vigorously shake. It’s like your web code needs a comment: Shake brain vigorously before trying to maintain.&lt;/p&gt;


&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hvh8eBlW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/http://www.quickmeme.com/img/51/517f960a190fb6c15251dc72d324d08e4d41fdd26ded135445483f2678729e5c.jpg" alt="Salad Dressing"&gt;&lt;/center&gt;What I wanted (what we all wanted) was one language. One language that would rule them all. A language used to create the browser’s Document Object Model (DOM). The obvious language to use is the world’s most prevalent and pervasive — JavaScript. But its syntax would need to be similar to XHTML. So let’s call it JSX for JavaScript XHTML. The following shows the simplest React JSX you might write:


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;You can try this code on &lt;a href="https://codepen.io/denoncourt/pen/MZVWNK"&gt;Codepen.io&lt;/a&gt;. Codepen manages the loading of the required React libraries. &lt;code&gt;ReactDOM&lt;/code&gt;, in the above code, makes the Header 1 element render into a DOM node with the ID of &lt;code&gt;root&lt;/code&gt;. Your React apps might have a minimal HTML page as follows:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;But you could use React on any HTML. The &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; contained within the &lt;code&gt;element&lt;/code&gt; variable above looks like HTML. It is not. It is a JavaScript function called &lt;code&gt;h1&lt;/code&gt;, implemented with the React libraries. In fact, during my delusions of creating React, I wrote JavaScript implementations for all the HTML tags. Like I said: no HTML, only JavaScript. (If you are still in ES5-land seeing &lt;a href="https://babeljs.io/repl#?babili=false&amp;amp;browsers=&amp;amp;build=&amp;amp;builtIns=false&amp;amp;spec=false&amp;amp;loose=false&amp;amp;code_lz=EoUwhgxgLgIg8gWQHQCcQDsAmIUAoA8AFgIwB8A6iADYQD2AtiAIT4D0JpANAASa0QBXRuihIAjgJwBPAMrUQ0WngDkAYhS1aUZQEodAKCA&amp;amp;debug=false&amp;amp;forceAllTransforms=false&amp;amp;shippedProposals=false&amp;amp;circleciRepo=&amp;amp;evaluate=false&amp;amp;fileSize=false&amp;amp;timeTravel=false&amp;amp;sourceType=module&amp;amp;lineWrap=true&amp;amp;presets=es2015%2Creact%2Cstage-2&amp;amp;prettier=false&amp;amp;targets=&amp;amp;version=6.26.0&amp;amp;envVersion="&gt;ES6 transpiled to ES5&lt;/a&gt; might be interesting)&lt;/p&gt;

&lt;p&gt;The trivial example above shows the simplicity of React but, it really is not yet very useful. The pages of our applications need to be dynamic.&lt;/p&gt;

&lt;p&gt;How might I pass data to one of these JSX components? Following our conceptual mapping of HTML syntax to JavaScript, we could use attributes. The image (&lt;code&gt;img&lt;/code&gt;) tag, for example, has, besides the ever present &lt;code&gt;id&lt;/code&gt; attribute, &lt;code&gt;src&lt;/code&gt;, &lt;code&gt;alt&lt;/code&gt;, &lt;code&gt;height&lt;/code&gt;, and &lt;code&gt;width&lt;/code&gt;. But, for our custom components, we will be creating our own non-HTML JSX functions and we can use any set of attributive name-value pairs. Consider the following:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The above code defines a custom JSX element called &lt;code&gt;Welcome&lt;/code&gt;. The usage of the Welcome JSX element is in the first argument of the call to &lt;code&gt;ReactDOM.render&lt;/code&gt; specifies two attributes: &lt;code&gt;name&lt;/code&gt; and &lt;code&gt;onClick&lt;/code&gt;. Name is set to simple text but onClick is an inline definition of an ES6 fat arrow function. So, using any name-value pairs we can pass any kind of data including function implementations.&lt;/p&gt;

&lt;p&gt;I said name-value pairs but, actually, all the attributes with their values are passed as a JavaScript object. So, it’s more correct to say key-value pair.&lt;/p&gt;

&lt;p&gt;If you try the Welcome code on &lt;a href="https://codepen.io/denoncourt/pen/YdevmZ"&gt;codepen&lt;/a&gt; you’ll see the value passed via the name key is used in the “&lt;em&gt;Hello from&lt;/em&gt;” string. Furthermore, if you click on the text, you’ll see the following in the console log:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;click [object HTMLDivElement] div-id&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Understand that the function executed from within the Welcome JSX function. The above code passed a JavaScript ES6 anonymous function inline with the attribute &lt;code&gt;name&lt;/code&gt; of &lt;code&gt;onClick&lt;/code&gt;. After all, JavaScript functions, as first class objects or citizens, can be passed around via arguments.&lt;/p&gt;

&lt;p&gt;I’m sure you know all about JavaScript handlers for HTML events, such as those listed at &lt;a href="https://www.w3schools.com/jsref/dom_obj_event.asp"&gt;w3schools&lt;/a&gt;. Various DOM elements generate these events. Before React, we set &lt;code&gt;onclick&lt;/code&gt; attributes directly in HTML source code to specify JS event handlers. This gave way to unobtrusive JavaScript and the binding of element events of DOM nodes in separate scripts using jQuery or &lt;code&gt;addEventListener&lt;/code&gt;. With React you specify the event in either inline JS code or pass a reference to a function.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I did have one problem with the naming of the attribute: I found I had to use mixed-case for the handler to avoid confusion. In fact, stick with camelCase for all your JSX attributes.&lt;/em&gt; (Check out the React docs for &lt;a href="https://reactjs.org/docs/dom-elements.html"&gt;DOM elements&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;My use of the term, attribute, is no longer broad enough to describe key-value pairs passed to React JavaScript functions. Let’s call them properties, or just &lt;code&gt;props&lt;/code&gt;. Properties are the magic that turns components into dynamic elements — they allow the embedding, nesting, and reuse of components.&lt;/p&gt;

&lt;h2&gt;
  
  
  JavaScript eXpressions
&lt;/h2&gt;

&lt;p&gt;JSX statements are expressions. Their name and properties describe what behaviors their JavaScript implementations provide. Earlier I said JSX stood for JavaScript XHTML but JavaScript eXpression is more articulate.&lt;/p&gt;

&lt;p&gt;As React is all JavaScript, your custom React component can contain other custom JSX components (as well as the standard HTML components like &lt;code&gt;h1&lt;/code&gt;, &lt;code&gt;p&lt;/code&gt;, &lt;code&gt;ul&lt;/code&gt;, &lt;code&gt;li&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;p&gt;To keep functional React components in the pure function category, their &lt;code&gt;props&lt;/code&gt; parameter should not be modified inside the component. Or, in functional programming terms, they are considered to be immutable objects. You can always re-invoke the function with a new props object, But that gets tedious.&lt;/p&gt;

&lt;h2&gt;
  
  
  Class
&lt;/h2&gt;

&lt;p&gt;Our complex business requirements necessitate the maintenance of application state. In object oriented programming a class is a template used to instantiate objects that contain state and methods/functions that manipulate that state. So, begrudgingly, in my invention of React, I’m going to need classes. When the state of an object instance of a React class changes, React will automatically update the browser’s DOM. To be very specific about the state that a React class is prepared to react to, those values must be contained within an instance property called, well… state.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://codepen.io/denoncourt/pen/rovMLL"&gt;Codepen.io&lt;/a&gt; hosts a simple example of a React component. The following shows the implementation of the constructor function for the component:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;center&gt;


&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7qgPr6st--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/justme-codepen-1024x936.png" alt="" width="680" height="622"&gt;&lt;p&gt;JustMe React application in Codepen.io&lt;/p&gt;









&lt;/center&gt;JustMe’s &lt;code&gt;state&lt;/code&gt; contains &lt;code&gt;mental&lt;/code&gt; state and state &lt;code&gt;locality&lt;/code&gt;. (Your applications may be a bit more complex.) &lt;code&gt;State&lt;/code&gt; is a JavaScript object that can be as complex as you’d like. What I envisioned was for React to respond to changes in the &lt;code&gt;state&lt;/code&gt; object by turning on the properties watering hose and dowsing its nested JSX with the updated values. React would then update the DOM to reflect the values in the modified &lt;code&gt;state&lt;/code&gt;. To manage the massive process of updating the DOM with &lt;code&gt;state&lt;/code&gt; changes, I minimized it by requiring changes to &lt;code&gt;state&lt;/code&gt; to be done in a function called &lt;code&gt;setState&lt;/code&gt;. After calls to the &lt;code&gt;setState&lt;/code&gt; method complete, the DOM refresh runs.

&lt;p&gt;Consider coding state management yourself…. You have to implement some implementation of the Observable pattern. Just pondering on it now, brings back of painful memories working with updates to Angular 1’s $scope.&lt;/p&gt;

&lt;p&gt;The handleStateChange method below embeds a call to &lt;code&gt;setState&lt;/code&gt; change. I’ll explain in a bit why the &lt;code&gt;state&lt;/code&gt; key is defined as a computed property. For now, suffice to say that, after &lt;code&gt;setState&lt;/code&gt; runs, all nested JSX that display values for mental or locality will be refreshed.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Cascading Properties
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;render&lt;/code&gt; method of your React class is where you tell React what JSX is to be, well, rendered as DOM. All the JSX functions therein are invoked passing, not just the key-value pairs of attributes in the &lt;code&gt;props&lt;/code&gt; variable. but optionally also the &lt;code&gt;state&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href="https://codepen.io/denoncourt/pen/rovMLL"&gt;codepen&lt;/a&gt; was created to show the flow of state through &lt;code&gt;&amp;lt;JustMe&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;LevelTwo&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;LevelThree&amp;gt;&lt;/code&gt;. The first line of the &lt;code&gt;return&lt;/code&gt; clause of the two Level functions does a &lt;code&gt;console.log&lt;/code&gt; of the passed properties:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;console.log('LevelTwo props: %O', props)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The result of which, when the page loads, is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;▾ "LevelTwo props: %O" Object {&lt;br&gt;
locality: "VA",&lt;br&gt;
mental: "hanging on",&lt;br&gt;
name: "LevelTwo",&lt;br&gt;
▸ onClick: function click(e) {↔}&lt;br&gt;
▸ onStateChange: function (e) {↔&lt;br&gt;
}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Notice the &lt;code&gt;state&lt;/code&gt; values of &lt;code&gt;mental&lt;/code&gt; and &lt;code&gt;locality&lt;/code&gt; (that were initially set in JustMe’s constructor) are passed. When these &lt;code&gt;state&lt;/code&gt; values change in their parent component (&lt;code&gt;JustMe&lt;/code&gt;), those &lt;code&gt;props&lt;/code&gt; values are passed down to children and trigger a re-render of descendant components that use them (&lt;code&gt;LevelTwo&lt;/code&gt; and &lt;code&gt;LevelThree&lt;/code&gt;.) So in addition to cascading properties, you also get cascading updates and selective re-rendering of stuff that’s changed. Pretty cool. As I said, properties are the magic that enables the propagation of values to nested components.&lt;/p&gt;
&lt;h3&gt;
  
  
  Lifting State Up
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;LevelThree&lt;/code&gt; has inputs for the &lt;code&gt;mental&lt;/code&gt; and &lt;code&gt;locality&lt;/code&gt; values. That component is, well…, three levels down from &lt;code&gt;JustMe&lt;/code&gt;. I explained how the values cascaded down the nested component tree, but how is the &lt;code&gt;state&lt;/code&gt; object — maintained by the root component &lt;code&gt;JustMe&lt;/code&gt; — going to be updated?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Property values cascade down but state updates are lifted up!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;JustMe&lt;/code&gt; passes its &lt;code&gt;handleStateChange&lt;/code&gt; method to &lt;code&gt;LevelOne&lt;/code&gt; with:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;onStateChange={this.handleStateChange}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;I could have used any object key to hold a reference to &lt;code&gt;handleStateChange&lt;/code&gt;, including handleStateChange but I used &lt;code&gt;onStateChange&lt;/code&gt; to show you can use whatever name you prefer for your property’s object keys.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;LevelTwo&lt;/code&gt; then did the same and passed everything to &lt;code&gt;LevelThree&lt;/code&gt;. But, rather than explicitly specifying the key-value pairs as &lt;code&gt;JustMe&lt;/code&gt; did when it called &lt;code&gt;LevelThree&lt;/code&gt;, in &lt;code&gt;LevelThree&lt;/code&gt; I got lazy and passed the full properties object:&lt;/p&gt;

&lt;p&gt;Actually, it used ES6’s spread operator (&lt;code&gt;...props&lt;/code&gt;) to create a new object. Remember: The key-value pairs specified in a JSX are passed as a JavaScript object to the function that implements the JSX.&lt;/p&gt;

&lt;p&gt;At any rate, the &lt;code&gt;LevelThree&lt;/code&gt; method has a reference to JustMe’s &lt;code&gt;handleStateChange&lt;/code&gt; function. So, when the user modifies the &lt;code&gt;mental&lt;/code&gt; or &lt;code&gt;locality&lt;/code&gt; input fields, their DOM’s &lt;code&gt;onchange&lt;/code&gt; event is handled by the passed properties &lt;code&gt;onStateChange&lt;/code&gt; reference. Which, we know, came originally from &lt;code&gt;JustMe&lt;/code&gt;. So state changes are “Lifted Up” from the following &lt;code&gt;LevelThree&lt;/code&gt; input fields to &lt;code&gt;LevelTwo&lt;/code&gt; back up to &lt;code&gt;JustMe&lt;/code&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  When It’s Time To StageChange (You’ve Got to Rearrange)
&lt;/h2&gt;

&lt;p&gt;Change is tough, just &lt;a href="https://www.youtube.com/watch?v=MKEQm10-n84"&gt;ask Peter Brady&lt;/a&gt;. Now I can explain to you the implementation of &lt;code&gt;handleStateChange&lt;/code&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;It takes one argument, &lt;code&gt;e&lt;/code&gt;, which, when &lt;code&gt;onchange&lt;/code&gt; calls it, will be the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Even"&gt;event object&lt;/a&gt;. The event object has a bunch of properties one of which is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Event/target"&gt;target&lt;/a&gt;. &lt;code&gt;Target&lt;/code&gt; has a property called &lt;code&gt;name&lt;/code&gt;. Well, here’s the gimmick: &lt;code&gt;LevelTwo&lt;/code&gt; defined the values for the input fields to match the object key names defined in &lt;code&gt;JustMe&lt;/code&gt;. So, when &lt;code&gt;mental&lt;/code&gt; state is changed to “completely nuts” the following code in:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;obj[e.target.name] = e.target.value;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Executes essentially as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;state[mental]: “completely nuts”&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Where the brackets contain any JavaScript expression that converts to an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names"&gt;object property name&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This is really crazy, and I’m so impressed with my React code (which I delusionally created) that updates the DOM: but, as you type “completel” — “y nuts” not yet typed — in the mental input field, you can watch the text displayed in the JSX in JustMe as:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;{this.state.mental}&lt;/code&gt; in &lt;code&gt;{this.state.locality}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Changes from:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;JustMe’s state:hanging on in VA&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;JustMe’s state:completel in VA&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For added kicks, you can click on the text displayed on the page in the div sections of LevelOne or LevelTwo and the console will display:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“LevelTwo-div clicked” or “LevelThree-div clicked”.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Note: I defined the &lt;code&gt;click&lt;/code&gt; function stand-alone just to be different as it wasn’t necessarily a behavior specific to the &lt;code&gt;JustMe&lt;/code&gt; component.&lt;/p&gt;

&lt;h2&gt;
  
  
  No Thanks to Dad
&lt;/h2&gt;

&lt;p&gt;Why no inheritance? Inheritance for React provides little. In fact, React is more about nesting JSX (composition) than inheritance. A well accepted principle of OOP is: “&lt;em&gt;Prefer composition over inheritance.&lt;/em&gt;” Actually, even though the power of classes is available in React, I recommend you start with functional components and only use class components when &lt;code&gt;state&lt;/code&gt; is required.You will find use of pure functions will make your code easier to understand, test, reuse, and maintain.&lt;/p&gt;


&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hbbPRXKr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/thanksdad.jpg" alt="" width="457" height="307"&gt;&lt;/center&gt;
&lt;h2&gt;
  
  
  Getting Real
&lt;/h2&gt;

&lt;p&gt;OK, OK, I didn’t invent nor have anything to do with the development of React. But you already knew that because you’ve already checked Wikipedia and React’s commit log.&lt;/p&gt;

&lt;p&gt;But, as I said, React’s clarity is amazing. It just makes sense — especially when compared to other JavaScript frameworks. React certainly has its own complexities (e.g. callbacks and context) but, for the most part, your code will be more clear without them. That said, you probably should look at React lifecycle events. I’m also quite excited about &lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;React Hooks&lt;/a&gt; as they let coders package state and side effects in pure functional components.&lt;/p&gt;

&lt;h2&gt;
  
  
  A few recommendations:
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Use codepen.io&lt;/strong&gt; :Read (and copy) other mini React apps. I want to point out that, often, when React code looks complicated, it is ES6 (or advanced JS) not React that is complicated. I had just picked up ES6 before learning React, which was good because ES6 features like spread, rest, and de-structuring are used heavily in React apps.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Get comfortable with ES6&lt;/strong&gt; : I highly recommend the book &lt;a href="https://pragprog.com/book/es6tips/simplifying-javascript"&gt;Simplifying JavaScript&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The reactjs.org &lt;a href="https://reactjs.org/docs/getting-started.html"&gt;Getting Started&lt;/a&gt; is great and makes great use of codepen.io. I also got a lot out of the vides at the Material UI &lt;a href="https://material-ui.com/getting-started/learn/"&gt;getting started&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Hey! I even came up with a clever logo for this new library!&lt;/em&gt;&lt;/p&gt;


&lt;center&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Qs39exTx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://www.simplethread.com/wp-content/uploads/2019/02/react-logo-1024x724.png" alt="" width="680" height="481"&gt;&lt;/center&gt;

&lt;p&gt;The post &lt;a href="https://www.simplethread.com/how-i-invented-react/"&gt;A Fictional Account of How I Invented React: A Simplified Perspective of How React Works&lt;/a&gt; appeared first on &lt;a href="https://www.simplethread.com"&gt;Simple Thread&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>react</category>
      <category>technology</category>
    </item>
  </channel>
</rss>
