<?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: Rakan</title>
    <description>The latest articles on DEV Community by Rakan (@irakan).</description>
    <link>https://dev.to/irakan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1246609%2Ff8633113-f125-40f2-9037-f8049a3c6809.jpg</url>
      <title>DEV Community: Rakan</title>
      <link>https://dev.to/irakan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/irakan"/>
    <language>en</language>
    <item>
      <title>Python package conflicts</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Thu, 05 Sep 2024 09:15:04 +0000</pubDate>
      <link>https://dev.to/irakan/python-package-conflicts-4cpe</link>
      <guid>https://dev.to/irakan/python-package-conflicts-4cpe</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fskvrvzuxw93ceffql76r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fskvrvzuxw93ceffql76r.png" alt="m" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When developing a Python package, users might encounter dependency conflicts if different versions of the same dependency are required. For example, if your package requires &lt;code&gt;requests==2.26.0&lt;/code&gt;, but the user's system needs &lt;code&gt;requests==2.25.1&lt;/code&gt;, both cannot coexist since Python doesn’t allow multiple versions of the same package to be installed simultaneously.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approaches to Avoid Dependency Conflicts:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  A. &lt;strong&gt;Vendor Approach&lt;/strong&gt;:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Vendoring Dependencies&lt;/strong&gt;: This involves including necessary dependencies directly in your package. It's useful for controlling versions but may increase package size.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pure-Python Packages&lt;/strong&gt;: Vendoring works well for pure Python packages without their own dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Packages with Dependencies&lt;/strong&gt;: Vendoring becomes problematic if the vendored package has its own dependencies, leading to potential conflicts.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Issues&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dependency Clashes&lt;/strong&gt;: Vendoring a package with dependencies may lead to conflicts in the user's environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Version Control&lt;/strong&gt;: Keeping vendored dependencies updated is crucial for security.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size&lt;/strong&gt;: Vendoring can increase package size.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Scenario 1&lt;/strong&gt;: If &lt;code&gt;requests&lt;/code&gt; had no dependencies, bundling it with your package ensures the correct version is used.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scenario 2&lt;/strong&gt;: Since &lt;code&gt;requests&lt;/code&gt; relies on libraries like &lt;code&gt;urllib3&lt;/code&gt;, including it may cause conflicts if other packages require different versions of &lt;code&gt;urllib3&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: If you do vendoring, you need to comply with the vendoring policy. &lt;a href="https://pip.pypa.io/en/stable/development/vendoring-policy/" rel="noopener noreferrer"&gt;Check it here&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  B. &lt;strong&gt;Virtual Environment Approach&lt;/strong&gt;:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Dependency conflicts are often out of your control, especially in third-party apps, even if virtual environments are used.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Issues&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Out of Our Control&lt;/strong&gt;: How users set up virtual environments is beyond our influence.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Third-Party Apps&lt;/strong&gt;: They might still face conflict issues, even in virtual environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  C. &lt;strong&gt;Fork Approach&lt;/strong&gt;:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You can fork the conflicting package, rename it (e.g., &lt;code&gt;mypackage-requests==2.26.0&lt;/code&gt;), and use the forked version in your package.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Issues&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance&lt;/strong&gt;: Forking requires keeping the fork updated with the original package.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Child Dependencies&lt;/strong&gt;: If the forked package has dependencies, you may need to fork and manage those as well.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion:
&lt;/h3&gt;

&lt;p&gt;Each approach has its benefits and challenges, and the choice depends on your specific use case and how much control you want over the dependencies. As a rule of thumb, it’s better to resolve conflicts by maintaining the package properly, ensuring compatibility with the broader Python ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/Python/comments/ua2a7k/how_do_you_manage_conflicting_packages_in_your/" rel="noopener noreferrer"&gt;How do you manage conflicting packages in your requirements.txt?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pip.pypa.io/en/stable/development/vendoring-policy/" rel="noopener noreferrer"&gt;Vendoring Policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/mwilliamson/python-vendorize" rel="noopener noreferrer"&gt;python-vendorize&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.reddit.com/r/Python/comments/132jk6l/how_do_you_feel_about_vendored_packages/" rel="noopener noreferrer"&gt;How do you feel about vendored packages?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>python</category>
      <category>development</category>
    </item>
    <item>
      <title>JWT can fit as an authentication system with a blacklist technique</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Sun, 04 Feb 2024 19:34:32 +0000</pubDate>
      <link>https://dev.to/irakan/jwt-can-fit-as-an-authentication-system-with-a-blacklist-technique-4ohl</link>
      <guid>https://dev.to/irakan/jwt-can-fit-as-an-authentication-system-with-a-blacklist-technique-4ohl</guid>
      <description>&lt;p&gt;As mentioned &lt;a href="https://dev.to/irakan/is-jwt-really-a-good-fit-for-authentication-1khm"&gt;before&lt;/a&gt;, JWT has some drawbacks that make it unsuitable as an authentication system. However, there are ways to work around these drawbacks and make JWT more secure.&lt;/p&gt;

&lt;p&gt;One way to protect our system is to blacklist JWT tokens (although JWT is stateless and was not designed to be blacklisted). But as they say, tools can be used in ways they were not designed for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here's how it works:
&lt;/h3&gt;

&lt;p&gt;First, make sure to add the &lt;code&gt;issued_at&lt;/code&gt; (iat) claim to the payload of the JWT token when the server creates it. It's a timestamp that represents the time when the token was issued/created. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"user_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"123"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"iat"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1643961600&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, this is how the process will work when a user logs out or you want to block someone from accessing the system through an admin dashboard or something:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When a user logs out, we will add their &lt;code&gt;user_id&lt;/code&gt; and &lt;code&gt;minimum_issued_at&lt;/code&gt; to a blacklist table in the database.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;blacklist&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;minimum_issued_at&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;When a user tries to access the system via a JWT token, it will go through this process:

&lt;ul&gt;
&lt;li&gt;The server will check if the JWT token is valid (not expired, not tampered with, etc.).&lt;/li&gt;
&lt;li&gt;If the JWT token is valid, the server will check if the &lt;code&gt;user_id&lt;/code&gt; that is in the JWT payload exists in the blacklist table.&lt;/li&gt;
&lt;li&gt;If it exists, the server will check if the &lt;code&gt;iat&lt;/code&gt; of the token is greater than &lt;code&gt;minimum_issued_at&lt;/code&gt; in the blacklist table for that &lt;code&gt;user_id&lt;/code&gt;.

&lt;ul&gt;
&lt;li&gt;NOTE: If the user has multiple records in the blacklist table, the server will check for the record with the latest &lt;code&gt;minimum_issued_at&lt;/code&gt; value since it's the most recent one.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If the &lt;code&gt;iat&lt;/code&gt; of the token is greater than &lt;code&gt;minimum_issued_at&lt;/code&gt;, the server will allow the user to access the system.&lt;/li&gt;
&lt;li&gt;If it's not greater, the server will deny the user access to the system (goodbye, you are blocked 😊 here is a 403 status code).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now, the blacklist table will have a lot of records over time (which is not good for performance/efficiency). So, we need to clean it up from time to time. We can do this by creating a cron job that runs every day and deletes all records that have &lt;code&gt;minimum_issued_at&lt;/code&gt; less than the current time minus JWT token TTL (Time To Live). This way, we can keep the blacklist table clean and small.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;blacklist&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;minimum_issued_at&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt; &lt;span class="k"&gt;MINUTE&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Additionally, you can also do global token invalidation by changing the secret key (not recommended, but it's an option). Or in the case of the Blacklist table, you can insert &lt;code&gt;user_id&lt;/code&gt; with the value "all" and &lt;code&gt;minimum_issued_at&lt;/code&gt; with the current time. And let the server check for this record first before checking for the user's record. If it exists, deny access to the system.&lt;/p&gt;

&lt;p&gt;Moreover, you can add more columns to the blacklist table to make it more flexible. For example, you can add a &lt;code&gt;platform&lt;/code&gt; column to store the platform that the token was issued for (web, mobile, etc.). You can add a &lt;code&gt;device&lt;/code&gt; column to store the device that the token was issued for (laptop, phone, etc.). This way, you can invalidate tokens based on the platform or device too.&lt;/p&gt;

&lt;p&gt;Drawbacks of Blacklisting JWT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need to query the database for each request to check if the token is blacklisted or not (since the table will be cleaned up from time to time, it will be small and fast to query + you can add an index on &lt;code&gt;user_id&lt;/code&gt; and &lt;code&gt;minimum_issued_at&lt;/code&gt; columns to make it faster to query + you can use a cache like Redis to store the blacklist table in memory to make it even faster).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Conclusion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Blacklisting JWT tokens is a good way to make JWT more secure and flexible even though it's not designed to be blacklisted. It's a good way to work around the drawbacks of JWT as an authentication system.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/pragativerma18/how-jwts-could-be-dangerous-and-its-alternatives-3k3j"&gt;How JWTs Could Be Dangerous and Its Alternatives&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>jwt</category>
      <category>authentication</category>
      <category>security</category>
    </item>
    <item>
      <title>Is JWT really a good fit for authentication?</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Sat, 03 Feb 2024 12:30:50 +0000</pubDate>
      <link>https://dev.to/irakan/is-jwt-really-a-good-fit-for-authentication-1khm</link>
      <guid>https://dev.to/irakan/is-jwt-really-a-good-fit-for-authentication-1khm</guid>
      <description>&lt;p&gt;UPDATE: &lt;a href="https://dev.to/irakan/jwt-can-fit-as-an-authentication-system-with-a-blacklist-technique-4ohl"&gt;JWT can fit as an authentication system with a blacklist technique&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;JWT (JSON Web Token) is a very popular way to authenticate users. It's a way to securely exchange data between client and server through a token. Here is how it works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;User sends their credentials (i.e. username and password) to the server.&lt;/li&gt;
&lt;li&gt;The server checks if the credentials are correct.&lt;/li&gt;
&lt;li&gt;If valid, server creates a JWT token as follows:

&lt;ul&gt;
&lt;li&gt;To make a JWT token, server will use 3 things: Header, Payload, and Secret.

&lt;ul&gt;
&lt;li&gt;Header: It contains type of token and hashing algorithm used to sign a signature.
&lt;code&gt;json
{
    "alg": "HS256",
    "typ": "JWT"
}
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Payload: It contains data that we want to send. For example, user's ID, username, email, etc.
&lt;code&gt;json
{
    "id": 1,
    "name": "John Doe",
    "admin": true
}
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Secret: It's a secret key that is used to sign a signature. It's only known by server.
&lt;code&gt;
"MySecretKeyThatNoBodyKnowsButTheServer"
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The server will use header (base64UrlEncode), payload (base64UrlEncode), and secret in order to create a signature. 
&lt;code&gt;
signature = HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The output structure of JWT token will be like this:
&lt;code&gt;
base64UrlEncode(header) + "." + base64UrlEncode(payload) + "." + signature 
&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The server sends JWT token to client.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;And that's it.  Client will send JWT token in header of each request to server.&lt;/p&gt;

&lt;p&gt;Very important notes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JWT token is not encrypted, it's just base64UrlEncoded. So, don't put any sensitive information in payload. Meaning, if for some reason an access token is stolen, an attacker will be able to decode it and see information in payload.&lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;Check it here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Keep access token expiry short (e.g., 15 minutes) to limit attacker misuse if stolen.&lt;/li&gt;
&lt;li&gt;Because access token is kept on client side, it's vulnerable to XSS attacks. Server can't set HttpOnly flag on it since client needs access to include it in requests.&lt;/li&gt;
&lt;li&gt;Dont use an access token to generate a new access token when old one expires. If access token is stolen, an attacker will be able to generate new access tokens forever. Instead, use a refresh token to generate new access tokens.&lt;/li&gt;
&lt;li&gt;Refresh tokens should have a long expiration time, and they are stored in HttpOnly cookies to prevent XSS attacks (only server can access them).&lt;/li&gt;
&lt;li&gt;Protect a refresh token from CSRF attacks by using &lt;code&gt;SameSite&lt;/code&gt; attribute in cookie. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite" rel="noopener noreferrer"&gt;Check it here&lt;/a&gt; so a browser will only send a cookie to server if a request originated from same site that set cookie in first place (server).&lt;/li&gt;
&lt;li&gt;As a security measure for refresh tokens. Create a table for refresh tokens in database and store refresh token's related information (user ID, expiration time, last used time, device, user agent, etc) to be able to revoke refresh token if it's stolen or check if refresh token was used before or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Firakan%2Fmy-learning-journey%2Fmain%2Fmemes%2F5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Firakan%2Fmy-learning-journey%2Fmain%2Fmemes%2F5.png" alt="perspective"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;Big Drawbacks of JWT:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Logout doesn't really log you out:

&lt;ul&gt;
&lt;li&gt;Once a JWT token is created, it's valid until it expires. There is no way to invalidate it. So, if a user logs out, you can delete the access token from client side, but it's still valid until it expires.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Blocking a user is not possible:

&lt;ul&gt;
&lt;li&gt;If a user is blocked, there is no way to block them from accessing the system until their access token expires. Imagine you are a bank and one of the users's access token is stolen, you can't block it or do anything about it until it expires which is a big security risk for a bank that deals with money.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Changes by system are not reflected in real time:

&lt;ul&gt;
&lt;li&gt;If a user's role is changed from admin to regular user, there is no way to reflect this change in real time. The user will still have access to admin features until their access token expires.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt; You can't know how many current users are logged-in:

&lt;ul&gt;
&lt;li&gt;Since JWT tokens are stateless, there is no way to know how many users are logged in at any given time in the system.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;My conclusion:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use traditional session-based authentication. It's more secure and flexible than JWT.&lt;/li&gt;
&lt;li&gt;JWT is a good fit for cases/situations where you want to issue a one-time token to be used for a specific purpose. &lt;a href="http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/" rel="noopener noreferrer"&gt;what is JWT good for, then?&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;JWT.io&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite" rel="noopener noreferrer"&gt;SameSite Cookie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#restrict_access_to_cookies" rel="noopener noreferrer"&gt;HttpOnly Cookie&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc6749" rel="noopener noreferrer"&gt;IETF RFC 6749&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jackywxd.medium.com/understand-jwt-access-token-vs-refresh-token-2951e5e45193" rel="noopener noreferrer"&gt;Access Token vs Refresh Token&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.izertis.com/en/-/refresh-token-with-jwt-authentication-in-node-js" rel="noopener noreferrer"&gt;Refresh token with JWT authentication in Node.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/" rel="noopener noreferrer"&gt;Stop using JWT for sessions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>jwt</category>
      <category>authentication</category>
      <category>security</category>
    </item>
    <item>
      <title>Type Declaration Files</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Sat, 20 Jan 2024 15:30:24 +0000</pubDate>
      <link>https://dev.to/irakan/type-declaration-files-36bk</link>
      <guid>https://dev.to/irakan/type-declaration-files-36bk</guid>
      <description>&lt;p&gt;Type Declaration Files are files that describe the whole API of a library that was written in Javascript. These files are the magic behind TypeScript. &lt;/p&gt;

&lt;p&gt;Let's break it down with a simple example:&lt;br&gt;
Suppose there is a JavaScript library called mathLibrary.js with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&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;If we try to use this library in a TypeScript file, we will get an error saying that &lt;code&gt;add&lt;/code&gt; function doesn't exist. This is because TypeScript doesn't know anything about this library (because it's written in JavaScript without any type annotations). So, we need to create a type declaration file for this library. Let's call it mathLibrary.d.ts. It will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;declare&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when we try to use this library in a TypeScript file, we will not get any errors. This is because TypeScript now knows about this library and its functions. It knows that &lt;code&gt;add&lt;/code&gt; function takes 2 numbers and returns a number. So, if we try to pass a string, it will show an error.&lt;/p&gt;

&lt;p&gt;Typescript depends on type declaration files heavily. It's what makes TypeScript so powerful. If you do &lt;code&gt;npm install typescript&lt;/code&gt;, you will see that it comes with a lot of type declaration files ".d.ts" files in the node_modules.&lt;/p&gt;

&lt;p&gt;Note: There is a tool called &lt;a href="https://github.com/DefinitelyTyped/DefinitelyTyped"&gt;DefinitelyTyped&lt;/a&gt; which has a lot of type declaration files for popular JavaScript libraries. You can install them using &lt;code&gt;npm install @types/&amp;lt;library-name&amp;gt;&lt;/code&gt;. For example, if you want to install type declaration files for Googlemaps JS library, you can do &lt;code&gt;npm install @types/googlemaps&lt;/code&gt; after that TypeScript will automatically find the type declaration files in the &lt;code&gt;node_modules/@types&lt;/code&gt; folder and use them to check your code for errors.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/2/type-declarations.html"&gt;Type Declarations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>TypeScript: Type Annotations and Type Inference</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Fri, 19 Jan 2024 20:07:43 +0000</pubDate>
      <link>https://dev.to/irakan/typescript-type-annotations-and-type-inference-146o</link>
      <guid>https://dev.to/irakan/typescript-type-annotations-and-type-inference-146o</guid>
      <description>&lt;p&gt;As I go through the typescript course, here are some things I have learned. In TypeScript, there are two important concepts: Type annotations and Type inference.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type Annotations:&lt;/strong&gt; We, as developers, use type annotations to tell TypeScript the type of value a variable will have. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;apples&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we're saying that &lt;code&gt;apples&lt;/code&gt; will always be a number. If we try to assign a string, TypeScript will show an error.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type Inference:&lt;/strong&gt; TypeScript tries to figure out the type of a variable by itself. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;apples&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When we declare and initialize a variable in one line, TypeScript guesses its type. In this case, it's a number. If we try to assign a string, TypeScript will show an error.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  When to use each one?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Type Inference:&lt;/strong&gt; Use it whenever possible. Let TypeScript do the work of figuring out types for you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Type Annotations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When declaring a variable and initializing it in separate lines:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;apples&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// should be let apples: number;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;When a function needs to clarify the type it returns:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numberToString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;num&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&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;When a variable's type can't be inferred(guessed by TypeScript):&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When Typescript can't figure out the intended type (a scenario where a variable could potentially have multiple types), we need to use type annotations. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;foundWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&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;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&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;foundWord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;i&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;to fix this, we need to add type annotations to &lt;code&gt;foundWord&lt;/code&gt; variable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;green&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;foundWord&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.udemy.com/course/nestjs-the-complete-developers-guide/"&gt;NestJS: The Complete Developer's Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Learning TypeScript and NestJS</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Fri, 19 Jan 2024 20:06:07 +0000</pubDate>
      <link>https://dev.to/irakan/learning-typescript-and-nestjs-13hm</link>
      <guid>https://dev.to/irakan/learning-typescript-and-nestjs-13hm</guid>
      <description>&lt;p&gt;In upcoming days I will shift my focus to learning NestJS and TypeScript for various reasons.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Javascript is a very popular language used by many small, big and huge companies (everywhere).&lt;/li&gt;
&lt;li&gt;Has a huge community and a lot of resources.&lt;/li&gt;
&lt;li&gt;Can be used for many things (Frontend, Backend, Mobile, Desktop, etc).&lt;/li&gt;
&lt;li&gt;In performance wise, its very fast and efficient language (very good for high traffic applications, example: Twitter/X).&lt;/li&gt;
&lt;li&gt;Its a must have skill/tool for any developer that wants to find a work in the tech industry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, I have enrolled in a course on Udemy to learn TypeScript and NestJS. I am on the first section of the course and here what I have learned so far:&lt;/p&gt;

&lt;p&gt;Why does TypeScript exist? &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Typescript is basically a superset of Javascript. It adds types to Javascript. It's like a layer on top of Javsacript. Typescript = Javascript + Type System.&lt;/li&gt;
&lt;li&gt;Helps you catch errors before you run your code.&lt;/li&gt;
&lt;li&gt;Helps you write better/Maintainable code.&lt;/li&gt;
&lt;li&gt;Doesnt run in the browser or nodejs. It needs to be compiled to Javascript first.&lt;/li&gt;
&lt;li&gt;It doesnt provide any performance benefits.&lt;/li&gt;
&lt;li&gt;Its like a friend sitting next to you and telling you "Hey, you made a mistake here, you should fix it before you run your code".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What is a type? &lt;br&gt;&lt;br&gt;&lt;br&gt;
A type is something that describes the different properties and functions that a value has. Lets take exmple of a string:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;color&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;red&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The type of &lt;code&gt;color&lt;/code&gt; is &lt;code&gt;string&lt;/code&gt;. It has properties like &lt;code&gt;length&lt;/code&gt; and functions like &lt;code&gt;toUpperCase()&lt;/code&gt;. &lt;br&gt;&lt;br&gt;&lt;br&gt;
Another example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The type of &lt;code&gt;count&lt;/code&gt; is &lt;code&gt;number&lt;/code&gt;. It has properties like &lt;code&gt;toFixed()&lt;/code&gt; and functions like &lt;code&gt;toString()&lt;/code&gt;. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;And there are 2 categories of types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primitive Types: (number, string, boolean, symbol, void, undefined, null)&lt;/li&gt;
&lt;li&gt;They directly store/hold the value.&lt;/li&gt;
&lt;li&gt;If you have variable a storing number 5, its like saying you have a number 5 in your hand.&lt;/li&gt;
&lt;li&gt;Object Types: (functions, arrays, classes, objects).&lt;/li&gt;
&lt;li&gt;They store a reference to the value.&lt;/li&gt;
&lt;li&gt;They don't hold the actual data, but point to where the data is stored.&lt;/li&gt;
&lt;li&gt;If you have a variable a storing an an object called Person, its like saying you have a piece of paper in your hand that has the address where the details about that Person are stored, not the Person itself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.udemy.com/course/nestjs-the-complete-developers-guide/"&gt;NestJS: The Complete Developer's Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>typescript</category>
    </item>
    <item>
      <title>Redis Scaling with RAM</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Sat, 13 Jan 2024 21:59:33 +0000</pubDate>
      <link>https://dev.to/irakan/redis-scaling-with-ram-p4a</link>
      <guid>https://dev.to/irakan/redis-scaling-with-ram-p4a</guid>
      <description>&lt;p&gt;Ok, So I have been using Redis for a long time in many applications, for storing cache, sessions, and queues. And a question came up that I need to an answer for: Can we scale Redis? and if yes, how? &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;So, I did some research and here is what I found: &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redis is in-memory data structure store, which means it stores data in RAM.&lt;/li&gt;
&lt;li&gt;The amount of data that can be stored in Redis is limited by the amount of RAM available. The more RAM you have, the more data you can store.&lt;/li&gt;
&lt;li&gt;When Redis uses all the available RAM, it supports swapping to disk. It can help to store more data and avoid crashing, but it will cause a huge performance drop.&lt;/li&gt;
&lt;li&gt;Based on a real-world test done by Redis team. Redis can handle up to 2^32 keys (4294967296 keys). And Each key can hold a value with its own limits based on the chosen data structure. For example, a string can hold up to 512MB, a list can hold up to 2^32 elements. So, if you store 1 string in each key, you can store up to 4294967296 * 512MB = 2048000000000 MB which is roughly 2 TB of data. That's a lot of data (if you have that much RAM that is 😄).&lt;/li&gt;
&lt;li&gt;To estimate the storage capacity of Redis, you can use this formula: &lt;code&gt;Redis Storage Capacity = Total Available RAM − (Redis Metadata Overhead + OS RAM Usage)&lt;/code&gt; where &lt;code&gt;Total Available RAM&lt;/code&gt; is the total RAM available in the server, &lt;code&gt;Redis Metadata Overhead&lt;/code&gt; Redis uses some amount of RAM for its internal metadata to manage keys, values, and other data structures efficiently. &lt;code&gt;OS RAM Usage&lt;/code&gt; is the amount of RAM used by the operating system and other processes running on the server.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, how can we scale Redis? &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add more RAM to the server. 😄&lt;/li&gt;
&lt;li&gt;Its all about the RAM. The more RAM you have, the more data you can store. Its the bottleneck of Redis.&lt;/li&gt;
&lt;li&gt;When your redis server reach 2^32 keys, you can use Redis Cluster to scale it horizontally by adding more nodes to the cluster. And the load balancer will distribute the requests between the nodes.&lt;/li&gt;
&lt;li&gt;If your app is using Redis for sessions, you can use sticky sessions(in the load balancer) to make sure that all the subsequent requests from the same user will be routed to the same Redis node where the user's session is stored, otherwise the user will be logged out because the session is not found when the request is routed to a different Redis node by the load balancer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.dragonflydb.io/faq/how-much-data-can-redis-store"&gt;How Much Data Can Redis Store?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://redis.io/docs/get-started/faq/"&gt;Redis FAQ&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Notes to Self</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Thu, 11 Jan 2024 19:08:38 +0000</pubDate>
      <link>https://dev.to/irakan/notes-to-self-567i</link>
      <guid>https://dev.to/irakan/notes-to-self-567i</guid>
      <description>&lt;p&gt;These are some thoughts I have learned/read somewhere that I would like to always make them stick in my mind and I want to write them down here so I can always come back to them and remind myself of them. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ITS NOT YOU!. No matter your job or how high up you are, it's not because you're smarter, better, stronger, or hard worker than others. It's not about your connections. It's because God gave you this, and you should be always grateful for it. Don't let it get to your head, and be always humble.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;YOU ONLY HAVE CONTROL OVER YOUR ACTIONS!. You can't control your life, your thoughts, your feelings, other people, or anything else. You have 0 control over everything except your actions. Focus on what you can control.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;EVERY ONE IS REPLACEABLE!. No matter how good you are at what you do. Here is the bitter truth: You are replaceable and everyone is.&lt;br&gt;
&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;And always remmber, things can be seen from different perspectives/angles. 😄&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Firakan%2Fmy-learning-journey%2Fmain%2Fmemes%2F3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Firakan%2Fmy-learning-journey%2Fmain%2Fmemes%2F3.jpg" alt="perspective"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Data Lake Vs Data Warehouse Vs Data Mart</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Tue, 09 Jan 2024 21:15:10 +0000</pubDate>
      <link>https://dev.to/irakan/data-lake-vs-data-warehouse-vs-data-mart-1ff7</link>
      <guid>https://dev.to/irakan/data-lake-vs-data-warehouse-vs-data-mart-1ff7</guid>
      <description>&lt;p&gt;Well, data is everywhere every second of every day.As a backend developer, I used to  dodge terms related to data engineering. However, due to a recent project, I've started learning more about it.&lt;br&gt;
&lt;br&gt;&lt;br&gt;
    &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YtfhrHh4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/irakan/my-learning-journey/main/memes/2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YtfhrHh4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/irakan/my-learning-journey/main/memes/2.jpg" alt="how-docker-works" width="474" height="355"&gt;&lt;/a&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;
    So, I came across these terms: Data Lake, Data Warehouse, and Data Mart. I will break them down into simple terms that I can understand. &lt;/p&gt;

&lt;p&gt;The format will be as follows:&lt;br&gt;
    - Definition: (Definition)&lt;br&gt;
    - Characteristics: (Characteristics)&lt;br&gt;
    - Why it exists: (Why it exists)&lt;br&gt;
    - Tools: (Tools that can be used to implement it)&lt;br&gt;
&lt;br&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Data Lake:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition:&lt;/strong&gt; A huge storage space for all raw data (For example: JSON, Videos, Database dumps, etc) where everything is dumped without organization.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Characteristics&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Stores raw data without modification.&lt;/li&gt;
&lt;li&gt;Store structured, semi-structured, and unstructured data.&lt;/li&gt;
&lt;li&gt;Can be Used for the entire data lifecycle.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it exists:&lt;/strong&gt; Data is valuable nowdays and it can be used for many things. So, store it and you can use it later when you need it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools:&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Free:&lt;/em&gt; Hadoop Distributed File System (HDFS)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Paid:&lt;/em&gt; Amazon S3, Azure Data Lake Storage, Google Cloud Storage

&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Warehouse:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition:&lt;/strong&gt; An organized storage place where data is structured and cleaned.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Characteristics&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Stores data in a structured way.&lt;/li&gt;
&lt;li&gt;Requires transformed and cleaned data.&lt;/li&gt;
&lt;li&gt;Time-variant data, meaning any existing data will be archived after perid of time (Example: 1 year) and stored in the Data Lake.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it exists:&lt;/strong&gt; Since data is stored in a structured way, it can be used for reporting and analysis.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools:&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Free:&lt;/em&gt; PostgreSQL, MySQL, MariaDB (limitions: not scalable for HUGE data and not optimized for analytics purposes)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Paid:&lt;/em&gt; Amazon Redshift, Google BigQuery

&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data Mart:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Definition:&lt;/strong&gt; A subset of a Data Warehouse, with a focus on specific topics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Characteristics&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;Users don't need advanced technical knowledge.&lt;/li&gt;
&lt;li&gt;Subset of a Data Warehouse, smaller and topic-focused.&lt;/li&gt;
&lt;li&gt;Users have read-only access to specific information.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why it exists:&lt;/strong&gt; Provides users a quick and easy access to data for specific topics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools:&lt;/strong&gt; 

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Free:&lt;/em&gt; Microsoft Power BI (limited features)&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Paid:&lt;/em&gt; Microsoft Power BI, Tableau, QlikView, Looker&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.sprinkledata.com/blogs/data-lake-vs-data-warehouse-vs-data-mart"&gt;Data Lake vs Data Warehouse vs Data Mart&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>data</category>
    </item>
    <item>
      <title>How Docker containers works?</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Tue, 09 Jan 2024 16:42:28 +0000</pubDate>
      <link>https://dev.to/irakan/how-docker-containers-works-1m23</link>
      <guid>https://dev.to/irakan/how-docker-containers-works-1m23</guid>
      <description>&lt;p&gt;Have you ever wondered how Docker containers work? &lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bWd3JikA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/irakan/my-learning-journey/main/memes/1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bWd3JikA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://raw.githubusercontent.com/irakan/my-learning-journey/main/memes/1.png" alt="how-docker-works" width="800" height="784"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;First, lets make these things clear:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VMs have their own kernel, making them heavier and slower compared to Docker containers.&lt;/li&gt;
&lt;li&gt;Docker containers share the host machine's kernel, making them lightweight and faster than VMs.&lt;/li&gt;
&lt;li&gt;There are different ways to create containers, but Docker is the most popular one (example: Podman, LXC, LXD, etc).&lt;/li&gt;
&lt;li&gt;A container must follow the OCI (Open Container Initiative) standards to be considered a container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, lets see how (Docker Linux containers) works. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;They are normal Linux processes that run in an isolated environment. And they rely on the following Linux features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Namespaces: This keeps each container separate from the others. It isolates things like processes, network, user IDs, and file systems, but they still share the same basic system (kernel).&lt;/li&gt;
&lt;li&gt;Control groups (cgroups): These control and limit how much of the computer's resources (like CPU, memory, disk, and network) each container can use. It helps in managing and isolating resource usage for a group of processes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So, now what happens when you execute a command like &lt;code&gt;docker run -it ubuntu bash&lt;/code&gt;? &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker will create a new container process.&lt;/li&gt;
&lt;li&gt;a new namespace will be created for the container.&lt;/li&gt;
&lt;li&gt;a new cgroup will be created for the container.&lt;/li&gt;
&lt;li&gt;a new root filesystem will be created for the container.&lt;/li&gt;
&lt;li&gt;a new network interface will be created for the container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://iximiuz.com/en/posts/oci-containers/"&gt;What Is a Standard Container&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>What is a hypervisor?</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Mon, 08 Jan 2024 18:24:42 +0000</pubDate>
      <link>https://dev.to/irakan/what-is-a-hypervisor-541n</link>
      <guid>https://dev.to/irakan/what-is-a-hypervisor-541n</guid>
      <description>&lt;p&gt;What is a hypervisor? A hypervisor is a software that creates and runs virtual machines (VMs). It allows you to run multiple operating systems on a single physical machine and share the underlying hardware resources. It will allocate the resources (CPU, RAM, Storage, etc) to each VM. &lt;br&gt;&lt;br&gt;&lt;/p&gt;

&lt;p&gt;There are two types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Type 1: Bare Metal Hypervisor (Native Hypervisor)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; What? It directly communicates with hardware, making it efficient and secure without a middleman OS.It can allocate more resources to virtual machines than your server actually has. For instance, with 128GB of RAM and eight VMs, you can assign 24GB to each, totaling 192GB. However, VMs use only the necessary RAM for their tasks, not the full allocated amount.&lt;/li&gt;
&lt;li&gt; Who? Used by enterprises and data centers (e.g., Amazon, Google) for running multiple OS on one machine.&lt;/li&gt;
&lt;li&gt; When to Use: Large data centers or server farms for maximum performance and direct hardware access.&lt;/li&gt;
&lt;li&gt;Example: VMware ESXi, Microsoft Hyper-V.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;Type 2: Hosted Hypervisor&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What? Operates within the regular OS, less powerful but user-friendly. Type 1 hypervisors allocate resources dynamically based on VM needs, making it easier. Type 2 hypervisors use fixed allocations, so if a user assigns 8GB to a VM, it takes that amount even if not fully used. This can lead to resource issues on the host machine.&lt;/li&gt;
&lt;li&gt;Who? Used by developers and individuals for running multiple OS on one machine.&lt;/li&gt;
&lt;li&gt;When to Use: Simple setups or software development when top performance is not critical.&lt;/li&gt;
&lt;li&gt;Example: VMware Workstation, Oracle VM VirtualBox.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is a diagram that explains it better than words. 😄 &lt;br&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0JIwbfQh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Hyperviseur.svg/400px-Hyperviseur.svg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0JIwbfQh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Hyperviseur.svg/400px-Hyperviseur.svg.png" alt="Hypervisor" width="400" height="242"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/what-is/hypervisor/"&gt;What is a hypervisor?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Hypervisor#/media/File:Hyperviseur.svg"&gt;Hypervisor Diagram&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>hypervisor</category>
      <category>virtualmachine</category>
    </item>
    <item>
      <title>What does Kubernetes mean?</title>
      <dc:creator>Rakan</dc:creator>
      <pubDate>Sat, 06 Jan 2024 18:31:43 +0000</pubDate>
      <link>https://dev.to/irakan/what-does-kubernetes-mean-54db</link>
      <guid>https://dev.to/irakan/what-does-kubernetes-mean-54db</guid>
      <description>&lt;p&gt;I recently found myself lacking knowledge about Kubernetes. I have read some posts about it, and I know it's like a management tool. It's somewhat similar to Composer and NPM for managing packages, but Kubernetes is for managing Docker containers. I didn't dive into it in the past because it was not relevant to me, and to be completely honest, I was running away from it (maybe scared). Now it's time to face it. 😬&lt;/p&gt;

&lt;p&gt;As they say, knowing the name of the enemy is the first step towards winning! Today, I want to shed light on its name. Kubernetes!? For some reason, I didn't like it. It's a long word, and I always find myself struggling to pronounce it. 🤔&lt;/p&gt;

&lt;p&gt;After researching, I found that Craig McLuckie, one of the founders of the Google-based Kubernetes project, said:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We had 13 other names we couldn’t get past Google’s legal department. It was the last day, and I had to pick something. I was driving into work, and I thought, ‘Well, [the technology] is like driving a container ship. What would the helmsman be called?’ So I tried to find something exotic. I had no idea what the Greek for that was. I had to look it up.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Basically, the word "κυβερνήτης" (&lt;a href="https://en.bab.la/pronunciation/greek/%CE%BA%CF%85%CE%B2%CE%B5%CF%81%CE%BD%CE%AE%CF%84%CE%B7%CF%82"&gt;Check How to pronounce κυβερνήτης&lt;/a&gt;) is a Greek term that translates to "helmsman" or "steersman" in English.&lt;/p&gt;

&lt;p&gt;To make sure, I opened Google Translator and typed "helmsman" then translated it into Greek, which gave me "πηδαλιούχος" pronounced as "pidalioúchos." That's incorrect; it's not even close to Kubernetes's word sound. I dug deeper and found the Liddell &amp;amp; Scott Greek-to-English lexicon, published in 1909, which had these meanings: "steersman, helmsman, guide, governor" for "κυβερνήτης." on page 397, which I was looking for. &lt;/p&gt;

&lt;p&gt;Now, what does "helmsman" mean?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A helmsman or helm (sometimes driver or steersman) is a person who steers a ship, sailboat, submarine, or any other type of maritime vessel or spacecraft. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another question: Why do people mention it sometimes as K8s?&lt;/p&gt;

&lt;p&gt;"K8s" is shorthand for Kubernetes because there are 8 letters between "K" and "s" in the word "Kubernetes" making it shorter and easier to type without spelling mistakes. &lt;/p&gt;

&lt;p&gt;Now that I know the origin of "Kubernetes" I can sleep in peace. 😴&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resources:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.geekwire.com/2016/ever-come-kooky-kubernetes-name-heptio/"&gt;How did they ever come up with that kooky ‘Kubernetes’ name? Here’s the inside story
&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://archive.org/details/dli.ernet.510177/page/397"&gt;Liddell &amp;amp; Scott Greek-to-English lexicon, page:397&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/Helmsman"&gt;Helmsman Definition&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
