<?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: Zachnology</title>
    <description>The latest articles on DEV Community by Zachnology (@zachnology).</description>
    <link>https://dev.to/zachnology</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%2F863521%2F7580d8f5-abf1-4179-83b1-a0c1a762d222.png</url>
      <title>DEV Community: Zachnology</title>
      <link>https://dev.to/zachnology</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zachnology"/>
    <language>en</language>
    <item>
      <title>Do Your Loops Have Knots?</title>
      <dc:creator>Zachnology</dc:creator>
      <pubDate>Wed, 15 May 2024 16:22:06 +0000</pubDate>
      <link>https://dev.to/zachnology/do-your-loops-have-knots-24o7</link>
      <guid>https://dev.to/zachnology/do-your-loops-have-knots-24o7</guid>
      <description>&lt;p&gt;Avoiding I/O performance pitfalls&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Cover Photo by &lt;a href="https://unsplash.com/@onderortel?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Önder Örtel&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/brown-rope-tied-on-white-background-WJ09YGBdrZs?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I/O operations are expensive. As an application scales I/O operations can become serious bottlenecks. Whether an application pulls data from a database, a web service, or an IoT device, it can suffer from the same problem: expensive I/O operations inside of loops. Here we will view the problem through the lens of Entity Framework in C#.&lt;/p&gt;

&lt;h2&gt;
  
  
  Identifying the Problem
&lt;/h2&gt;

&lt;p&gt;Without experience with this issue, it can be easy to overlook during initial development. Unit tests, integration tests, and manual QA testing may not use large enough datasets to identify problems preemptively. If not caught ahead of time, the issue will certainly be noticed in production. Here is what it might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;GetUsers&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetRawUsers&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="nf"&gt;SomeExpensiveOperation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s say that &lt;code&gt;GetRawUsers()&lt;/code&gt; and &lt;code&gt;SomeExpensiveOption()&lt;/code&gt; take 100ms each to run. If there are only 10 users in the users array, then &lt;code&gt;GetUser()&lt;/code&gt; takes 1100ms to run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;100ms + (100ms * user_count)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see the problem with scale now. The cost in time increases linearly with the number of users. With only 100 users, it will take 10,100ms to run the &lt;code&gt;GetUsers()&lt;/code&gt; method and even worse if &lt;code&gt;SomeExpensiveOperation()&lt;/code&gt; contains a loop of its own.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to address it
&lt;/h2&gt;

&lt;p&gt;In real-world scenarios, the problem code might be more subtle than the above contrived scenario. Here are some ways to identify such cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be mindful of when a query is executed
&lt;/h3&gt;

&lt;p&gt;One common cause for this issue when using Entity Framework, and I suppose other frameworks that provide query building, is not paying attention to when the query is executed. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;usersWithGreenEyes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EyeColor&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"green"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;ages&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;usersWithGreenEyes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Today&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DateOfBirth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Year&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because &lt;code&gt;Where()&lt;/code&gt; does not execute a query, each iteration of the loop will fetch the in-scope user record from the database creating a database call per user.&lt;/p&gt;

&lt;p&gt;In Entity Framework, this can be solved by ensuring the query is executed before operations on the data begin by calling a method that takes the &lt;code&gt;IQueryable&lt;/code&gt; returned by &lt;code&gt;Where()&lt;/code&gt; and produces an &lt;code&gt;List&lt;/code&gt; or &lt;code&gt;Array&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; var usersWithGreenEyes = db.Users.Where(u =&amp;gt; u.EyeColor == "green").ToList();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now only one query will be executed and before the loop starts.&lt;/p&gt;

&lt;h3&gt;
  
  
  Be mindful of lazy loading
&lt;/h3&gt;

&lt;p&gt;In Entity Framework, if lazy loading is turned on, seemingly benign references to child entities and child collections, could execute a query. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;distinctTraveledCountries&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;HashSet&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;users&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;distinctTraveledCountries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UnionWith&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TraveledCounties&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we made sure the execute the query before entering the loop, but if lazy loading is turned on, each access to a child collection (like &lt;code&gt;user.TraveledCountries&lt;/code&gt;) will still execute a database query to get the child data.&lt;/p&gt;

&lt;p&gt;This can also happen when using a mapper library. For example, if I have an array of user entities and I want to map that to an array of some type of user view that contains the same child collection of traveled countries.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;UserView&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;userViews&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mapper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;userEntities&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same lazy loading mechanism from the previous example will cause issues here as well since the mapper library will internally access each user in the array.&lt;/p&gt;

&lt;p&gt;Often the solution for both of these cases is the same: eager-load the child collections and child entities, either explicitly or by mapping as part of the query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Eager loading explicitly&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;usersWithChildren&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TraveledCountries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccountInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above will eager load both the &lt;code&gt;TraveledCountries&lt;/code&gt; collection as well as the child member &lt;code&gt;AccountInfo&lt;/code&gt;, so that those properties will be prefetched along with the rest of the User entity.&lt;/p&gt;

&lt;p&gt;In Entity Framework this generates a single query which will include left joins on the child data. In some cases this could cause performance issues itself. One solution would be to use a &lt;a href="https://learn.microsoft.com/en-us/ef/core/querying/single-split-queries"&gt;split query&lt;/a&gt;. This looks almost the same but underneath it executes a query for the parent and a query for each included child. Instead of left joins, the child members are joined with an inner join.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Eager loading explicitly as split query&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;usersWithChildren&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TraveledCountries&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Include&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccountInfo&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AsSplitQuery&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The below will map any needed fields to a custom object type by only selecting the fields needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Mapping in query&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userViews&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;u&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;UserView&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="n"&gt;Id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;AccountInfo&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;u&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AccountInfo&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use Paged Data and Work in Small Batches
&lt;/h3&gt;

&lt;p&gt;You may find that while eager-loading data fixed your performance issue as far as the loop is concerned but it caused another performance issue with a query result set that is too large or a query that takes too long to run. In this case, it may be helpful to limit the scope of an operation. You can do this by implementing pagination. If the application is a web service, you can limit the amount of data returned and provide metadata for fetching the other pages. A response could look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"metadata"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"page"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pageCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"limit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"links"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"self"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://myapi.com/users?page=3&amp;amp;limit=20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"first"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://myapi.com/users?page=1&amp;amp;limit=20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"previous"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://myapi.com/users?page=2&amp;amp;limit=20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://myapi.com/users?page=4&amp;amp;limit=20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"last"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://myapi.com/users?page=10&amp;amp;limit=20"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"users"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;//...&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the application is an automated process, it can work in small batches instead of the entire dataset at once. Pagination for query execution in Entity Framework looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IList&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;User&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetPagedUsers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;currPage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Users&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OrderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Skip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currPage&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="n"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pageSize&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Identifying Before Production
&lt;/h2&gt;

&lt;p&gt;The symptoms of the issue we are discussing usually don’t reveal themselves until applied at scale, so it can be easy for it to get past traditional automated testing and manual QA. Here are some ways to help identify it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Developer education. Learning about pitfalls so they can be addressed during development.&lt;/li&gt;
&lt;li&gt;Setting performance requirements associated with features. Whether or not you have an SLA you must adhere do, you can still include a threshold in the feature requirements before development begins.&lt;/li&gt;
&lt;li&gt;Code reviews&lt;/li&gt;
&lt;li&gt;Realistic testing against production-like environments (the earlier in the release process the better).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Need help with your software project?
&lt;/h2&gt;

&lt;p&gt;My day job is working as a software engineer for &lt;a href="https://trendsic.com"&gt;Trendsic&lt;/a&gt; where I help businesses large and small plan and develop secure and scalable software. Reach out to me at &lt;a href="//mailto:contact@zachnology.io"&gt;contact@zachnology.io&lt;/a&gt; to discuss how I can help bring your ideas to life.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>performance</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Making Websites for Spies</title>
      <dc:creator>Zachnology</dc:creator>
      <pubDate>Tue, 07 May 2024 04:01:37 +0000</pubDate>
      <link>https://dev.to/zachnology/making-websites-for-spies-3m17</link>
      <guid>https://dev.to/zachnology/making-websites-for-spies-3m17</guid>
      <description>&lt;h2&gt;
  
  
  Abstract JavaScript Events
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@olloweb?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Agence Olloweb&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/magnifying-glass-near-gray-laptop-computer-d9ILr-dbEdg?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Have you ever thought about how the CIA communicates with informants all over the globe? There’s the clandestine meeting. Maybe slipping of a note into a pocket as someone walk by. A removable brick in a wall. But is there a way to communicate in plain sight?&lt;/p&gt;

&lt;p&gt;It is believed that during the mid 2000s to at least the early 2010s the CIA created a series of fake websites that handlers used to communicate with informants. To the unknowing eavesdropper, it would look like an informant was just visiting a local news website, but the ordinary-looking search box was actually a password input field that would give them access to the communications functionality.&lt;/p&gt;

&lt;p&gt;Before I ever heard about this practice, I had built a proof of concept for clandestine interaction on websites too. And since I didn’t use it for international espionage, what I’m about to share is completely declassified…&lt;/p&gt;

&lt;h2&gt;
  
  
  Abstract Events
&lt;/h2&gt;

&lt;p&gt;We can detect and listen to pretty much any input performed on a website. Whether we need to simply detect a focus or blur event on an input element or we want to track mouse movement across the page, we have access to the data and the triggering event.&lt;/p&gt;

&lt;p&gt;This is all fine and dandy, but what if I want to implement keyboard shortcuts for my website? Two of the more popular use cases for this is making enter do something other than submitting a form and creating desktop-like shortcuts for web apps (like Ctrl+ shortcuts).&lt;/p&gt;

&lt;p&gt;The case of overriding the behavior of the enter press is mostly trivial. You’ll need to listen to the keydown or keyup event, then check if enter is the key that has been pressed. If so, cancel the default behavior and then do whatever you want enter to do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Enter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// your custom logic here&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works the same way for the Ctrl+ shortcuts but you just check if ctrl is also pressed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ctrlKey&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;z&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// your custom logic here&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These simple key “overrides” got me thinking about making an event listener factory that took abstract instructions and produced a JS event handler. My goal was to come up with some unique input events and provide an easy to use interface for it.&lt;/p&gt;

&lt;p&gt;What if I wanted to listen for more complex input that needed more information than a single mouse or key event could give me? Can I trigger special behavior if a key word is typed in even if an input element is not in focus? Can I make a button behave differently depending on how many times I clicked it, or how fast I clicked it? If we buffer the input, we can easily track these types of events.&lt;/p&gt;

&lt;p&gt;I created a proof of concept npm package called abstract-events that exposes a simple interface for this type of event. The create() method accepts 2 parameters: options and a callback. Here are some examples:&lt;/p&gt;

&lt;h2&gt;
  
  
  Count Events
&lt;/h2&gt;

&lt;p&gt;The first type of abstract event is a count event. It triggers once an input event has been triggered a defined number of times.&lt;/p&gt;

&lt;h3&gt;
  
  
  Click Count
&lt;/h3&gt;

&lt;p&gt;The code below attaches an event handler to a buttons onclick event that triggers when you’ve clicked the button 4 times.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;abstractEvents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abstract-events&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;someButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;someButton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;someButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;abstractEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You clicked the button 4 times!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Timed Click Count
&lt;/h3&gt;

&lt;p&gt;Here’s the same example but ignores clicks that happen outside a 1.5 second window. This could be used to ensure the clicks were intentional to trigger this event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;abstractEvents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;abstract-events&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;someButton&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;someButton&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;someButton&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;onclick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;abstractEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;count&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You clicked the button 4 times within 1.5 seconds!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Parsed String Events
&lt;/h2&gt;

&lt;p&gt;You can also trigger phrase events. This listens for a specific string before triggering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Specific String
&lt;/h3&gt;

&lt;p&gt;Here the event is attached to the document’s keydown event. It triggers once you’ve typed in the string “secret”, regardless of focus.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;abstractEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;phrase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;secret&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You did it!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Timed String
&lt;/h2&gt;

&lt;p&gt;Just like click example, you can limit the phrase event to a time window. In this example, the event only triggers if the string “faster” is typed within 1.5 seconds.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;keydown&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;abstractEvents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;phrase&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;phrase&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;faster&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;
&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;You did it fast!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can play around with these events on the &lt;a href="https://zachnology.github.io/abstract-events-website/"&gt;live demo page&lt;/a&gt;.&lt;br&gt;
The source code for the library is available on &lt;a href="https://github.com/zachnology/abstract-events"&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Note on Security
&lt;/h2&gt;

&lt;p&gt;Don’t use this for actual privileged access. Because these events are defined entirely in the frontend, they are not suitable for authentication. Someone could easily just look at the source of your web app and see how to bypass the security. Further, having a single global passphrase makes any system easier to hack. Deploying something like this at scale may also make your sites easily discoverable just with google dorking, which brings us back to the CIA’s implementation…&lt;/p&gt;

&lt;h2&gt;
  
  
  A “Security Through Obscurity” Failure
&lt;/h2&gt;

&lt;p&gt;The CIA’s spy website project did not end well. The sites were just a thin façade for their real purpose. And since websites are constantly up, they can be submitted to scrutiny for longer periods of time than more traditional CIA informant encounters. If you were suspicious of a website someone was viewing, you just had to look at the page source and see that the search text box was actually a password field. Research by Citizen Lab found 885 such websites just by using OSINT (Open-source Intelligence) and discovered evidence that the poor design of security features for these sites led to the compromised identity and arrest of informants worldwide.&lt;/p&gt;

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

&lt;p&gt;This article ended up serving two purposes. One was hopefully food for thought in thinking outside the box on how to use JS events for web input. The other is the importance of security for our web applications, not just using proper authentication or protecting sensitive data but also that we should protect the means of security so attackers don’t have an easy starting place.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need help with your software project?
&lt;/h2&gt;

&lt;p&gt;My day job is working as a software engineer for &lt;a href="https://trendsic.com"&gt;Trendsic&lt;/a&gt; where I help businesses large and small plan and develop secure and scalable software. Reach out to me at &lt;a href="mailto:contact@zachnology.io"&gt;contact@zachnology.io&lt;/a&gt; to discuss how I can help bring your ideas to life.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Automation: Holidays</title>
      <dc:creator>Zachnology</dc:creator>
      <pubDate>Tue, 07 May 2024 03:54:19 +0000</pubDate>
      <link>https://dev.to/zachnology/automation-holidays-504a</link>
      <guid>https://dev.to/zachnology/automation-holidays-504a</guid>
      <description>&lt;h2&gt;
  
  
  Procedurally calculated holiday dates in JS
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@towfiqu999999?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Towfiqu barbhuiya&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/a-calendar-with-red-push-buttons-pinned-to-it-bwOAixLG0uc?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Have you worked on a project that required a periodically updated list of holidays? How did you find those dates?&lt;/p&gt;

&lt;h2&gt;
  
  
  I’m seeing a pattern
&lt;/h2&gt;

&lt;p&gt;I’ve seen a lot of databases and one table that consistently pops up in corporate databases is the “holiday” table. HR will store paid company holidays in it, or marketing will use it to schedule email blasts, or it might be used to automatically populate the calendar on the company’s public website.&lt;/p&gt;

&lt;p&gt;What is interesting about this database table is that it is usually manually populated periodically…usually when something breaks and IT realizes it’s time to update the holiday list again. And that may be totally find for your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The plot thickens
&lt;/h2&gt;

&lt;p&gt;A few years ago I was working on a project that was using one such holiday table for marketing purposes. I decided to see what other solutions were out there. Googling the matter, I came across several PAID services offering a holiday API. You paid to access an api that would return dates of holidays. It seemed that even companies focused on solving this problem were just using their own manually updated holiday list and charging you to access it with the promise of keeping it up to date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is there a better way?
&lt;/h2&gt;

&lt;p&gt;Do you really need an API to provide easily consumable holiday dates? As it turns out you can procedurally determine the date of any holiday. While some holidays always fall on the same date, most holidays are determined by some algorithm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Federal Holidays
&lt;/h2&gt;

&lt;p&gt;Federal holidays in the United States are created by law, meaning there are defined procedures to determine the date of a given holiday. What’s more, there are procedures defined to determine what day a holiday should be observed should the holiday fall on a weekend (so employees can still enjoy a day off).&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Memorial Day is the last Monday of May&lt;/li&gt;
&lt;li&gt;Thanksgiving Day is the last Thursday of November&lt;/li&gt;
&lt;li&gt;Christmas Day is always the 25th of December but the federally observed day is the nearest weekday&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Religious Holidays
&lt;/h2&gt;

&lt;p&gt;Similar to federal holidays, there are rules defined by religions for when each religious holiday should be observed. Some branches of a religion might celebrate the same holiday on a different date governed by a different procedure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Holidays
&lt;/h2&gt;

&lt;p&gt;Some observed holidays are not defined by the government or religions but there at least exists some rule so everyone knows when to observe it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Easter
&lt;/h2&gt;

&lt;p&gt;Most holidays are easy enough to calculate. This one, though, might be the cause of so many just giving up and manually punching in the date for holidays each year. The good news, is we only have to write the logic to determine it once.&lt;/p&gt;

&lt;p&gt;Easter has several methods of calculation depending on where you are in the world. I’ll describe the calculation used in the United States. It’s calculated using the “Metonic Cycle” with logic determined by the Easter computus.&lt;/p&gt;

&lt;p&gt;The gist is this. There is an association between a “Golden number” and a “Paschal full moon date”. (Technically the golden number is associated with a number called Epact which determines the full moon date, but all these numbers have a 1 to 1 association so we can just jump from golden number to the full moon date.)&lt;/p&gt;

&lt;p&gt;The association is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Golden Number  Paschal Full Moon Date
1..............14 April
2...............3 April
3..............23 March
4..............11 April
5..............31 March
6..............18 April
7...............8 April
8..............28 March
9..............16 April
10..............5 April
11.............25 March
12.............13 April
13..............2 April
14.............22 March
15.............10 April
16.............30 March
17.............17 April
18..............7 April
19.............27 March
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First you need to determine the Golden number. This is done by taking the modulus of the year divided by 19, then adding 1. The calculation for 2024 is as follows:&lt;br&gt;
&lt;code&gt;2024 mod 19 + 1 = 11&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;11 is our Golden Number. We do a lookup on our computus table and see that 11 is associated with the Paschal full moon date of March 25.&lt;/p&gt;

&lt;p&gt;The rule then says that Easter should be observed the next Sunday following this date. If the Paschal full moon date lands on a Sunday, Easter will be observed the following Sunday.&lt;/p&gt;

&lt;p&gt;The closest Sunday following March 25, 2024 is March 31, 2024 so that is our date for Easter 2024. Now Google it to check if I’m right.&lt;/p&gt;

&lt;p&gt;Now we can determine the date of other holidays dependent on Easter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Mardi Gras: 47 days before Easter&lt;/li&gt;
&lt;li&gt;Ash Wednesday: 46 days before Easter&lt;/li&gt;
&lt;li&gt;Palm Sunday: 7 days before Easter&lt;/li&gt;
&lt;li&gt;Good Friday: 2 days before Easter&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Enter Holidate
&lt;/h2&gt;

&lt;p&gt;After learning all I did about holiday calculation, especially that of Easter and its related holidays, I decided to publish those algorithms for anyone to use without going through the mess of writing the logic themselves.&lt;/p&gt;

&lt;p&gt;You can install the dependency free npm package with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i holidate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or you can check out the source code on github.&lt;/p&gt;

&lt;p&gt;It has basic features allowing you to query holidays by year, locale, language, and holiday type.&lt;/p&gt;

&lt;p&gt;Most of the existing holiday logic is for US-based holidays and available in English and Spanish. If you’d like to help add holidays from other countries or from cultures or religions not currently represented in the holidate library, feel free to open a pull request and contribute to the repo.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Now go forth and automate your holiday lists!&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Apply It Elsewhere
&lt;/h2&gt;

&lt;p&gt;This article is about holiday calculation but the idea and process could apply to any date calculation regardless of being a holiday or not. The holidate library is a very basic rule engine. It relies on holidays being defined by rules. The code processes these rules to determine the date of a holiday for a given year. This same process could easily be applied to any type of recurring event.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need help with your software project?
&lt;/h2&gt;

&lt;p&gt;My day job is working as a software engineer for &lt;a href="https://trendsic.com"&gt;Trendsic&lt;/a&gt; where I help businesses large and small plan and develop software ideas using lean practices. Reach out to me at &lt;a href="mailto:contact@zachnology.io"&gt;contact@zachnology.io&lt;/a&gt; to discuss how I can help bring your ideas to life.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>automation</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>The Infrastructure Iceberg</title>
      <dc:creator>Zachnology</dc:creator>
      <pubDate>Tue, 07 May 2024 03:42:53 +0000</pubDate>
      <link>https://dev.to/zachnology/the-infrastructure-iceberg-ede</link>
      <guid>https://dev.to/zachnology/the-infrastructure-iceberg-ede</guid>
      <description>&lt;h2&gt;
  
  
  I just need a simple app on the app store, that's all...
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Cover photo by &lt;a href="https://unsplash.com/@mlenny?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Alexander Hafemann&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/photo-of-iceberg-M-EwSRl8BK8?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let’s say you are seeking a consultant to build a software product for you. You might be inclined to hire your friend’s buddy who builds apps on the side since he can do it cheap or at a low hourly rate. All you need is the dev to build the app and then it’s self sufficient, right? I mean the app store hosts the thing after all!&lt;/p&gt;

&lt;p&gt;SaaS products are like an iceberg. The end user sees a pretty mobile app icon or a nice web site but rarely is all the functionality self-contained. Often there are many layers of technology behind the scenes that support that app, not to mention infrastructure and security maintenance. When factoring in the viability and cost of implementing an idea, you should consider all it takes to support an app and what maintenance for it looks like.&lt;/p&gt;

&lt;p&gt;To help explain different infrastructure components, I’ll use the example of a mobile app that helps you manage your pantry. You can create an account, store the contents of your pantry, get recipe recommendations based on what you have in stock, purchase food to replace what’s out of stock, and receive alerts when certain items are on sale. What does it take to support such an app?&lt;/p&gt;

&lt;h2&gt;
  
  
  App Store Developer Account
&lt;/h2&gt;

&lt;p&gt;In order to publish an app to the Apple App Store or the Google Play Store, you will need a developer account on the corresponding store’s platform. Although the name includes “developer” you can think of these accounts as vendor accounts that allow you to publish mobile applications under your company’s name. You can give your developer team limited access to your account via specific permissions to manage the app they are developing for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication Provider
&lt;/h2&gt;

&lt;p&gt;Because our example app allows users to create user accounts and store information tied to their user account, you will need a tool that manages user accounts and provides authentication functionality. While this can be a home-grown solution, it’s usually more secure and more cost effective to use a third party provider. Such third party providers include Auth0, AWS Cognito, and Microsoft Entra ID.&lt;/p&gt;

&lt;h2&gt;
  
  
  Email Service
&lt;/h2&gt;

&lt;p&gt;When there are user accounts, there are emails. At the very least, you’ll need to email users as part of setting up an account or for password recovery. You may also choose to send marketing emails related to your app or to send notification alerts. Regardless of the reason, you’ll need a way to send automated emails. In order to do so you’ll either need your own SMTP server or use a third party email service to handle the sending. Some examples of third party email services are SendGrid and Mailchimp.&lt;/p&gt;

&lt;h2&gt;
  
  
  Data Store
&lt;/h2&gt;

&lt;p&gt;Because the app allows users to recall the items in their pantry, you’ll need a place to store that information across login sessions and devices. Some form of database or datastore will be needed. These can be a managed database service you pay for through a cloud provider like Amazon Web Services, Google Cloud, Microsoft Azure or it can be a database server installed on a bare-metal our cloud server you manage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Payment Processing
&lt;/h2&gt;

&lt;p&gt;Since the app allows users to purchase items through the in-app store, you’ll need a way to process payments for those orders. This means a 3rd party integration with a payment gateway. These include Stripe or Paypal, or payment gateway aggregators like Chargebee or even Shopify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Servers
&lt;/h2&gt;

&lt;p&gt;For your app to communicate with all of the above services and provide business logic for your app, you’ll need some form of a backend API or web service. This a service running on a server somewhere that communicates with your app to interact with the database, validate users, send emails and facilitate payment processing. Depending on the architecture of the backend, processing power required, bandwidth, and availability zone requirements, this could be multiple servers across multiple time zones and countries.&lt;/p&gt;

&lt;p&gt;Since our example app sends alerts to users, we’ll need to a service to send push notifications to them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Presence
&lt;/h2&gt;

&lt;p&gt;You may also want your app’s functionality to be available on the web. This involves developing a web application viewable on desktop and mobile that provides the same functionality and will also need hosting. Even if your app is mobile-download-only, you may still want a landing page website for those using search engines to find your app. There are many hosting providers for web. For a simple landing page, pretty much any static site host will do. For a web application you may need a more custom hosting configuration and infrastructure depending on the technology used.&lt;/p&gt;

&lt;h2&gt;
  
  
  UI/UX
&lt;/h2&gt;

&lt;p&gt;You’ll want to collaborate with a UX designer to create the look and feel for your app and also how the users interact with it in an intuitive way. If you have a landing page or web version of your app, you’ll want to have those designed with a matching look and feel. If you are sending emails, you will want the email design to match the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ads
&lt;/h2&gt;

&lt;p&gt;In our example app, users are sent alerts for sales they may be interested in. This may include advertisements from third parties. We’ll need to either coordinate with an ad service or collaborate with specific vendors to serve up their ads in our app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile Platforms
&lt;/h2&gt;

&lt;p&gt;While mobile apps on both Android and iOS may look the same, the technology and process used to build them natively are drastically different. Some apps can be created using a cross-platform framework that allows code to be written once and compiled for each mobile platform (more or less). Some apps because of performance, sensor accessibility, or other reasons may need to be developed independently for each platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;Because your app stores information about its users and payment information, you must do your due diligence in securing that data. That includes securing the database and network used by the platform. It also includes using proper encryption for appropriate data, applying security patches as they become available, and responding to security threats to keep your platform secure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ongoing Support
&lt;/h2&gt;

&lt;p&gt;So far we’ve discussed several components that may be part of a software product but are not known to the end consumer. One of the difficulties for small businesses and solo entrepreneurs is the management of all of these components to support their product. While your friend’s buddy may be able to set up some of these components, who is going to manage them while you run your business or as your business scales up? As you move from proof-of-concept to serving real customers, you’ll want to partner with a company that can provide that maintenance and ongoing support.&lt;/p&gt;

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

&lt;p&gt;There is a lot more to running and maintaining successful software platforms that meets they eye. Hopefully this information can help you get a better idea of cost of investment and give you real talking points to discuss when shopping around your project.&lt;/p&gt;

&lt;h2&gt;
  
  
  Need help with your software product?
&lt;/h2&gt;

&lt;p&gt;My day job is working as a software engineer for &lt;a href="https://trendsic.com"&gt;Trendsic&lt;/a&gt; where I help businesses large and small architect scalable and sustainable software platforms. Reach out to me at &lt;a href="mailto:contact@zachnology.io"&gt;contact@zachnology.io&lt;/a&gt; to discuss how I can help you with your next project.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Idea Validation for the New Tech Entrepreneur</title>
      <dc:creator>Zachnology</dc:creator>
      <pubDate>Mon, 06 May 2024 18:31:23 +0000</pubDate>
      <link>https://dev.to/zachnology/idea-validation-for-the-new-tech-entrepreneur-5204</link>
      <guid>https://dev.to/zachnology/idea-validation-for-the-new-tech-entrepreneur-5204</guid>
      <description>&lt;h2&gt;
  
  
  So you've got an idea for an app...
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Cover Photo by &lt;a href="https://unsplash.com/@rishabhdharmani?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Rishabh Dharmani&lt;/a&gt; on &lt;a href="https://unsplash.com/photos/grayscale-photo-of-person-holding-lighted-candle-vU8kM8B_Giw?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Not long ago, I found a post in a tech-focused entrepreneurship forum that went something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My business partner and I have been working on an engineering software tool since we were in grad school. After 10 years of work, it is now full-featured and ready for the market. However, we are having trouble selling it. We have had lots of meetings but no one is signing contracts. Does anyone have advice?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The comments all reflected deep sadness that this team of developer-entrepreneurs had wasted so much time and money only to find out that no one wanted the product they had made. Ten years is a long time but their strategy is actually a fairly common one, especially for technical entrepreneurs.&lt;/p&gt;

&lt;p&gt;As developers and engineers, we are hypersensitive to inefficiencies and sometimes to a fault. Instead of asking ourselves “is someone willing to pay for this?”, we just get started building our ideas right away with the hope that if our product has enough fancy features someone will buy it and surely the price they pay and the volume of sales will compensate use appropriately for all of our hard work.&lt;/p&gt;

&lt;p&gt;This article aims to help address this behavior of putting the cart before the horse by encouraging the validation of ideas before their implementation and encouraging experimentation as a means of validating ideas. This means putting your idea to the test to see if it is actually a viable product that can make real money.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;The goal of idea validation is to prove that someone is willing to pay for your product and that there is a big enough audience of such people to make a profit.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What Constitutes a Validated Idea?
&lt;/h2&gt;

&lt;p&gt;It is important to be honest with yourself and to disregard false-positives. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Someone only telling you that your idea sounds great is not validation.&lt;/li&gt;
&lt;li&gt;Your mother wanting to invest is also not validation.&lt;/li&gt;
&lt;li&gt;Even someone using and liking a free prototype is not validation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal of idea validation is to prove that someone is willing to pay for your product and that there is a big enough audience of such people to make a profit.&lt;/p&gt;

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

&lt;p&gt;I’m not a marketing expert. My expertise is in implementing dreamed-up software ideas and that is the point of view from which this article is written. I understand that creative marketing and clever business strategy can overcome some of the obstacles mentioned here but I feel the advice here is still relevant for the majority of startups and entrepreneurs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Self Assessment
&lt;/h2&gt;

&lt;p&gt;Here are some questions that it would be good to answer about your product before significant investment. I ask these types of questions to clients in our first meeting.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. What Problem does my idea solve?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1a. Am I trying to solve a real pain point or is it just a mild inconvenience?
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Real Pain Point:
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;My child’s school bus arrives at inconsistent times. This worries me because I don’t know if my child is missing or if the bus is just late. I wish there were a notification system to alert me to the status of the bus to give me piece of mind.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  Just a mild inconvenience:
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;All my favorite apps have dark mode except MS Word. I want to create a word processer that has native dark mode.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  2. How unique is my idea?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  2a. Is there already a product on the market that solves the same problem?
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;I want a website where people can go to talk about motorcycles. I want to be able to create a post about motorcycles and people can comment on it and communicate with each other.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why should customers use your platform instead of just making a Facebook group for motorcyclists or joining one of the many such Facebook groups already out there. If you intend to compete with the social media giants you’ll need to cater to the motorcycle community in a way they do not or cannot.&lt;/p&gt;

&lt;h4&gt;
  
  
  2b. What differentiates my product from others and incentivizes potential customers to choose my solution over what already exists?
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Little Differentiation:
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;My idea is a calculator app that lets you change the background color.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  More Differentiation:
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;My idea is a calculator app that has shortcuts for common equations used by surveyors doing field work. Instead of fiddling around with a regular calculator and punching in lots of numbers, they can quickly and easily get the data they need and get back to work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  2c. Could a competitor easily make an update to their existing product to solve the same problem?
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;MS Word doesn’t have dark mode so everyone that likes dark mode will want to use my word processor.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What happens if Microsoft decides to add dark mode tomorrow? Does that invalidate my entire business?&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Who is my target audience?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  3a. Is it a small, large, niche or broad audience?
&lt;/h4&gt;

&lt;h5&gt;
  
  
  Too Small an Audience:
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;My idea is an app for people with gen 1 android phones that allows them to blah blah blah.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  Too Broad an Audience:
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;I want to make an app that does everything for everyone and we’ll market it to all humans.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  Well Defined Niche:
&lt;/h5&gt;

&lt;blockquote&gt;
&lt;p&gt;My idea is a web app that focuses on helping the desert landscaping industry source climate compatible plants and products.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  3b. Is the audience accustomed to paying for such products?
&lt;/h4&gt;

&lt;p&gt;Studies have shown that iOS users spend more on apps and on in-app purchases than their Android counterparts. How do I account for this with my idea?&lt;/p&gt;

&lt;h4&gt;
  
  
  3c. Would this audience pay the price I want/need to charge?
&lt;/h4&gt;

&lt;p&gt;My idea may provide a “better” experience than its competitors. Does this add to infrastructure or licensing costs that will put my product’s price out of range of what customers are willing to pay?&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Does my idea solve a problem for a particular industry?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  4a. Are there regulatory factors to consider for a product in this space?
&lt;/h4&gt;

&lt;p&gt;There may be regulatory or legal factors based on the industry that could increase cost of development, legal matters, or require that I hire a security or compliance officer. I need to be aware of these cost to plan accordingly.&lt;/p&gt;

&lt;h4&gt;
  
  
  4b. What is the community like in this industry?
&lt;/h4&gt;

&lt;p&gt;The community in this industry may be averse to change or use of certain technology. An industry that relies on precision of information and data may not welcome tools that use AI. Does my product threaten the jobs of members of this community? How does that affect my ability to market to this community?&lt;/p&gt;

&lt;h4&gt;
  
  
  4c. How do other successful companies market to the industry?
&lt;/h4&gt;

&lt;p&gt;Can I take advantage of the findings of other companies to know how best to reach this community?&lt;/p&gt;

&lt;h3&gt;
  
  
  5. What are the legal considerations to implementing and selling my idea?
&lt;/h3&gt;

&lt;h4&gt;
  
  
  5a. In which locales can this product be sold and used?
&lt;/h4&gt;

&lt;p&gt;Can I sell this product in all 50 states? Does California require additional legal considerations? Can I sell this product in other countries?&lt;/p&gt;

&lt;h4&gt;
  
  
  5b. Will I need to collect or store data that is sensitive in nature?
&lt;/h4&gt;

&lt;p&gt;Depending on the industry my product serves, I could be legally compelled to comply with certain laws or standards to protect the data I store on behalf of users. For example if my product serves the medical industry, it will probably need to be HIPAA compliant. I will need to factor that into my budget for development, infrastructure, and maintenance.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. On what types of devices will my product run? Am I targeting mobile, web, desktop, other?
&lt;/h3&gt;

&lt;p&gt;Where do my customers expect to interact with products like mine? Will they be in an office where it will be more convenient to use on the desktop with a keyboard and a large monitor? Is lots of typing required? Do I need to design the user experience to require minimal typing because users will be on mobile devices?&lt;/p&gt;

&lt;h3&gt;
  
  
  And more…
&lt;/h3&gt;

&lt;p&gt;I don’t mean to give an exhaustive list of self-assessment questions but rather an idea of the types of questions you should be thinking about. You want to identify potential problems that could hurt or inhibit viability. You may need to revisit some of these questions as you iterate upon your idea.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Lean on the wins and learn from the failures.&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  A Scientific Approach
&lt;/h2&gt;

&lt;p&gt;What if you learn that part of my idea is not viable? That’s ok! Not only is it expected, it should be considered a win. You learned this valuable information now instead spending thousands of dollars and months of time working on something that would no one would buy. A core tenant of lean methodology is to fail fast. Find out what won’t work quickly so you know to go in another direction before wasting resources. Now you can pivot and adjust your plan to compensate. Lean on the wins and learn from the failures.&lt;/p&gt;

&lt;p&gt;By completing an initial assessment of your idea, you’ve completed an experiment. You had an idea, put it through tests, and hopefully you have learned something. At this point you should have identified items that need to be changed to your product to make it more viable. This process of experimentation can be repeated throughout the life of your product, from idea to prototype to MVP to initial release to feature updates. The concept is to make informed decisions about the direction of your product based on real evidence.&lt;/p&gt;

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

&lt;p&gt;What could our friends from the forum post have done differently and what could have been the outcome? Were they wrong to be passionate about an idea? No. What they lacked was proof that their product filled a real need. Now imagine what they could have accomplished in those 10 years if they had tested the viability of their product first, experimented and failed early, and iterated on their idea making changes based on real evidence.&lt;/p&gt;

&lt;h2&gt;
  
  
  Up Next…
&lt;/h2&gt;

&lt;p&gt;Stay tuned for the next article, “The Infrastructure Iceberg” where we will build a hypothetical app and learn about the costs of supporting a fully-loaded SaaS product&lt;/p&gt;

&lt;h2&gt;
  
  
  Need help with your software product?
&lt;/h2&gt;

&lt;p&gt;My day job is working as a software engineer for Trendsic where I help businesses large and small plan and develop software ideas using lean practices. Reach out to me at &lt;a href="mailto:contact@zachnology.io"&gt;contact@zachnology.io&lt;/a&gt; to discuss how I can help bring your ideas to life.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>beginners</category>
      <category>productivity</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
