<?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: Balaji Sasikumar</title>
    <description>The latest articles on DEV Community by Balaji Sasikumar (@balajisasikumar).</description>
    <link>https://dev.to/balajisasikumar</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%2F210353%2Fd67cd902-cc07-43ca-9db8-d55daba9fd45.png</url>
      <title>DEV Community: Balaji Sasikumar</title>
      <link>https://dev.to/balajisasikumar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/balajisasikumar"/>
    <language>en</language>
    <item>
      <title>Autostart Minikube on Ubuntu</title>
      <dc:creator>Balaji Sasikumar</dc:creator>
      <pubDate>Wed, 05 Nov 2025 05:50:17 +0000</pubDate>
      <link>https://dev.to/balajisasikumar/autostart-minikube-on-ubuntu-3la4</link>
      <guid>https://dev.to/balajisasikumar/autostart-minikube-on-ubuntu-3la4</guid>
      <description>&lt;h2&gt;
  
  
  So You Want Minikube on Autopilot?
&lt;/h2&gt;

&lt;p&gt;Picture this: the system reboots and—bam!—Minikube is already there, ready to go. No coffee required, no &lt;code&gt;minikube start&lt;/code&gt; ritual in the morning. Pure bliss. But Linux needs to know: under whose authority shall this magic commence?&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Unmask Your Secret Identity
&lt;/h2&gt;

&lt;p&gt;Let’s get personal. Who are you? The all-powerful root, the humble johnny, or the mysterious testsms? To find out, type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;whoami&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your reply is &lt;code&gt;root&lt;/code&gt;, you’re basically a wizard. If it’s something else, that’s your user.&lt;/p&gt;

&lt;p&gt;Now for your gang affiliation (primary group):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;id&lt;/span&gt; &lt;span class="nt"&gt;-gn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most of the time, your user and group are identical—a bit like Clark Kent and Superman. Remember them! You’ll need both for the systemd spell.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Write Your Systemd Spellbook
&lt;/h2&gt;

&lt;p&gt;Open /etc/systemd/system/minikube.service, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/systemd/system/minikube.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Type this incantation (replace &lt;code&gt;test&lt;/code&gt; with your actual self—yes, you):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=Kickoff Minikube Cluster
After=docker.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/minikube start
RemainAfterExit=true
ExecStop=/usr/local/bin/minikube stop
StandardOutput=journal
User=test
Group=test

[Install]
WantedBy=multi-user.target

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script orders Minikube to start and stop as you (so it doesn’t go rogue and start the Kubernetes world domination from your grandma’s account).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Make systemd Notice You
&lt;/h2&gt;

&lt;p&gt;Like poking a sleepy cat, do this to wake up systemd to your new magical file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No, it doesn’t reboot the system. It just reads your new scribblings and mutters “OK, fine.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Flip the Startup Switch
&lt;/h2&gt;

&lt;p&gt;Tell Linux to run Minikube every time it wakes up:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;minikube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you don’t want to wait for your next power nap, you can start it right now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl start minikube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Confirm Your Spell’s Success
&lt;/h2&gt;

&lt;p&gt;Don’t trust magic blindly—check if Minikube is alive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status minikube
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see &lt;code&gt;active (running)&lt;/code&gt;, congratulations! If you see &lt;code&gt;inactive (dead)&lt;/code&gt;, it's time to check logs...or sacrifice a rubber duck.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Summary:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Discover your mysterious username and group, write your service file, reload its magic, and enable it! Welcome to hands-free Minikube on Ubuntu. Enjoy your extra five minutes of sleep—Kubernetes is already up and brewing as soon as your computer starts&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>cloud</category>
      <category>devops</category>
      <category>development</category>
    </item>
    <item>
      <title>Authentication Cheatsheet</title>
      <dc:creator>Balaji Sasikumar</dc:creator>
      <pubDate>Thu, 06 Feb 2025 04:29:22 +0000</pubDate>
      <link>https://dev.to/balajisasikumar/authentication-cheatsheet-35lp</link>
      <guid>https://dev.to/balajisasikumar/authentication-cheatsheet-35lp</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;1. OpenID Connect (OIDC)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An identity layer built on top of OAuth 2.0.&lt;/li&gt;
&lt;li&gt;Provides authentication and basic profile information.&lt;/li&gt;
&lt;li&gt;Relies on ID tokens (JWT format).&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;2. Single Sign-On (SSO)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A user logs in once to access multiple applications.&lt;/li&gt;
&lt;li&gt;Centralized authentication handled by an Identity Provider (IdP).&lt;/li&gt;
&lt;li&gt;Examples: Google SSO, Microsoft Azure AD.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;3. OAuth 2.0&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;An authorization framework (not for authentication).&lt;/li&gt;
&lt;li&gt;Grants access to resources without sharing user credentials.&lt;/li&gt;
&lt;li&gt;Uses &lt;strong&gt;access tokens&lt;/strong&gt; to secure API calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;4. Auth0&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A cloud-based Identity as a Service (IDaaS) platform.&lt;/li&gt;
&lt;li&gt;Supports OAuth 2.0, OIDC, and SAML.&lt;/li&gt;
&lt;li&gt;Provides features like user management, MFA, and social login.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;5. Identity Providers (IdP)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Services that manage user identity.&lt;/li&gt;
&lt;li&gt;Examples: Keycloak, Okta, Azure AD, Ping Identity.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;6. SAML (Security Assertion Markup Language)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;XML-based protocol for exchanging authentication data.&lt;/li&gt;
&lt;li&gt;Often used in enterprise SSO solutions.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;7. JWT (JSON Web Token)&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A compact, URL-safe token format.&lt;/li&gt;
&lt;li&gt;Contains claims (identity, permissions) encoded in three parts: header, payload, signature.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;OAuth 2.0 Flows&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Flow&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Use Case&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Key Token&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authorization Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;User-based web app authentication (most secure).&lt;/td&gt;
&lt;td&gt;1. Redirect user to authorize. &lt;br&gt; 2. Exchange authorization code for tokens.&lt;/td&gt;
&lt;td&gt;Access, Refresh, ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PKCE (Proof Key for Code Exchange)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Secure mobile/SPA variant of Authorization Code.&lt;/td&gt;
&lt;td&gt;1. Generate a code verifier &amp;amp; challenge. &lt;br&gt; 2. Send verifier in token exchange.&lt;/td&gt;
&lt;td&gt;Access, Refresh, ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Implicit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;SPAs needing quick tokens (legacy, less secure).&lt;/td&gt;
&lt;td&gt;1. Directly return tokens in the URL fragment after user consent.&lt;/td&gt;
&lt;td&gt;Access, ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Client Credentials&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Machine-to-machine communication (no user interaction).&lt;/td&gt;
&lt;td&gt;1. Application sends client ID &amp;amp; secret directly.&lt;/td&gt;
&lt;td&gt;Access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Resource Owner Password&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Direct user credentials exchange (legacy, avoid).&lt;/td&gt;
&lt;td&gt;1. Application sends user credentials to the authorization server to get tokens.&lt;/td&gt;
&lt;td&gt;Access, Refresh&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Device Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Devices without browsers (e.g., TVs, IoT).&lt;/td&gt;
&lt;td&gt;1. Show user a code &amp;amp; URL. &lt;br&gt; 2. User authorizes on another device.&lt;/td&gt;
&lt;td&gt;Access, Refresh&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;OIDC Flows&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;OIDC builds on OAuth 2.0 by adding &lt;strong&gt;ID tokens&lt;/strong&gt; for authentication.&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;Flow&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Additional Steps for OIDC&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Authorization Code&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ID token is included in the response to identify the user.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Implicit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Returns both Access &amp;amp; ID tokens directly.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Hybrid&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Returns both Authorization Code &amp;amp; ID token in the first response.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Key Tokens&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Token&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Purpose&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Format&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Expiry&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Access&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Authorize API access.&lt;/td&gt;
&lt;td&gt;JWT (OAuth 2.0 spec compliant)&lt;/td&gt;
&lt;td&gt;Short-lived (minutes).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;ID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;User authentication &amp;amp; profile claims (OIDC).&lt;/td&gt;
&lt;td&gt;JWT&lt;/td&gt;
&lt;td&gt;Short-lived (minutes).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Refresh&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Obtain new access tokens without re-authenticating.&lt;/td&gt;
&lt;td&gt;Opaque or JWT&lt;/td&gt;
&lt;td&gt;Long-lived (days/months).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Key Concepts Cheat Sheet&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Concept&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Description&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Redirect URI&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Callback URL where tokens/codes are sent after user authorization.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scopes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Permissions requested by the client application (e.g., &lt;code&gt;profile&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consent Screen&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;UI presented to users to approve access scopes requested by the app.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PKCE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Adds a layer of security to prevent interception of authorization codes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Well-Known URL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Discovery endpoint (&lt;code&gt;/.well-known/openid-configuration&lt;/code&gt;) for fetching IdP metadata.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MFA&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Multi-factor authentication for added security (e.g., SMS, authenticator apps).&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Quick Decision Guide&lt;/strong&gt;
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Flow to Use&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Secure user authentication (web app)&lt;/td&gt;
&lt;td&gt;Authorization Code + PKCE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SPA with no backend&lt;/td&gt;
&lt;td&gt;PKCE (replaces Implicit flow)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Machine-to-machine API access&lt;/td&gt;
&lt;td&gt;Client Credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Devices without browsers&lt;/td&gt;
&lt;td&gt;Device Code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Avoid (legacy, insecure, or risky scenarios)&lt;/td&gt;
&lt;td&gt;Implicit, Resource Owner Password&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Comparison of Access Control Models
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Context-Based Access Control (CBAC)&lt;/th&gt;
&lt;th&gt;Role-Based Access Control (RBAC)&lt;/th&gt;
&lt;th&gt;Fine-Grained Access Control (FGAC)&lt;/th&gt;
&lt;th&gt;Discretionary Access Control (DAC)&lt;/th&gt;
&lt;th&gt;Mandatory Access Control (MAC)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Decision Basis&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Real-time contextual attributes like time, location, device, and user behavior.&lt;/td&gt;
&lt;td&gt;Predefined roles and associated permissions.&lt;/td&gt;
&lt;td&gt;Highly detailed policies based on specific attributes.&lt;/td&gt;
&lt;td&gt;Owner or creator defines access permissions.&lt;/td&gt;
&lt;td&gt;Central authority enforces access based on labels.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Flexibility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Highly flexible and adapts to environmental changes.&lt;/td&gt;
&lt;td&gt;Limited to static or hierarchical roles.&lt;/td&gt;
&lt;td&gt;Extremely flexible; designed for complex needs.&lt;/td&gt;
&lt;td&gt;Flexible but depends on owner decisions.&lt;/td&gt;
&lt;td&gt;Rigid and predefined, based on strict rules.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Granularity&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Medium to High: Uses multiple contextual factors.&lt;/td&gt;
&lt;td&gt;Medium: Permissions tied to roles, not specific attributes.&lt;/td&gt;
&lt;td&gt;Very High: Can specify access at a granular level.&lt;/td&gt;
&lt;td&gt;Low to Medium: Based on owner's definition.&lt;/td&gt;
&lt;td&gt;High: Broad classification levels control access.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Adaptability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High: Evaluates access dynamically based on real-time context.&lt;/td&gt;
&lt;td&gt;Low: Static, predefined roles rarely change dynamically.&lt;/td&gt;
&lt;td&gt;High: Highly customizable for complex needs.&lt;/td&gt;
&lt;td&gt;Medium: Relies on owner's decisions.&lt;/td&gt;
&lt;td&gt;Low: Cannot adapt dynamically.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Security&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Very High: Mitigates risks with dynamic evaluation.&lt;/td&gt;
&lt;td&gt;Medium: Static roles can lead to privilege creep.&lt;/td&gt;
&lt;td&gt;Very High: Fine-grained policies reduce over-permissioning.&lt;/td&gt;
&lt;td&gt;Medium: Risks due to inconsistent permissions.&lt;/td&gt;
&lt;td&gt;Very High: Strict rules prevent unauthorized access.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Ease of Implementation&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Medium: Requires infrastructure for monitoring context.&lt;/td&gt;
&lt;td&gt;Easy: Widely supported and simple to implement.&lt;/td&gt;
&lt;td&gt;Complex: Requires detailed policy definitions.&lt;/td&gt;
&lt;td&gt;Easy: Straightforward implementation.&lt;/td&gt;
&lt;td&gt;Difficult: Strict classification and enforcement.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Scalability&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;High: Scales well in dynamic environments.&lt;/td&gt;
&lt;td&gt;High: Scales well with role hierarchies.&lt;/td&gt;
&lt;td&gt;High: Suitable for large systems with diverse requirements.&lt;/td&gt;
&lt;td&gt;Low: Limited to individual owners.&lt;/td&gt;
&lt;td&gt;Low: Difficult to scale due to rigid structure.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Use Cases&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;- Remote work environments.&lt;/td&gt;
&lt;td&gt;- Enterprise applications.&lt;/td&gt;
&lt;td&gt;- Multi-tenant systems.&lt;/td&gt;
&lt;td&gt;- Small teams or personal systems.&lt;/td&gt;
&lt;td&gt;- Military and government systems.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;- Banking transactions.&lt;/td&gt;
&lt;td&gt;- Basic organizational hierarchies.&lt;/td&gt;
&lt;td&gt;- Healthcare and finance.&lt;/td&gt;
&lt;td&gt;- File-sharing applications.&lt;/td&gt;
&lt;td&gt;- Classified data protection.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;- Zero Trust security models.&lt;/td&gt;
&lt;td&gt;- Traditional IT.&lt;/td&gt;
&lt;td&gt;- GDPR-compliant systems.&lt;/td&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;h2&gt;
  
  
  Which Model to Use?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Recommended Model&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Flexible, real-time access control needed&lt;/td&gt;
&lt;td&gt;CBAC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structured, role-based organizations&lt;/td&gt;
&lt;td&gt;RBAC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;High compliance and precision requirements&lt;/td&gt;
&lt;td&gt;FGAC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Small-scale or personal systems&lt;/td&gt;
&lt;td&gt;DAC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Military or highly sensitive environments&lt;/td&gt;
&lt;td&gt;MAC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>computerscience</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>APIs: How to Stop Torturing Developers and Start Writing Code They Won't Hate</title>
      <dc:creator>Balaji Sasikumar</dc:creator>
      <pubDate>Mon, 30 Dec 2024 17:39:48 +0000</pubDate>
      <link>https://dev.to/balajisasikumar/apis-how-to-stop-torturing-developers-and-start-writing-code-they-wont-hate-3jjj</link>
      <guid>https://dev.to/balajisasikumar/apis-how-to-stop-torturing-developers-and-start-writing-code-they-wont-hate-3jjj</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Ah, APIs—the love letters developers write to each other (sometimes in a cryptic language no one can understand). Whether you're crafting an elegant symphony of methods or unleashing a monstrosity of unreadable spaghetti code, this guide will help you design APIs that won't make your colleagues cry (or, at least, cry less). Let’s dive in!&lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Characteristics of Good APIs&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Easy to Learn and Memorize&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A good API should be so simple even your grandma could use it. If your API feels like it requires a PhD in rocket science, you’re doing it wrong. Let's say you're building a calculator API.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad API Example&lt;/strong&gt;:&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="nf"&gt;calculate&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plus&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;round&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;basic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;verbosity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;low&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;"Uh, what? Why do I need to know the verbosity of a basic addition?"  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good API Example&lt;/strong&gt;:&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="nx"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Ah, so simple even my pet goldfish gets it!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  2. &lt;strong&gt;Leads to Readable Code&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Readable APIs are the ones you can skim through without questioning your life choices.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sarcastic Scenario&lt;/strong&gt;: Imagine you’re debugging at 2 AM with coffee in one hand and despair in the other. Which code would you prefer?  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad API Example&lt;/strong&gt;:&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;const&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;A&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nc"&gt;B&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nc"&gt;C&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  
&lt;span class="c1"&gt;// What is A? What is B? Are we building a spaceship or solving math?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Good API Example&lt;/strong&gt;:&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;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;multiply&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getResult&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;  
&lt;span class="c1"&gt;// Ah, now I know what I’m doing. I'm multiplying happiness.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  3. &lt;strong&gt;Hard to Misuse&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;An API that’s easy to misuse is like a vending machine that eats your money. Let’s protect developers from themselves.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad API Example&lt;/strong&gt;:&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="nx"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apple&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="s2"&gt;banana&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Hmm, should this work? It does. But why?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Good API Example&lt;/strong&gt;:&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="nx"&gt;calculator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Only numbers allowed, sorry fruit enthusiasts.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And, of course, throw an error that screams:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Invalid argument type: We accept numbers, not your grocery list!"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;The Design Process&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4. &lt;strong&gt;Know the Requirements&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Before you write any code, ask yourself:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What do users need?
&lt;/li&gt;
&lt;li&gt;What do they &lt;em&gt;actually&lt;/em&gt; need (not what they say they need)?
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;: If users need a &lt;code&gt;Todo API&lt;/code&gt;, don’t build a rocket launcher API. Stay focused.  &lt;/p&gt;




&lt;h3&gt;
  
  
  5. &lt;strong&gt;Write Use Cases First&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ever tried assembling IKEA furniture without instructions? Writing code without use cases is kind of like that, but worse.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use Case&lt;/strong&gt;:&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="c1"&gt;// BEFORE implementation:&lt;/span&gt;
&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Write blog&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;completeTask&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="nf"&gt;deleteTask&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, build the API to match this. No extra fluff, no over-engineering.  &lt;/p&gt;




&lt;h3&gt;
  
  
  6. &lt;strong&gt;Prepare for Extensions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Don’t create a rigid API that breaks the moment someone wants to add a feature.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example of Extensible API&lt;/strong&gt;:&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;interface&lt;/span&gt; &lt;span class="nx"&gt;Calculator&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="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="nx"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;subtract&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="nx"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nf"&gt;withOptions&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;span class="nl"&gt;precision&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="nl"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;basic&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;scientific&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}):&lt;/span&gt; &lt;span class="nx"&gt;Calculator&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  7. &lt;strong&gt;When in Doubt, Leave It Out&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Developers love adding features like it’s a toppings bar. But sometimes, the best topping is nothing.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Sarcastic Example&lt;/strong&gt;:&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="c1"&gt;// Bad API with unnecessary features:&lt;/span&gt;
&lt;span class="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Cook dinner&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;priority&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;urgent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;notifyVia&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;pigeon&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;withEmojis&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Really? Emojis and pigeon notifications? Calm down.  &lt;/p&gt;




&lt;h2&gt;
  
  
  &lt;strong&gt;Design Guidelines&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8. &lt;strong&gt;Choose Self-Explanatory Names&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your API should be so clear even a 5-year-old could explain it.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad Example&lt;/strong&gt;:&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="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;api&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xyz&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// What is this sorcery?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Good Example&lt;/strong&gt;:&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="nx"&gt;todo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Learn TypeScript&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;completeTask&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See? Clear, concise, and makes you look smart.  &lt;/p&gt;




&lt;h3&gt;
  
  
  9. &lt;strong&gt;Avoid Abbreviations&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Abbreviations are for Twitter, not APIs.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bad Example&lt;/strong&gt;:&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="nx"&gt;usrMgmt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addUsr&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;Is this a typo or code?  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Good Example&lt;/strong&gt;:&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="nx"&gt;userManagement&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addUser&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;h3&gt;
  
  
  10. &lt;strong&gt;The Best API is No API&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Sometimes, simplicity means not writing an API at all. Can you solve the problem without it? If yes, do that instead.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;:&lt;br&gt;&lt;br&gt;
Instead of a custom &lt;code&gt;fetchData&lt;/code&gt; API, just use:&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="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://example.com/data&lt;/span&gt;&lt;span class="dl"&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="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="nx"&gt;res&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>api</category>
      <category>webdev</category>
      <category>node</category>
      <category>programming</category>
    </item>
    <item>
      <title>🎨 Mastering Angular-React Integration: How to Use tldraw Without Losing Your Mind!</title>
      <dc:creator>Balaji Sasikumar</dc:creator>
      <pubDate>Sun, 01 Dec 2024 12:26:53 +0000</pubDate>
      <link>https://dev.to/balajisasikumar/integrating-tldraw-react-component-in-an-angular-app-without-losing-your-mind-21i1</link>
      <guid>https://dev.to/balajisasikumar/integrating-tldraw-react-component-in-an-angular-app-without-losing-your-mind-21i1</guid>
      <description>&lt;h3&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If you’re an Angular dev eyeing the React world, you might feel like a cat walking into a dog park. &lt;code&gt;tldraw&lt;/code&gt;—the cool kid on the React block—makes it seem worth the risk. But how do you get them to play nicely together? By using &lt;strong&gt;web components&lt;/strong&gt;, the ultimate middleman that lets Angular and React shake hands instead of throwing shade. 🚀&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;What are Web Components?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Imagine a magical HTML element that doesn’t care who made it—it just works. That’s a &lt;strong&gt;web component&lt;/strong&gt; for you! It's like the Switzerland of the web frameworks, neutral and ready to mediate.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Key Features:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Custom Elements:&lt;/strong&gt; Make up your own tags like &lt;code&gt;&amp;lt;awesome-button&amp;gt;&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Shadow DOM:&lt;/strong&gt; Keeps your styles from messing with everyone else’s (no sibling drama here!).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTML Templates:&lt;/strong&gt; Build it once, reuse it everywhere (yes, like Legos).&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;What is r2wc?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Think of &lt;a href="https://www.npmjs.com/package/@r2wc/react-to-web-component" rel="noopener noreferrer"&gt;&lt;code&gt;r2wc&lt;/code&gt;&lt;/a&gt; as the translator between React and the rest of the web. It wraps your React components in a cozy custom element that even Angular can understand. 😎&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;How it Works:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Take your React component. 🧑‍🎨&lt;/li&gt;
&lt;li&gt;Wrap it with &lt;code&gt;r2wc&lt;/code&gt;. 🛁&lt;/li&gt;
&lt;li&gt;Register it as a custom element with a snazzy name like &lt;code&gt;&amp;lt;tl-draw&amp;gt;&lt;/code&gt;. 🏷️&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Step-by-Step Guide&lt;/strong&gt;
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Step 1: Install the Required Stuff&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Get the cool toys with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @r2wc/react-to-web-component @tldraw/tldraw react react-dom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  &lt;strong&gt;Step 2: Let Angular Know About Web Components&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Add this to your Angular module, so Angular doesn’t freak out about your new custom elements:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CUSTOM_ELEMENTS_SCHEMA&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&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="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;declarations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;BrowserModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;schemas&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;CUSTOM_ELEMENTS_SCHEMA&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Step 3: Add tldraw Styles
&lt;/h4&gt;

&lt;p&gt;You can’t draw without style, right? Add &lt;code&gt;tldraw&lt;/code&gt;'s styles to your Angular app.&lt;/p&gt;

&lt;p&gt;Open &lt;code&gt;angular.json&lt;/code&gt; and include the following in the styles array:&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="nl"&gt;"styles"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"src/global.scss"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="s2"&gt;"node_modules/tldraw/tldraw.css"&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;h4&gt;
  
  
  Step 4: Importing tldraw Based on Angular Version
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;For Angular 15 and Above&lt;/strong&gt;:
&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;r2wc&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@r2wc/react-to-web-component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tldraw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tldraw/tldraw&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;ul&gt;
&lt;li&gt;
&lt;strong&gt;For Angular Below 15&lt;/strong&gt;:
&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;r2wc&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../node_modules/@r2wc/react-to-web-component/dist/react-to-web-component.js&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tldraw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../../node_modules/tldraw/dist-esm/index.mjs&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;Because Angular’s TypeScript isn’t quite ready to hang with tldraw. 🙃. This workaround is necessary because tldraw uses TypeScript features that older Angular versions don’t fully support.&lt;/p&gt;




&lt;h4&gt;
  
  
  Step 5: Create tldraw.js
&lt;/h4&gt;

&lt;p&gt;Create a file named &lt;code&gt;tldraw.js&lt;/code&gt; to convert the &lt;code&gt;tldraw&lt;/code&gt; React component into a web component.&lt;/p&gt;

&lt;p&gt;Here’s the magic potion that converts tldraw into a web component:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;r2wc&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@r2wc/react-to-web-component&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Tldraw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@tldraw/tldraw&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;TldrawComponent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;r2wc&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Tldraw&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;props&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;forceMobile&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;boolean&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;onMount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function&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;customElements&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;tl-draw&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;TldrawComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This wraps the tldraw component and defines it as a custom element named .&lt;/p&gt;




&lt;h3&gt;
  
  
  Step 6: Use the Web Component in Angular
&lt;/h3&gt;

&lt;p&gt;Here’s how you can use &lt;code&gt;&amp;lt;tl-draw&amp;gt;&lt;/code&gt; in your Angular app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTML (&lt;code&gt;app.component.html&lt;/code&gt;):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;style=&lt;/span&gt;&lt;span class="s"&gt;"width: 100vw; height: 95vh"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt;
    &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"handleSaveChanges()"&lt;/span&gt;
    &lt;span class="na"&gt;[ngStyle]=&lt;/span&gt;&lt;span class="s"&gt;"{
      position: 'absolute',
      top: '44px',
      right: '0.5em',
      padding: '8px 16px',
      zIndex: 100,
      backgroundColor: hasUnsavedChanges ? '#007bff' : '#ccc',
      cursor: hasUnsavedChanges ? 'pointer' : 'not-allowed',
      opacity: hasUnsavedChanges ? 1 : 0.6
    }"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    Save
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;tl-draw&lt;/span&gt;
    &lt;span class="na"&gt;[forceMobile]=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
    &lt;span class="na"&gt;[snapshot]=&lt;/span&gt;&lt;span class="s"&gt;"snapshot"&lt;/span&gt;
    &lt;span class="na"&gt;[onMount]=&lt;/span&gt;&lt;span class="s"&gt;"onMountEvent"&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;gt;&amp;lt;/tl-draw&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;TypeScript (app.component.ts):&lt;/strong&gt;&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;getSnapshot1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./path-to-tldraw.js&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="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&lt;/span&gt;&lt;span class="p"&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;./app.component.scss&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;hasUnsavedChanges&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="nl"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;onMountEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handleChangeEvent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;all&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;handleChangeEvent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;added&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
      &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;updated&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt;
      &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;removed&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="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasUnsavedChanges&lt;/span&gt; &lt;span class="o"&gt;=&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="p"&gt;};&lt;/span&gt;

  &lt;span class="nx"&gt;handleSaveChanges&lt;/span&gt; &lt;span class="o"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;snapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getSnapshot1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;store&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;Snapshot saved:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;snapshot&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hasUnsavedChanges&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="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;drawingSnapshot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&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;snapshot&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="nf"&gt;ngOnInit&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;savedSnapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;localStorage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getItem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;drawingSnapshot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;snapshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;savedSnapshot&lt;/span&gt; &lt;span class="p"&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;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;savedSnapshot&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="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;Now, you’re all set to use tldraw in your Angular app! 🎉&lt;/p&gt;




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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Props Mapping:&lt;/strong&gt; React props become Angular-friendly attributes via &lt;code&gt;r2wc&lt;/code&gt;. For example:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;tl-draw&lt;/span&gt;
    &lt;span class="na"&gt;[forceMobile]=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
    &lt;span class="na"&gt;[snapshot]=&lt;/span&gt;&lt;span class="s"&gt;"snapshot"&lt;/span&gt;
    &lt;span class="na"&gt;[onMount]=&lt;/span&gt;&lt;span class="s"&gt;"onMountEvent"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/tl-draw&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Event Handling:&lt;/strong&gt; Use Angular bindings to handle events like [onMount]="onMountEvent".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Snapshots FTW:&lt;/strong&gt; Save and restore drawing state using getSnapshot.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You’ve successfully bridged the React-Angular divide! 🎉&lt;/p&gt;




&lt;h3&gt;
  
  
  Common Gotchas
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;TypeScript Compatibility:&lt;/strong&gt; If you see errors, try downgrading TypeScript to a compatible version.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Missing Styles:&lt;/strong&gt; If your canvas looks broken, check &lt;code&gt;angular.json&lt;/code&gt; to ensure &lt;code&gt;tldraw.css&lt;/code&gt; is added to the styles array.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Prop Mismatches:&lt;/strong&gt; Double-check the &lt;code&gt;props&lt;/code&gt; object in &lt;code&gt;tldraw.js&lt;/code&gt; to make sure attributes like &lt;code&gt;forceMobile&lt;/code&gt; are correctly exposed.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;By the time you’re done, your Angular app will be flexing tldraw like it was born to do it. Who said React and Angular can’t get along? With a little help from &lt;code&gt;r2wc&lt;/code&gt;, you’ve just made it happen. Go on, give yourself a high five! 🖐️🎉&lt;/p&gt;

</description>
      <category>react</category>
      <category>angular</category>
      <category>webdev</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Inside SQL Joins</title>
      <dc:creator>Balaji Sasikumar</dc:creator>
      <pubDate>Wed, 15 May 2024 18:19:17 +0000</pubDate>
      <link>https://dev.to/balajisasikumar/inside-sql-joins-5h6b</link>
      <guid>https://dev.to/balajisasikumar/inside-sql-joins-5h6b</guid>
      <description>&lt;p&gt;SQL joins are fundamental to querying databases, allowing users to combine data from multiple tables based on specified conditions. Joins are categorized into two main types: &lt;code&gt;logical joins&lt;/code&gt; and &lt;code&gt;physical joins&lt;/code&gt;. Logical joins represent the conceptual way in which data from tables is combined, while physical joins refer to the actual implementation of these joins within database systems like RDS (Relational Database Service) or other SQL servers. In today's blog post, we'll unravel the mysteries of SQL joins.&lt;/p&gt;

&lt;p&gt;Let's jump in! &lt;/p&gt;

&lt;h2&gt;
  
  
  Logical Join
&lt;/h2&gt;

&lt;p&gt;There are various types of logical joins in SQL. The two most common are Inner join and Outer join. We use these joins when we need to retrieve data from tables.&lt;/p&gt;

&lt;h2&gt;
  
  
  Physical Join
&lt;/h2&gt;

&lt;p&gt;Physical joins are implemented inside RDS. The user writes the query using a logical join and RDS uses a physical join to perform the join operations. There are different types of physical joins like&lt;br&gt;
    1. Nested Loop Join&lt;br&gt;
    2. Hash Join&lt;br&gt;
    3. Merge Join  and so on&lt;/p&gt;
&lt;h3&gt;
  
  
  Nested Loop Join
&lt;/h3&gt;

&lt;p&gt;This is a type of join where a smaller table with fewer records is selected and looped through the other table until a match is found. This type of join is available in MySQL, Postgres, and even SQL servers. However, it is not a scalable option for large tables. It is mainly used in cases where the join operator does not use equality.&lt;/p&gt;

&lt;p&gt;For example,&lt;code&gt;Geospatial Queries&lt;/code&gt;: When dealing with geographic data, you might want to find points within a certain distance of other points. This could involve comparing the distance between every combination of points, which could be achieved with a Nested Loop Join.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM cities
JOIN landmarks ON distance(cities.location, landmarks.location) &amp;lt; 100;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hash Join
&lt;/h3&gt;

&lt;p&gt;Hash join is a method of executing a join using the hash table to find a match record. A hash table is created in memory. If there is a large amount of data and there is not enough memory to store it, then it is written to disk. Hash join is more efficient than Nested Loop join. During execution, RDS builds the in-memory hash table where the rows from the join table are stored using the join attribute as the key. After the execution, the server starts reading the rows from the other table and finds the corresponding row from hash table. This method is commonly used when the join operator uses equality.&lt;/p&gt;

&lt;p&gt;Suppose you have an "Employee" table with employee details like ID, name, and department ID, and a "Department" table with department details like ID and name. You want to join these tables to get the department each employee belongs to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM Employee
JOIN Department ON Employee.department_id = Department.department_id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example the join condition is based on &lt;code&gt;equality&lt;/code&gt; between columns, making it suitable for a hash join. This method is efficient, especially when dealing with large datasets, as it can quickly match records using the hash table. However, as with any join method, it's important to consider the size of the datasets and available memory to ensure optimal performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Merge Join
&lt;/h3&gt;

&lt;p&gt;Merge Join is a method used in SQL query execution when the join condition employs an &lt;code&gt;equality operator&lt;/code&gt; and both sides of the join are &lt;code&gt;large&lt;/code&gt;. This technique relies on &lt;code&gt;sorted data inputs&lt;/code&gt;. If there exists an &lt;code&gt;index&lt;/code&gt; on the expressions used in the join column, it can be utilized to obtain the sorted data efficiently. However, if the server needs to sort the data explicitly, it's crucial to analyze the indexes and consider optimizing them for improved performance.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
Consider a scenario involving a "Sales" table with sales transactions, including sale ID, customer ID, and sale amount, and a "Customers" table containing customer details like customer ID, name, and location.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM Sales
JOIN Customers ON Sales.customer_id = Customers.customer_id;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case, both the "Sales" and "Customers" tables are substantial, and the join condition relies on the equality of the "customer_id" column. For an efficient merge join, both input tables need to be sorted by the join column ("customer_id"). If there's no existing index on the "customer_id" column, the server may need to perform additional sorting operations, which could impact performance.&lt;/p&gt;

&lt;p&gt;To optimize the merge join, it's advisable to create or modify indexes on the "customer_id" column in both tables. Ensuring proper maintenance and optimization of these indexes can lead to significant improvements in query performance, particularly for queries frequently involving joins based on the "customer_id" column.&lt;/p&gt;

&lt;p&gt;By leveraging indexes effectively and ensuring sorted data inputs, merge joins can efficiently handle joins between large tables with equality-based join conditions, contributing to enhanced query performance and overall system efficiency.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Aspect&lt;/th&gt;
&lt;th&gt;Nested Loop Join&lt;/th&gt;
&lt;th&gt;Hash Join&lt;/th&gt;
&lt;th&gt;Merge Join&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Join Condition&lt;/td&gt;
&lt;td&gt;Non-equality&lt;/td&gt;
&lt;td&gt;Equality&lt;/td&gt;
&lt;td&gt;Equality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input Data Size&lt;/td&gt;
&lt;td&gt;Small to Medium&lt;/td&gt;
&lt;td&gt;Medium to Large&lt;/td&gt;
&lt;td&gt;Large&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Data Sorting&lt;/td&gt;
&lt;td&gt;Not required&lt;/td&gt;
&lt;td&gt;Not required&lt;/td&gt;
&lt;td&gt;Required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory Usage&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Moderate to High&lt;/td&gt;
&lt;td&gt;Moderate to High&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Index Utilization&lt;/td&gt;
&lt;td&gt;Not a primary concern&lt;/td&gt;
&lt;td&gt;Beneficial&lt;/td&gt;
&lt;td&gt;Relies on indexes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance(large datasets)&lt;/td&gt;
&lt;td&gt;Slower&lt;/td&gt;
&lt;td&gt;Efficient&lt;/td&gt;
&lt;td&gt;Efficient&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scalability&lt;/td&gt;
&lt;td&gt;Less scalable&lt;/td&gt;
&lt;td&gt;Scalable&lt;/td&gt;
&lt;td&gt;Scalable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Typical Use Cases&lt;/td&gt;
&lt;td&gt;Small to medium-sized tables&lt;/td&gt;
&lt;td&gt;Large tables with equality joins&lt;/td&gt;
&lt;td&gt;Large tables with equality joins&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

</description>
      <category>sql</category>
      <category>database</category>
      <category>mysql</category>
      <category>development</category>
    </item>
  </channel>
</rss>
