<?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: #./TECHLAB.MA</title>
    <description>The latest articles on DEV Community by #./TECHLAB.MA (@techlabma).</description>
    <link>https://dev.to/techlabma</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%2Forganization%2Fprofile_image%2F9353%2F950ad38f-54b8-4501-9063-f12f5cb027bf.jpeg</url>
      <title>DEV Community: #./TECHLAB.MA</title>
      <link>https://dev.to/techlabma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/techlabma"/>
    <language>en</language>
    <item>
      <title>Design Patterns: Facade</title>
      <dc:creator>Youssef El Idrissi</dc:creator>
      <pubDate>Wed, 25 Feb 2026 01:45:00 +0000</pubDate>
      <link>https://dev.to/techlabma/design-patterns-facade-23d3</link>
      <guid>https://dev.to/techlabma/design-patterns-facade-23d3</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This Blog post is part of a collaborative work between &lt;strong&gt;Me&lt;/strong&gt; and &lt;strong&gt;Mustapha El Idrissi&lt;/strong&gt;, Consult his devTo page for more information: &lt;a href="https://dev.to/appsbymuss"&gt;https://dev.to/appsbymuss&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;h2&gt;
  
  
  What is the Facade Pattern
&lt;/h2&gt;

&lt;p&gt;This &lt;strong&gt;Structural Pattern&lt;/strong&gt; provides a simplified interface to a complex subsystem, making it easier to use by encapsulating the intricacies of the system behind a single, unified interface.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's its purpose ?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The Facade Pattern helps in reducing the complexity of interactions with a complex system by providing a higher-level interface that abstracts away the underlying details.&lt;/li&gt;
&lt;li&gt;It’s useful when you want to simplify communication with a subsystem, allowing clients to interact with the system in a more straightforward way without needing to understand its complexity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Key Concepts
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Facade Class:&lt;/strong&gt; The main class that provides a simplified interface to the client. It delegates client requests to the appropriate components within the subsystem.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Subsystem Classes:&lt;/strong&gt; The classes that represent the complex functionality of the system. These classes contain the actual implementation details and logic but are hidden from the client.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example: Home Automation System
&lt;/h2&gt;

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

&lt;ul&gt;
&lt;li&gt;these are &lt;strong&gt;Subsystem Classes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LightSystem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TurnOnLights&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lights are on."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TurnOffLights&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Lights are off."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MusicSystem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;PlayMusic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Playing music."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;StopMusic&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Music stopped."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SecuritySystem&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ArmSystem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Security system armed."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;DisarmSystem&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Security system disarmed."&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;ul&gt;
&lt;li&gt;This is the &lt;strong&gt;Facade Class&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeAutomationFacade&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;LightSystem&lt;/span&gt; &lt;span class="n"&gt;_lights&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;MusicSystem&lt;/span&gt; &lt;span class="n"&gt;_music&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;SecuritySystem&lt;/span&gt; &lt;span class="n"&gt;_security&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;HomeAutomationFacade&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_lights&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;LightSystem&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_music&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MusicSystem&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_security&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SecuritySystem&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;LeaveHome&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_lights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TurnOffLights&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_music&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;StopMusic&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ArmSystem&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Home is in 'leave' mode."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;EnterHome&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_security&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;DisarmSystem&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_lights&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TurnOnLights&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;_music&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PlayMusic&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Home is in 'enter' mode."&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;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ai5lmdshzioihi0tble.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ai5lmdshzioihi0tble.png" alt=" " width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;And this is the Test (aka Consumer class)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;TestFacade&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;HomeAutomationFacade&lt;/span&gt; &lt;span class="n"&gt;homeSystem&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;HomeAutomationFacade&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;homeSystem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;EnterHome&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;homeSystem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LeaveHome&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;
  
  
  The Good, The Bad and the Ugly
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Advantages
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Simplifies the interface for interacting with complex subsystems, making it easier for clients to use.&lt;/li&gt;
&lt;li&gt;Reduces dependencies between clients and subsystems, promoting loose coupling.&lt;/li&gt;
&lt;li&gt;Encapsulates subsystem complexity, allowing for easier maintenance and understanding.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Disadvantages
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The facade can become a "God Object" if it tries to handle too many responsibilities.&lt;/li&gt;
&lt;li&gt;May hide system complexities that might be needed for advanced usage.&lt;/li&gt;
&lt;li&gt;Over-simplifying can lead to limitations in functionality for clients needing deeper access.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  When to not use
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;When a subsystem is simple enough that no facade is needed.&lt;/li&gt;
&lt;li&gt;If clients require direct access to the components of a subsystem for customization or extension.&lt;/li&gt;
&lt;li&gt;In cases where the added layer of abstraction complicates the system rather than simplifying it.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>softwareengineering</category>
      <category>designpatterns</category>
      <category>programming</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Design Patterns: Introduction</title>
      <dc:creator>Youssef El Idrissi</dc:creator>
      <pubDate>Wed, 25 Feb 2026 01:34:22 +0000</pubDate>
      <link>https://dev.to/techlabma/design-patterns-introduction-377g</link>
      <guid>https://dev.to/techlabma/design-patterns-introduction-377g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This Blog post is part of a collaborative work between &lt;strong&gt;Me&lt;/strong&gt; and &lt;strong&gt;Mustapha El Idrissi&lt;/strong&gt;, Consult his devTo page for more information: &lt;a href="https://dev.to/appsbymuss"&gt;https://dev.to/appsbymuss&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Design patterns are proven, reusable solutions to common problems that occur during software design and development. They are like templates that can be adapted to address specific challenges within various contexts. Design patterns are not code themselves but rather descriptions of how to solve problems in a way that maximizes efficiency, scalability, and maintainability.&lt;/p&gt;

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

&lt;p&gt;There is in general 3 types of design patterns:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Creational Design Patterns (such as: Singleton Pattern, Simple Factory Pattern)&lt;/li&gt;
&lt;li&gt;Structural Design Patterns (such as: Decorator Pattern, Facade Pattern, Adapter Pattern, Proxy Pattern)&lt;/li&gt;
&lt;li&gt;Behavioral Design Patterns (such as: Strategy Pattern, Observer Pattern)&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>softwareengineering</category>
      <category>csharp</category>
      <category>programming</category>
    </item>
    <item>
      <title>Floating-Point Numbers</title>
      <dc:creator>appsbymuss</dc:creator>
      <pubDate>Tue, 24 Feb 2026 18:58:43 +0000</pubDate>
      <link>https://dev.to/techlabma/floating-point-numbers-1igo</link>
      <guid>https://dev.to/techlabma/floating-point-numbers-1igo</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This Blog post is part of a collaborative work between &lt;strong&gt;Me&lt;/strong&gt; and &lt;strong&gt;Youssef El Idrissi&lt;/strong&gt;, Consult his devTo page for more information: &lt;a href="https://dev.to/0xw3ston"&gt;https://dev.to/0xw3ston&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  The Backstory...
&lt;/h1&gt;

&lt;p&gt;Long ago Computer Engineers found themselves in a tricky pickle, they had no way to work with Numbers that are &lt;strong&gt;not "full-Integers"&lt;/strong&gt; (aka Numbers that have &lt;em&gt;fractions&lt;/em&gt; in them).&lt;/p&gt;

&lt;p&gt;They came up with something called &lt;strong&gt;"Fixed-Point Numbers"&lt;/strong&gt;:&lt;/p&gt;

&lt;h1&gt;
  
  
  Fixed-Point Numbers
&lt;/h1&gt;

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

&lt;ul&gt;
&lt;li&gt;The DOT in pink is called a &lt;strong&gt;radix point&lt;/strong&gt;, it's what separates the integer value from the decimal value.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Fixed-Point is about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;giving the integer side &lt;strong&gt;X bits&lt;/strong&gt; in order to represent it in binary&lt;/li&gt;
&lt;li&gt;giving the fraction side &lt;strong&gt;Y bits&lt;/strong&gt; in order to represent it in binary&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here are a few examples&lt;br&gt;
(&lt;strong&gt;In our examples we assign 4-bits for the fraction part, 4-bits for the integer part&lt;/strong&gt;)&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Examples &lt;strong&gt;1&lt;/strong&gt; and &lt;strong&gt;2&lt;/strong&gt; are normal since the 8 bits cover the value(s)&lt;/li&gt;
&lt;li&gt;however, in Examples &lt;strong&gt;3&lt;/strong&gt; and &lt;strong&gt;4&lt;/strong&gt; you can clearly see some issues arise when it comes on how to account for negative numbers and for accuracy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this reason there was another standard defined, &lt;strong&gt;"Floating-Point Numbers"&lt;/strong&gt;:&lt;/p&gt;

&lt;h1&gt;
  
  
  Floating-Point Numbers
&lt;/h1&gt;

&lt;p&gt;What makes Floating-Point Numbers so elegant is the direct inspiration they have drawn from Scientific notation writing. it is a formal standard (IEEE 754)&lt;/p&gt;

&lt;p&gt;In High School, it was taught to short-write either super big or super miniscule numbers like so.&lt;/p&gt;

&lt;p&gt;135600000 = 1,356 * 10^8&lt;br&gt;
and&lt;br&gt;
0,00005997758 = 5,997758 * 10^-5&lt;/p&gt;

&lt;p&gt;with a paper and pen (it's generally) okay to write numbers both ways (as they are, or in scientific notation)&lt;br&gt;
But with computers how data is stored  is very critical and requires bit-level accuracy to not get the wrong results.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single-Precision Floating Point
&lt;/h2&gt;

&lt;p&gt;32-bit representation&lt;/p&gt;

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

&lt;p&gt;There's multiple variations of &lt;strong&gt;Floating-Point Numbers&lt;/strong&gt;, one of them is a the &lt;strong&gt;32-bit&lt;/strong&gt; representation.&lt;/p&gt;

&lt;p&gt;Usually in all of the &lt;strong&gt;Floating-Point&lt;/strong&gt; variations we find three main components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Mantissa&lt;/strong&gt;: This part represents the part of our number that cannot be further encoded&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Exponent&lt;/strong&gt;: That part represents the exponent by which we multiply the Mantissa to get the original number back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sign&lt;/strong&gt;: this is a one bit flag that tells us if the number is negative or positive.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Encoding
&lt;/h3&gt;

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

&lt;p&gt;To encode a number from &lt;code&gt;base-10&lt;/code&gt; to &lt;code&gt;base-2&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We take the &lt;strong&gt;integer side&lt;/strong&gt; and turn it into binary&lt;/li&gt;
&lt;li&gt;We take the &lt;strong&gt;fraction/decimal side&lt;/strong&gt; and turn it into binary&lt;/li&gt;
&lt;li&gt;We then slide the &lt;strong&gt;radix point&lt;/strong&gt; until we get a &lt;strong&gt;&lt;code&gt;1&lt;/code&gt;&lt;/strong&gt; on the left side&lt;/li&gt;
&lt;li&gt;And lastly we apply the &lt;strong&gt;"Bias"&lt;/strong&gt; which we will explain later.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Encoding&lt;/strong&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Integer to Binary Conversion
&lt;/h5&gt;

&lt;p&gt;We do the following Calculation to turn the integer into binary&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Value (Integer)&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;bit&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;124 mod 2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;62 mod 2&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;31 mod 2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15 mod 2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7 mod 2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3 mod 2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1 mod 2&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;1111100&lt;/code&gt;&lt;/p&gt;

&lt;h5&gt;
  
  
  Fraction/Decimal to Binary Conversion
&lt;/h5&gt;

&lt;p&gt;We do the following Calculation to turn the decimal into binary&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Value (Fraction)&lt;/th&gt;
&lt;th&gt;bit&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.25568 . 2 = 0.51136&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.51136 . 2 = 1.02272&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.02272 . 2 = 0.04544&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.04544 . 2 = 0.09088&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.0988 . 2 = 0.18176&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.18176 . 2 = 0.36352&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.3652 . 2 = 0.72704&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.72704 . 2 = 1.45408&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.45408 . 2 = 0.90816&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.90816 . 2 = 1.81632&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.81632 . 2 = 1.63264&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.63264 . 2 = 1.26528&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.26528 . 2 = 0.53056&lt;/td&gt;
&lt;td&gt;0&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.53056 . 2 = 1.06112&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;td&gt;...&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;.01000001011101...&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So once we are done we are left with &lt;code&gt;1111100.01000001011101&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We have to normalize that to get the scientific notation for this number, we would slide the radix point to the left (or the right, depending on where the left upmost "1" exists) until there is exactly one single "1" on the left side of the radix point, like so&lt;br&gt;
&lt;code&gt;1111100.01000001011101100&lt;/code&gt;  = &lt;code&gt;1.11110001000001011101100 x 2^6&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then comes the &lt;strong&gt;Adding Bias&lt;/strong&gt; step, first what's a Bias ?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bias&lt;/strong&gt;: Bias is a fixed value added to the real exponent so the exponent can be stored as an &lt;strong&gt;unsigned integer&lt;/strong&gt;. Instead of storing negative exponents directly, we store: &lt;code&gt;Stored Exponent = Real exponent + Bias&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;for example &lt;strong&gt;Single-precision Floating-point&lt;/strong&gt; uses a bias of &lt;code&gt;127&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So in this case The bias is &lt;code&gt;6 + 127&lt;/code&gt; which is &lt;code&gt;133&lt;/code&gt; and in binary &lt;code&gt;133 = 10000101&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So we're left with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sign: 0 (positive number)&lt;/li&gt;
&lt;li&gt;Exponent: 10000101&lt;/li&gt;
&lt;li&gt;Mantissa: 111100....&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In normalized IEEE 754 numbers, the leading 1 (highlighted in red in the diagram below) before the radix point is &lt;strong&gt;implicit&lt;/strong&gt; and therefore not stored. This is known as the &lt;strong&gt;hidden bit&lt;/strong&gt; optimization.&lt;/p&gt;

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

&lt;h3&gt;
  
  
  Decoding
&lt;/h3&gt;

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

&lt;p&gt;Decoding is fairly simple&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extract the &lt;strong&gt;Exponent&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Remove the &lt;strong&gt;Bias&lt;/strong&gt; from the exponent to get the real exponent (which is &lt;code&gt;6&lt;/code&gt; in this case)&lt;/li&gt;
&lt;li&gt;Extract the &lt;strong&gt;Mantissa&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Reconstruct the equation &lt;strong&gt;mantissa x 2^exponent&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;which later on gives us&lt;/p&gt;

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

&lt;p&gt;This way we managed to Decode the Floating Point.&lt;/p&gt;

&lt;h2&gt;
  
  
  Other Precision
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Half-Precision Floating-Point
&lt;/h4&gt;

&lt;p&gt;Used mostly in AI and Graphics&lt;/p&gt;

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

&lt;h4&gt;
  
  
  Double-Precision Floating-Point
&lt;/h4&gt;

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

&lt;p&gt;Mostly used in Scientific Computer such as Physics Simulations, Engineering calculations &amp;amp; Numerical methods.&lt;/p&gt;

&lt;h4&gt;
  
  
  Quad-Precision Floating-Point
&lt;/h4&gt;

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

&lt;p&gt;Used in High-Precision scientific simulations &amp;amp; Financial systems where the error rate should be minimized aggressively, it is present in Astrophysics, Climate modeling, Computational number theory etc..&lt;/p&gt;

&lt;h4&gt;
  
  
  Octuple-Precision Floating-Point
&lt;/h4&gt;

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

&lt;p&gt;Used in Cryptography research, symbolic mathematics, experimental physics and extremely sensitive numerical algorithms&lt;/p&gt;

</description>
      <category>learning</category>
      <category>computerscience</category>
      <category>softwareengineering</category>
      <category>science</category>
    </item>
    <item>
      <title>Push Notifications: How Your App Speaks When It’s Sleeping</title>
      <dc:creator>Youssef El Idrissi</dc:creator>
      <pubDate>Sun, 18 May 2025 06:48:11 +0000</pubDate>
      <link>https://dev.to/techlabma/push-notifications-4lma</link>
      <guid>https://dev.to/techlabma/push-notifications-4lma</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This Blog post is part of a collaborative work between &lt;strong&gt;Me&lt;/strong&gt; and &lt;strong&gt;Mustapha El Idrissi&lt;/strong&gt;, Consult his devTo page for more information: &lt;a href="https://dev.to/appsbymuss"&gt;https://dev.to/appsbymuss&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What are Push Notifications ?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Push notifications&lt;/strong&gt; are messages sent from an app or website to a user's device, even when the app or site isn’t actively open. They appear as pop-up alerts, banners, or notification icons on devices like smartphones, tablets, and computers.&lt;/p&gt;

&lt;p&gt;The mechanism with which these "Push Notifications" work is usually the use of some sort of background processes, these processes maintain a persistent connection with the designated "Push Server" depending on their device (in the case of Native Push) or their navigator (in the case of Web Push).&lt;/p&gt;

&lt;p&gt;There's two types of Push Notifications:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Native Push: This one usually is linked directly to the Operating System of the Device where Push notifications were activated, for example, Windows, MacOS, Android or IOS.&lt;/li&gt;
&lt;li&gt;Web Push: This one is linked to specific navigators instead of the OS directly, Firefox, Chrome (or any Chromium based navigator like Opera...), Firefox etc...&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is a difference between both the execution and implementation of these two types.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Push
&lt;/h2&gt;

&lt;p&gt;Web Push is a Protocol/technology that allows &lt;strong&gt;websites to send push notifications to users’ devices&lt;/strong&gt; (desktop, mobile) &lt;strong&gt;even when the browser is closed&lt;/strong&gt;. It’s part of the &lt;strong&gt;Push API&lt;/strong&gt; and &lt;strong&gt;Notifications API&lt;/strong&gt; standards, because it's not tightly coupled with the OS, sometimes it could not work as proficiently.&lt;br&gt;
On some mobile OSes, browsers may be restricted from running background processes aggressively to save battery, causing delays or missed notifications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Native Push
&lt;/h2&gt;

&lt;p&gt;The Native one works the greatest because Push Notifications are considered Top Priority by the OS, meaning that as long as the user has actual internet connection, they will 100% receive that Push notification, unless they go out of their way to tamper with the settings concerning those notifications or maybe they simply deactivate them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrappers
&lt;/h2&gt;

&lt;p&gt;They’re &lt;strong&gt;libraries or services&lt;/strong&gt; that &lt;strong&gt;abstract the differences between native push services&lt;/strong&gt; (like Apple Push Notification Service for iOS, Firebase Cloud Messaging for Android, Windows Notification Service, and Web Push for browsers) so you can send notifications without writing separate code for each platform. The issue with these "wrappers" is summarized in two things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Due to the abstractions offered by third-party wrappers, a new problem could arise, instead of fully operating your system/mechanism, you rely on a third party service.&lt;/li&gt;
&lt;li&gt;These "wrapper" services usually either cost money or are "fremiums" (meaning they are free for a certain amount of traffic/messages, after that it becomes paid once it passes a certain threshold)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Push Server
&lt;/h2&gt;

&lt;p&gt;One of the most important components when it comes to push notifications is the "Push Server". The way it works is that we subscribe a device for a specific app/notification etc., which generates a very Unique URL, the vendor-specific server registers that this specific device "subscribed" to listen for push notifications coming on that navigator/device, the Unique URL generated gets stored in the backend so that we send a request to it, which in turns gets the actual vendor-specific server to push those notifications to those devices, So in very simple words, it's just a middleman, we don't get the right to directly push notifications from the backend to the device.&lt;/p&gt;

&lt;p&gt;Push Notifications usually operate with a &lt;strong&gt;Pub/Sub Architecture&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Subscribers&lt;/strong&gt;: are the devices that want to receive notifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Broker&lt;/strong&gt;: being the Push Server that mediates between the Broadcaster (Backend) and the actual subscribed clients.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publisher(s)&lt;/strong&gt;: the backend that wants to broadcast events/messages (new discounts etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9u58fvvcwc9pbo73hn8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu9u58fvvcwc9pbo73hn8.png" alt="pub/sub architecture in a Push Notification System" width="800" height="571"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are Push Servers that handle notifications for each OS/Browser:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38ecqwf1w9w9itfqtp8q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38ecqwf1w9w9itfqtp8q.png" alt="Push Notifications: Native vs Web vs Wrappers" width="800" height="307"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Diagram above demonstrates the common &lt;strong&gt;Native Push Servers&lt;/strong&gt; for each platform/browser (on the left), and it also shows how wrappers could be used to hide all that technical implementation behind abstractions that end up offering the developers very simplified API endpoints/library methods to use (on the far right)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Advantages of Push Notifications:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;One of the main advantages is the ability to distribute specific messages/notifications to devices/browsers that aren’t currently open or in use.&lt;/li&gt;
&lt;li&gt;If there are multiple Websites/apps that use the same vendor-specific server to push their notifications to devices, then a singular connection gets persisted with multiple "Publishers" but with the same "Broker" which minimizes back-and-forth Network communication, for this reason &lt;strong&gt;Multiplexing&lt;/strong&gt; is used to minimize battery drain, especially on phones. &lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  Example(s) of Use Cases:
&lt;/h2&gt;

&lt;p&gt;1) An admin needs to be notified immediately when a new order is placed, even if the browser or device is idle or closed. Push notifications ensure that the admin receives timely updates regardless of the app’s active state.&lt;br&gt;
2) A user needs to know when a new message is received. While real-time communication methods like WebSockets, Polling, or Server-Sent Events (SSE) work when the app is open, they fail when the window is minimized or fully closed. In such cases, push notifications become the most reliable strategy.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up: WebPush
&lt;/h1&gt;

&lt;p&gt;To setup WebPush on your web server, we're going to use a minimal wrapper library called "web-push" (it exists in NodeJS, Python and PHP and there are other implementations aswell).&lt;/p&gt;

&lt;p&gt;There are 2 major sections:&lt;/p&gt;

&lt;h2&gt;
  
  
  1 - Backend
&lt;/h2&gt;

&lt;p&gt;Now each website/API is identified with a pair of &lt;strong&gt;VAPID&lt;/strong&gt; keys (&lt;strong&gt;Voluntary Application Server Identification&lt;/strong&gt;), In order for our Web server to send push notifications, VAPID keys are used to authenticate the web server to the push server.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To generate the VAPID keys, we run the following instruction:
&lt;/li&gt;
&lt;/ul&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;webPush&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="s2"&gt;web-push&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;webPush&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateVAPIDKeys&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;


&lt;span class="c1"&gt;// response:&lt;/span&gt;
&lt;span class="cm"&gt;/* {
  publicKey: 'BENBPj_33ywKcH109jfokUTiS91pLbD2SmVNbUja9KBN4Ppn8HTuZNC_TKEGGsJLRzx4X02kiNA7I-7uKYnLwRM',
  privateKey: '0LLLufPFBBXYFWOymFzrrLkLFeh0GTJzZ-XKf-Ehe_w'      
} */&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;We set those details with this function:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;webPush&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setVapidDetails&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="s2"&gt;`mailto:&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PRIMARY_EMAIL_OF_MENTAINER&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;vapidKeys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;publicKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;vapidKeys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;privateKey&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now we need 2 methods.&lt;/li&gt;
&lt;li&gt;One Method for adding the "Push Endpoints" for each app/device (aka the subscribers)&lt;/li&gt;
&lt;li&gt;One other method is for sending the actual Push Notification.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;subscribers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;setNewAdminSubscription&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;new subscription&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendAdminsNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;for &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;adminSub&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;subscribers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;webPush&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;adminSub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Test&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&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;
  
  
  2 - Frontend
&lt;/h2&gt;

&lt;p&gt;Okay on the front end we have to setup 2 things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;Service Worker&lt;/strong&gt;, which is basically a type of process that runs in the background, it's seperated from the web page itself, so it can do background fetching, handle push notifications and other things..&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A &lt;strong&gt;Function to Subscribe&lt;/strong&gt;, This would accomplish two things, show an "allow notifications ?" popup to show up, and also subscribe to the designated "Push Server" (depending on which navigator is being used).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For the service worker we create a file named "sw.js" (or any other name, it doesn't matter)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This handles the push notification in a way that it shows a popup and specifies the vibration settings (if the navigator is on a phone) etc etc.. basically customizing the popup that will show up.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// sw.js&lt;/span&gt;
&lt;span class="nb"&gt;self&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;push&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;e&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="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This notification is a teest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;images/example.jpg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;vibrate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="c1"&gt;// data: {&lt;/span&gt;
        &lt;span class="c1"&gt;//     dateOfArrival: Date.now(),&lt;/span&gt;
        &lt;span class="c1"&gt;//     primaryKey: '2'&lt;/span&gt;
        &lt;span class="c1"&gt;// },&lt;/span&gt;
        &lt;span class="c1"&gt;// sticky: true,&lt;/span&gt;
        &lt;span class="na"&gt;requireInteraction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;explore&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Explore this new world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;images/checkmark.jpg&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="na"&gt;action&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;icon&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;images/xmark.png&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;waitUntil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;registration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello World&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&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;ul&gt;
&lt;li&gt;Now to actually register it within the website, you have to run this code in the index.js (if you're using an SPA like React), or maybe index.html (inside a |script| block)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.js&lt;/span&gt;
&lt;span class="cm"&gt;/* ... */&lt;/span&gt;

&lt;span class="nf"&gt;createRoot&lt;/span&gt;&lt;span class="p"&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;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;StrictMode&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/StrictMode&amp;gt;&lt;/span&gt;&lt;span class="err"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;serviceWorker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/sw.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;registration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Service Worker Registered.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;function &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;registration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Service Worker Ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&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;ul&gt;
&lt;li&gt;Now this would be the actual subscribe action:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;sw&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;navigator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;serviceWorker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;push&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sw&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pushManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="err"&gt; &lt;/span&gt; &lt;span class="na"&gt;userVisibleOnly&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;applicationServerKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;VAPID-PUBLIC-KEY&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="err"&gt; &lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/subscribe-push&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;push&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point you're basically done, all you have to do now is incorporate the "sendPushNotification" method in critical parts of your backend.&lt;/p&gt;

&lt;p&gt;In an E-commerce website it could be a simple "new order has been created!" notification when an order has been created (on a &lt;strong&gt;Model/ORM/T-SQL Level&lt;/strong&gt;) or it could be of other uses.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl2ty7iy2cr7qajzy292.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwl2ty7iy2cr7qajzy292.png" alt="Flow of a Push Notification Mechanism in an E-Commerce website" width="800" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1) &lt;strong&gt;The Client makes a purchase (aka confirms an order)&lt;/strong&gt;&lt;br&gt;
2) &lt;strong&gt;The Web Server then logs the successful order in a Database (using an ORM or a Native DB-Adapter), then using the method we defined, the backend initializes a Push Notification to the Push Server&lt;/strong&gt;&lt;br&gt;
3) &lt;strong&gt;The Push Server then Pushes the notification to the Admin's Browser&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The point is that you could broadcast any notification to anyone, conditional statements could be added to make sure specific notifications get sent to specific "User-Agents" and so on.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>systemdesign</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>From the Market Stalls of Morocco to Building Tech Solutions for Europe</title>
      <dc:creator>appsbymuss</dc:creator>
      <pubDate>Thu, 24 Apr 2025 18:48:35 +0000</pubDate>
      <link>https://dev.to/techlabma/from-the-market-stalls-of-morocco-to-building-tech-solutions-for-europe-3lp9</link>
      <guid>https://dev.to/techlabma/from-the-market-stalls-of-morocco-to-building-tech-solutions-for-europe-3lp9</guid>
      <description>&lt;p&gt;I was born in &lt;strong&gt;Errachidia&lt;/strong&gt; and raised in &lt;strong&gt;Nador&lt;/strong&gt;, two small towns in &lt;strong&gt;Morocco&lt;/strong&gt;, in a family deeply rooted in &lt;strong&gt;B2B distribution&lt;/strong&gt; ; food, meat, and agricultural products through our family business, &lt;em&gt;2MP DIP Errachidia&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Summers were my earliest training ground. While other kids took vacations, I was at the local markets with my father and uncles, observing the rhythm of commerce and learning the subtle art of negotiation.&lt;/p&gt;

&lt;p&gt;At my uncle’s office , a real-world classroom ,I developed an instinct for &lt;strong&gt;positioning products&lt;/strong&gt;, understanding &lt;strong&gt;customer psychology&lt;/strong&gt;, and thinking in &lt;strong&gt;strategies&lt;/strong&gt; long before I opened my first marketing textbook.&lt;/p&gt;

&lt;h2&gt;
  
  
  From the Market to the Classroom
&lt;/h2&gt;

&lt;p&gt;These formative experiences shaped my academic direction. I pursued a &lt;strong&gt;BTS in Technico-Commercial&lt;/strong&gt;, followed by a &lt;strong&gt;professional bachelor's program in Management of Sales Forces&lt;/strong&gt;, seeking to reinforce practical knowledge with formal training.&lt;/p&gt;

&lt;p&gt;But in &lt;strong&gt;2019&lt;/strong&gt;, everything changed.&lt;/p&gt;

&lt;p&gt;I discovered the world of &lt;strong&gt;digital marketing&lt;/strong&gt;. I became fascinated by how websites rank, how algorithms behave, and how people interact with digital content. What started as curiosity quickly became a &lt;strong&gt;passion&lt;/strong&gt;, and that passion pointed me towards &lt;strong&gt;technology&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diving into Tech
&lt;/h2&gt;

&lt;p&gt;I took a bold leap.&lt;/p&gt;

&lt;p&gt;Determined to dive deeper, I joined a &lt;strong&gt;vocational program in Full-Stack Web Development&lt;/strong&gt; at the &lt;em&gt;Institute Specialized Technology Applied&lt;/em&gt;. Later, I advanced my skills through the &lt;strong&gt;ALX Software Engineering Program&lt;/strong&gt;, specializing in &lt;strong&gt;Back-end Development&lt;/strong&gt;. This rigorous training empowered me to &lt;strong&gt;build scalable digital solutions from scratch&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, there was one major challenge: in &lt;strong&gt;Nador&lt;/strong&gt;, tech jobs were limited.&lt;/p&gt;

&lt;p&gt;Instead of waiting for opportunities, I decided to &lt;strong&gt;create them&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a Bridge to Europe
&lt;/h2&gt;

&lt;p&gt;Drawing on my creative connections, particularly within the music and audiovisual arts community at &lt;strong&gt;Rif Records Studio&lt;/strong&gt;, I found an unexpected bridge to the &lt;strong&gt;European market&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Alongside fellow software engineer &lt;strong&gt;Youssef El Idrissi&lt;/strong&gt;, I co-founded the &lt;strong&gt;#./Techlab.MA Community&lt;/strong&gt;: a remote collective of five &lt;strong&gt;multidisciplinary freelancers&lt;/strong&gt; dedicated to delivering real-world tech solutions to startups and small businesses.&lt;/p&gt;

&lt;p&gt;With my strong background in business, I naturally stepped into the role of &lt;strong&gt;Business Lead&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Managing client relations&lt;/li&gt;
&lt;li&gt;Negotiating contracts&lt;/li&gt;
&lt;li&gt;Building sustainable partnerships&lt;/li&gt;
&lt;li&gt;Collaborating with our community in production&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Real Clients, Real Impact
&lt;/h2&gt;

&lt;p&gt;We’ve successfully collaborated with companies across &lt;strong&gt;Europe and Morocco&lt;/strong&gt;, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sanhaji Production&lt;/strong&gt; and &lt;strong&gt;Ness Production&lt;/strong&gt; in &lt;em&gt;Belgium&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;lemiel.shop&lt;/strong&gt; in &lt;em&gt;France&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;22 Codes&lt;/strong&gt; in &lt;em&gt;Fes&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dima TV Press&lt;/strong&gt; and &lt;strong&gt;Opal Multiservices&lt;/strong&gt; in &lt;em&gt;Morocco&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These weren’t just freelance gigs. Each project was &lt;strong&gt;proof that talent, resilience, and results can come from anywhere&lt;/strong&gt; , even a small town like Nador.&lt;/p&gt;

&lt;h2&gt;
  
  
  Looking Ahead: A New Chapter in Germany
&lt;/h2&gt;

&lt;p&gt;Today, I’m actively preparing to pursue a &lt;strong&gt;Duales Studium in Wirtschaftsinformatik&lt;/strong&gt; in &lt;strong&gt;Germany&lt;/strong&gt;,a country where innovation meets precision and where theory is deeply connected to real-world practice.&lt;/p&gt;

&lt;p&gt;Germany’s dual education system aligns perfectly with my story: I’ve always learned by doing, from markets to codebases. Wirtschaftsinformatik allows me to blend my business roots with technical skills to help companies deliver smarter, faster, and more user-centered solutions.&lt;/p&gt;

&lt;p&gt;My goal is to &lt;strong&gt;become a bridge between business and development teams&lt;/strong&gt;, making sure that customer needs, tech possibilities, and strategic priorities stay aligned.&lt;/p&gt;

&lt;p&gt;This path offers the ideal convergence of my &lt;strong&gt;practical business experience&lt;/strong&gt; and &lt;strong&gt;technical expertise&lt;/strong&gt;, while immersing me in the heart of &lt;strong&gt;Europe’s innovation ecosystem&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For me, this isn’t just a career move, it’s a &lt;strong&gt;mission&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I aim to stand at the intersection of &lt;strong&gt;business and technology&lt;/strong&gt; to build impactful, sustainable, and inclusive solutions. The goal is not just to succeed, but to &lt;strong&gt;open doors for others like me&lt;/strong&gt;, self-taught, self-driven, and ready to make a difference.&lt;br&gt;
In the long term, I see myself growing into the role of a &lt;strong&gt;Product Owner&lt;/strong&gt;, then eventually a &lt;strong&gt;Chief Product Officer (CPO) or Chief Technology Officer (CTO)&lt;/strong&gt; in a forward-thinking tech company ,guiding strategy, innovation, and cross-functional collaboration at the highest level.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Connect
&lt;/h2&gt;

&lt;p&gt;I’m currently open to &lt;strong&gt;collaborations&lt;/strong&gt;, &lt;strong&gt;mentorships&lt;/strong&gt;, and &lt;strong&gt;career opportunities&lt;/strong&gt; across the &lt;strong&gt;tech industry&lt;/strong&gt; from startups to established companies, across all disciplines.&lt;/p&gt;

&lt;p&gt;I’m especially interested in connecting with those working in Germany and also people works in :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;#businessinformatics&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;#softwaredevelopment&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether you’re a professional, student, founder, or mentor—if you’re passionate about tech and innovation, &lt;strong&gt;let’s connect and build the future together&lt;/strong&gt; .&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>softwareengineering</category>
      <category>career</category>
      <category>devjournal</category>
    </item>
    <item>
      <title>Real-Time Communication in Web</title>
      <dc:creator>appsbymuss</dc:creator>
      <pubDate>Thu, 06 Feb 2025 08:27:36 +0000</pubDate>
      <link>https://dev.to/techlabma/real-time-communication-in-web-1mbi</link>
      <guid>https://dev.to/techlabma/real-time-communication-in-web-1mbi</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This Blog post is part of a collaborative work between &lt;strong&gt;Me&lt;/strong&gt; and &lt;strong&gt;Youssef El Idrissi&lt;/strong&gt;, Consult his devTo page for more information: &lt;a href="https://dev.to/0xw3ston"&gt;https://dev.to/0xw3ston&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is Real-Time Communication ?
&lt;/h2&gt;

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

&lt;p&gt;Real-Time Communication refers to the instant exchange of data between systems, often characterized by low latency, where responses are nearly immediate. This type of communication is critical in applications like messaging, live streaming, gaming, financial trading, and collaborative tools where updates need to be reflected immediately for a seamless user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Some use cases for using RT Comm. Mechanisms:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Video and Audio Streaming:&lt;/em&gt; RTC is essential for low-latency, real-time media streaming in applications like video conferencing, virtual events, and online broadcasting where any delay can disrupt the user experience.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Live Updates and Notifications:&lt;/em&gt; RTC is used to push real-time notifications and alerts to users, such as updates in social media feeds, new messages, stock price changes, or sports scores, allowing users to stay up-to-date without needing to reload the page.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Instant Messaging and Chat:&lt;/em&gt; RTC allows for real-time text, audio, or video messaging, which is essential for communication apps and customer support platforms. Users can see messages immediately without refreshing the app.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What ways/methods exist to achieve that ?
&lt;/h2&gt;

&lt;p&gt;There are 4 common ways to implement live data updates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Short Polling&lt;/em&gt;: It involves sending HTTP GET Requests every X seconds (most commonly 5 seconds) in order to fetch if there are any updates from the backend server&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Long Polling&lt;/em&gt;: This one only sends the backend one single HTTP Request, which the backend tries to delay as much as possible for incase an Update occurs to let the user be notified of it.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;SSE (Server-Sent Events)&lt;/em&gt;: This method is Unidirectional (from Backend to Frontend), which means the Client cannot send data to the server (not using SSE's anyways).&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;WebSockets&lt;/em&gt;: this is the best choice in terms of Bidirectional communication (it allows both the client and backend to communicate with eachother), it is the most common way of implementing real time communication.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;blockquote&gt;
&lt;p&gt;There are other ways such as WebRTC for video streaming but we won't cover that in this post.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>learning</category>
      <category>interview</category>
      <category>career</category>
    </item>
    <item>
      <title>GitHub Webhook CI/CD: Step-by-step guide</title>
      <dc:creator>Youssef El Idrissi</dc:creator>
      <pubDate>Tue, 04 Feb 2025 21:33:53 +0000</pubDate>
      <link>https://dev.to/techlabma/github-webhook-cicd-step-by-step-guide-1j6g</link>
      <guid>https://dev.to/techlabma/github-webhook-cicd-step-by-step-guide-1j6g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This Blog post is part of a collaborative work between &lt;strong&gt;Me&lt;/strong&gt; and &lt;strong&gt;Mustapha El Idrissi&lt;/strong&gt;, Consult his devTo page for more information: &lt;a href="https://dev.to/appsbymuss"&gt;https://dev.to/appsbymuss&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is CI/CD
&lt;/h2&gt;

&lt;p&gt;CI/CD, or &lt;strong&gt;Continuous Integration and Continuous Delivery/Deployment&lt;/strong&gt;, is a set of practices and tools that automates the process of software development, testing, and release. It helps developers deliver code changes more frequently, safely, and reliably.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuous Integration&lt;/strong&gt;: This is a development practice where developers frequently integrate their code changes into a shared repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuous Delivery&lt;/strong&gt;:  This goes one step further by automating the entire release process. Once code passes all testing stages, it is automatically deployed to the production environment.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There are lot of tools that are used to perform &lt;strong&gt;CI&lt;/strong&gt; and &lt;strong&gt;CD&lt;/strong&gt; such as and not limited to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Jenkins&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Actions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitLab CI/CD&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Travis CI&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However these tools are usually followed by resource use restrictions or require monetary contributions to be used efficiently and at the same time beginners struggle to use such tools at the start of their Software Development career.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;There is however an easier-to-bootstrap and harder-to-efficiently-setup way to achieve CI/CD which is &lt;strong&gt;"GitHub &lt;a href="https://www.youtube.com/watch?v=Q_VPL6KrH2o" rel="noopener noreferrer"&gt;Webhooks&lt;/a&gt;"&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How to setup GitHub Webhook ?
&lt;/h2&gt;

&lt;h4&gt;
  
  
  Step 0: Create a repo
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ofcourse when we have a new project we have to create a new repository for it to store our code changes (aka commits), but in this case it will also be useful to achieve our CI/CD goal.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 1: Create a route for the POST-webhook
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Assuming that you already have a server with your desired runtime environment/Framework up and running on a specific port.&lt;/li&gt;
&lt;li&gt;You're gonna have to also make a webhook in order to let Github have a way to reach your server in the case of new change to the &lt;strong&gt;main/production branch on your github repo&lt;/strong&gt; like so:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&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;dotenv&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;config&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;express&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;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;crypto&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;crypto&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bodyParser&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;body-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt; &lt;span class="p"&gt;}&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;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;express&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updatedAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;verifySignature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;encoding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x-hub-signature-256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; &lt;span class="c1"&gt;// GitHub sends the signature here&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;No signature found on request&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;hmac&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;crypto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createHmac&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha256&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REPO_WEBHOOK_SECRET&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;digest&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;sha256=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;hmac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;hex&lt;/span&gt;&lt;span class="dl"&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;signature&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="nx"&gt;digest&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Signature does not match&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Signature is valid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bodyParser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/cicd/github-cicd&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// The raw body of the request&lt;/span&gt;
    &lt;span class="c1"&gt;// const isValid = verifySignature(req, res, buf);&lt;/span&gt;

    &lt;span class="cm"&gt;/* if (!isValid) {
            return res.status(401).send('Invalid signature');
    }*/&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&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;ref&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;refs/heads/main&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="c1"&gt;// PM2 is my instance manager&lt;/span&gt;
        &lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;git pull origin main &amp;amp;&amp;amp; pm2 restart cicd_app&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/cicd/time&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;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;updatedAt&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h1&amp;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;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&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="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Listening on Port 80...&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;p&gt;(&lt;a href="https://github.com/0xW3ston/ci_cd_basics" rel="noopener noreferrer"&gt;Full source code&lt;/a&gt;)&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Configure the repo's settings
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to [YourRepo -&amp;gt; Settings -&amp;gt; Webhooks]&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ylrjzqbebg5ut9mcjdg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1ylrjzqbebg5ut9mcjdg.png" alt=" " width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8kx2eo2055ujnbi897q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq8kx2eo2055ujnbi897q.png" alt=" " width="785" height="126"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then we get to the webhook creation panel&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[&lt;strong&gt;warn&lt;/strong&gt;] Depending on the SSL state of your website (if it's activated or not), choose the "SSL Verification" option accordingly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;[&lt;strong&gt;warn&lt;/strong&gt;] Incase you want Github to include a "secret" token to authenticate itself to your server to ensure it's Github and not a threat actor, then put a secret word, otherwise leave empty. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h4&gt;
  
  
  Step 3: Ready !
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;After Setting up your webhook on your &lt;strong&gt;webserver&lt;/strong&gt; and &lt;strong&gt;github webhook&lt;/strong&gt; of your repo, then you're basically good to go.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Macro
&lt;/h3&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;First&lt;/strong&gt; a developer will push their commit (code changes) to GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Secondly&lt;/strong&gt; GitHub will send a POST Request to our server, and specifically to our webhook route with the body in JSON with information related to that github push that we've done just a moment ago.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Thirdly&lt;/strong&gt; The server will then ofcourse treat said request as a way to know that there are changes on the production branch that must be applied as soon as possible, therefor a &lt;strong&gt;git pull&lt;/strong&gt; will be attempted and then tests and new builds and whatnot are going to be executed. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Finally&lt;/strong&gt; The server will consequently restart with the updated source code.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>devops</category>
      <category>node</category>
      <category>github</category>
    </item>
    <item>
      <title>Vim: an epic terminal-based text editor</title>
      <dc:creator>Youssef El Idrissi</dc:creator>
      <pubDate>Sat, 28 Sep 2024 06:01:59 +0000</pubDate>
      <link>https://dev.to/techlabma/vim-an-epic-terminal-based-text-editor-4p9m</link>
      <guid>https://dev.to/techlabma/vim-an-epic-terminal-based-text-editor-4p9m</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This Blog post is part of a collaborative work between &lt;strong&gt;Me&lt;/strong&gt; and &lt;strong&gt;Mustapha El Idrissi&lt;/strong&gt;, Consult his devTo page for more information: &lt;a href="https://dev.to/appsbymuss"&gt;https://dev.to/appsbymuss&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Introduction about Vim
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Vim&lt;/strong&gt; (short for &lt;strong&gt;V&lt;/strong&gt;i &lt;strong&gt;IM&lt;/strong&gt;proved) is a highly configurable and efficient text editor that extends the functionality of the classic Unix-based Vi editor. Created by &lt;u&gt;Bram Moolenaar&lt;/u&gt;, Vim is designed to maximize productivity in text editing through a combination of keyboard-driven commands and modes.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Buffers in vim ?
&lt;/h2&gt;

&lt;p&gt;In Vim, a buffer is essentially an in-memory representation of a file. When you open a file in Vim, it is loaded into a buffer, allowing you to make changes to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basics of Vim
&lt;/h2&gt;

&lt;h4&gt;
  
  
  To Edit a file (or Create one)
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;vim &amp;lt;file_name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Saving and Quitting
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;To save the modifications to a file&lt;/strong&gt;: you simply press [:] then type &lt;a href="https://dev.towhich%20stands%20for%20[w]rite"&gt;w&lt;/a&gt; and press ENTER&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To save the mods. and quit the file&lt;/strong&gt;: you do the same thing except it's &lt;a href="https://dev.towhich%20is%20w[rite]%20and%20q[uit]"&gt;:wq&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;To quit a file and discard the mods.&lt;/strong&gt;: press [:] and type [q!] then ENTER&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  There are 4 Modes in Vim
&lt;/h4&gt;

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

&lt;h6&gt;
  
  
  &lt;strong&gt;NORMAL MODE&lt;/strong&gt;: It is the default mode. It is mostly useful for navigating through a file, however there are some shortcuts that make modifications to the file even with this mode. For example:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Pressing [0]: Places the cursor at the start of the current line.&lt;/li&gt;
&lt;li&gt;Pressing [$]: Places the cursor at the end of the current line.&lt;/li&gt;
&lt;li&gt;Pressing [u]: Undo's the last change that was done to the "buffer".&lt;/li&gt;
&lt;li&gt;Pressing [x]: Deletes one character (where the cursor is).&lt;/li&gt;
&lt;li&gt;Pressing [dd]: Deletes the current line (but it gets saved in the "paste buffer", which means the contents can be "pasted".&lt;/li&gt;
&lt;li&gt;Pressing [p]: Pastes whatever is copied (in the "paste buffer")&lt;/li&gt;
&lt;li&gt;Pressing [gg]: Places the cursor at the first line in the file.&lt;/li&gt;
&lt;li&gt;Pressing [G]: Places the cursor at the last line in the file&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  &lt;strong&gt;INSERT MODE&lt;/strong&gt;: This mode is activated by pressing [i]. It is used to insert new data to the document. Here are some examples of shortcuts:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Pressing [a + Shift]: Places the cursor at the end of the current line and activates INSERT MODE.&lt;/li&gt;
&lt;li&gt;Pressing [i]: Activates INSERT MODE.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  &lt;strong&gt;VISUAL MODE&lt;/strong&gt;: This mode is useful to select specific subtext and apply modifications on it. It is activated by pressing [v]. Here are a few examples of shortcuts:
&lt;/h6&gt;

&lt;ul&gt;
&lt;li&gt;Pressing [y]: The selected section of text will be copied (not cut) and get placed in the "paste buffer" (to be pasted somewhere)&lt;/li&gt;
&lt;li&gt;Pressing [:] then Typing [sort ui]: This will sort the selected lines alphabetically and ensure there are no duplicate lines.&lt;/li&gt;
&lt;/ul&gt;

&lt;h6&gt;
  
  
  &lt;strong&gt;COMMAND MODE&lt;/strong&gt;: Accessed by pressing [:]. Used for entering commands such as saving files, quitting Vim, and searching.
&lt;/h6&gt;

&lt;p&gt;examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;[:! &amp;lt;LINUX_COMMAND&amp;gt;] - Execute a command while in vim&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  File Operations
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;[:q] - Close the current window/buffer.&lt;/li&gt;
&lt;li&gt;[:w] - Write changes to the current file.&lt;/li&gt;
&lt;li&gt;[:q!] - Close the current window/buffer and discard of the changes.&lt;/li&gt;
&lt;li&gt;[:wq] - Write changes to the current file and close the window.&lt;/li&gt;
&lt;li&gt;[:r &amp;lt;file_name&amp;gt;] - Copy the buffer of "file_name" and paste it in the current buffer.&lt;/li&gt;
&lt;li&gt;[:w &amp;lt;file_name&amp;gt;] - Copy and Write the current buffer to "file_name"&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  String Search
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;[:%s/&amp;lt;regExpr&amp;gt;] - Search and highlight the first occurence of a string/pattern.&lt;/li&gt;
&lt;li&gt;[:%s/&amp;lt;regExpr&amp;gt;/String2/g] - Search and replace ALL the occurences of a string/pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Buffers
&lt;/h2&gt;

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

&lt;p&gt;Buffers can be extremely useful when you want to edit multiple files at the same time. Using COMMAND MODE, here are some useful tricks:&lt;/p&gt;

&lt;p&gt;[:ls] - Lists all the buffers currently accessible. (the one active has a %a sign)&lt;br&gt;
[:e &amp;lt;file_name&amp;gt;] - Load a file into a new buffer.&lt;br&gt;
[:b &amp;lt;buffer_number&amp;gt;] - To switch to a buffer&lt;br&gt;
[:enew] - To create an empty buffer (whose content that you can later on save to a file or to another buffer)&lt;br&gt;
[:bn] - Switches to the next buffer in the list.&lt;br&gt;
[:bp] - Switches to the previous buffer in the list.&lt;br&gt;
[:bw &amp;lt;buffer_number&amp;gt;] - Saves changes to the buffer X.&lt;br&gt;
[:bd &amp;lt;buffer_name&amp;gt;] - Deletes the buffer X.&lt;br&gt;
[:bd! &amp;lt;buffer_name&amp;gt;] - Deletes the buffer X discarding of any changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Splitting the screen
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Horizentally
&lt;/h3&gt;

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

&lt;p&gt;[:sp[lit] &amp;lt;file_name&amp;gt;] - Splits the current file with "file_name" horizentally, This step can be done multiple times with multiple files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vertically
&lt;/h3&gt;

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

&lt;p&gt;[:vsp[lit] &amp;lt;file_name&amp;gt;] - Splits the current file with "file_name" horizentally, This step can be done multiple times with multiple files.&lt;br&gt;
[Ctrl + ww] - To switch between "splits".&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages of a Terminal-based Text editor
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Vim is very light resources-wise, which makes it ideal to run on low-end machines.&lt;/li&gt;
&lt;li&gt;It is terminal-based which means it can be executed and used remotely without any trouble using something like SSH.&lt;/li&gt;
&lt;li&gt;The learning curve to master Vim is a bit steep but everyone can master the basics quite easily after a bit of practice.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>linux</category>
      <category>vim</category>
      <category>terminal</category>
    </item>
    <item>
      <title>Diffie-Hellman Key Exchange (DHKE) Algorithm</title>
      <dc:creator>Youssef El Idrissi</dc:creator>
      <pubDate>Sat, 31 Aug 2024 17:12:48 +0000</pubDate>
      <link>https://dev.to/techlabma/diffie-hellman-key-exchange-dhke-algorithm-505b</link>
      <guid>https://dev.to/techlabma/diffie-hellman-key-exchange-dhke-algorithm-505b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction &amp;amp; History
&lt;/h2&gt;

&lt;p&gt;The Diffie-Hellman Key Exchange algorithm is a fascinating method that allows two parties to securely share a secret key over an insecure communication channel (for example: over the internet). Introduced by &lt;u&gt;Whitfield Diffie&lt;/u&gt; and &lt;u&gt;Martin Hellman&lt;/u&gt; in 1976 and it marked a significant advancement in the field of cryptography because, prior to its development, securely exchanging keys was a major challenge, particularly in the realm of &lt;strong&gt;symmetric encryption&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the "DHKE" Algorithm?
&lt;/h2&gt;

&lt;p&gt;The Diffie-Hellman Key Exchange algorithm is &lt;strong&gt;a type of public key cryptography&lt;/strong&gt; that enables two parties, who may have never communicated before and are connected &lt;strong&gt;over an unsecured network&lt;/strong&gt;, to establish a shared secret. This shared secret can then be used to encrypt subsequent communications using &lt;strong&gt;symmetric encryption algorithms&lt;/strong&gt; (such as AES-256).&lt;/p&gt;

&lt;h2&gt;
  
  
  Phase I: Initialization
&lt;/h2&gt;

&lt;p&gt;Two parties, typically called Alice and Bob, agree on a common set of public parameters:&lt;br&gt;
&lt;strong&gt;- 𝑝:&lt;/strong&gt; A large prime number, which will be used as the "modulus".&lt;br&gt;
&lt;strong&gt;- g:&lt;/strong&gt; a primitive root (also known as the generator) of 𝑝, which is a number that, when raised to various powers, generates all the numbers from 1 to 𝑝−1 under modulo 𝑝.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Phase II: Key Exchange
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Private Key Selection:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Alice&lt;/strong&gt; selects a &lt;strong&gt;private key X&lt;/strong&gt;, which is a random integer that she keeps secret.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bob&lt;/strong&gt; selects a &lt;strong&gt;private key Y&lt;/strong&gt;, which is also a random integer that he keeps secret.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h3&gt;
  
  
  Public Key Computation and Exchange:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Both &lt;strong&gt;Alice&lt;/strong&gt; and &lt;strong&gt;Bob&lt;/strong&gt; calculate their public keys respectively using the equations in the graph shown below.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Then &lt;strong&gt;Alice&lt;/strong&gt; and &lt;strong&gt;Bob&lt;/strong&gt; exchange their public keys (&lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B&lt;/strong&gt; over the insecure channel)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Phase III: Shared Secret Computation
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Shared Secret Derivation:
&lt;/h3&gt;

&lt;p&gt;The Last step is to derive the &lt;strong&gt;Shared Secret&lt;/strong&gt; using the equations below&lt;/p&gt;

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

&lt;p&gt;Both calculations result in the same shared secret &lt;strong&gt;K&lt;/strong&gt;, which can now be used as a key for &lt;strong&gt;symmetric encryption&lt;/strong&gt; to securely communicate.&lt;/p&gt;

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

&lt;h2&gt;
  
  
  Disadvantages...
&lt;/h2&gt;

&lt;p&gt;Diffie-Hellman is a great algorithm but when used alone there are vulnerabilities such as, &lt;strong&gt;Man-in-The-Middle attack (MiTM)&lt;/strong&gt;.&lt;br&gt;
It goes like the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the exact moment that "Alice" and "Bob" have generated their Public Keys (A and B) and when one of them tries to share their public key with the other over an insecure network, an Attacker ("Aku" for example) intercepts that public key, only to replace it with his own calculated Public key.&lt;/li&gt;
&lt;li&gt;The process then happens the same way for both parties (Bob and Alice).&lt;/li&gt;
&lt;li&gt;Aku Sends his Public Key C to Bob and receives Bob's public key B.&lt;/li&gt;
&lt;li&gt;Aku Sends his Public Key C to Alice and receives Alice's public key A.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Shared Secret Derivation gets calculated by Bob, Alice, and as for Aku, he does that calculation 2 times (one for Aku-Bob shared secret, and another for Aku-Alice shared secret)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;In the end, Aku ends up seeing what both Alice and Bob send each other over the network.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Digital Certificates help against this type of Attack because it confirms that "Bob" is Bob and that "Alice" is Alice.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>cybersecurity</category>
      <category>learning</category>
      <category>security</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>SSH Tunneling</title>
      <dc:creator>appsbymuss</dc:creator>
      <pubDate>Sat, 31 Aug 2024 17:11:05 +0000</pubDate>
      <link>https://dev.to/techlabma/ssh-tunneling-5ej6</link>
      <guid>https://dev.to/techlabma/ssh-tunneling-5ej6</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;(This Blog post is part of a collaborative work between &lt;strong&gt;Me&lt;/strong&gt; and &lt;strong&gt;Youssef El Idrissi&lt;/strong&gt;, Consult his devTo page for more information: &lt;a href="https://dev.to/0xw3ston"&gt;https://dev.to/0xw3ston&lt;/a&gt;)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What is SSH Tunneling
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;SSH tunneling&lt;/strong&gt;, also known as &lt;strong&gt;SSH port forwarding&lt;/strong&gt;, is a method of securely routing network traffic from one network to another through an encrypted SSH (Secure Shell) connection. This technique allows you to forward traffic for various types of network services through the SSH connection, effectively bypassing firewalls or securing communications over an untrusted network, such as the internet.&lt;br&gt;
There are 3 types of SSH Tunneling: Local, Remote and Dynamic&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Port Forwarding
&lt;/h3&gt;

&lt;p&gt;This forwards traffic from a specific port on the local machine to a port on a remote machine through the SSH server. It's commonly used to access services behind a firewall or NAT that aren't directly accessible from the client machine.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; You have a MySQL server that is running a remote machine but you don't want to directly expose its port publicly, we can use a MySQL Client Tool (such as MySQL-Workbench) through a Local SSH Tunnel to access the DB without ever exposing said database publicly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;command to execute:&lt;/strong&gt; &lt;code&gt;ssh -L [local_port]:[remote_host]:[remote_port] [user]@[ssh_server]&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;example&lt;/strong&gt;: ssh &lt;strong&gt;-L&lt;/strong&gt; 3008:remote.example.com:3306 &lt;a href="mailto:user@ssh-server.com"&gt;user@ssh-server.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Remote Port Forwarding
&lt;/h3&gt;

&lt;p&gt;This forwards traffic from a specific port on the SSH server to a port on a machine accessible to the client. It's used to expose a local service to the internet or a remote network.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; You have an Apache web server that you want to be exposed only to a single remote machine (or network) to maybe automate tests or something of the sort.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;command to execute:&lt;/strong&gt; &lt;code&gt;ssh -R [remote_port]:[local_host]:[local_port] [user]@[ssh_server]&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;example&lt;/strong&gt;: ssh &lt;strong&gt;-R&lt;/strong&gt; 8080:localhost:80 &lt;a href="mailto:user@ssh-server.com"&gt;user@ssh-server.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Dynamic Port Forwarding
&lt;/h3&gt;

&lt;p&gt;This turns the SSH client into a SOCKS proxy server, allowing it to dynamically forward traffic through the SSH server. It's useful for routing traffic from multiple applications through the SSH connection.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; There are geographical restrictions on some website you want to visit, therefor we use the Remote machine to act as a &lt;strong&gt;SOCKS Proxy&lt;/strong&gt; and essentially forward requests to the Internet on our behalf (in this case it's HTTP Requests)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;command to execute:&lt;/strong&gt; &lt;code&gt;ssh -D [local_port] [user]@[ssh_server]&lt;/code&gt;&lt;br&gt;
&lt;strong&gt;example&lt;/strong&gt;: ssh &lt;strong&gt;-D&lt;/strong&gt; 1080 &lt;a href="mailto:user@ssh-server.com"&gt;user@ssh-server.com&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
  </channel>
</rss>
