<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Supercharged Dev]]></title><description><![CDATA[Software developer]]></description><link>https://blog.supercharged.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1616143618312/IZyH60o0g.png</url><title>Supercharged Dev</title><link>https://blog.supercharged.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Tue, 14 Apr 2026 05:12:35 GMT</lastBuildDate><atom:link href="https://blog.supercharged.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Solving the AWS CloudFront Cross-Region Certificate Puzzle with CDK]]></title><description><![CDATA[The Problem That Makes Developers Pull Their Hair Out
When you design infrastructure across multiple AWS regions, you expect each region to be self-contained — its own EKS clusters, databases, Lambdas, and certificates — all neatly separated by regio...]]></description><link>https://blog.supercharged.dev/solving-the-aws-cloudfront-cross-region-certificate-puzzle-with-cdk</link><guid isPermaLink="true">https://blog.supercharged.dev/solving-the-aws-cloudfront-cross-region-certificate-puzzle-with-cdk</guid><category><![CDATA[AWS]]></category><category><![CDATA[aws-cdk]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Mon, 27 Oct 2025 21:57:17 GMT</pubDate><content:encoded><![CDATA[<h2 id="heading-the-problem-that-makes-developers-pull-their-hair-out">The Problem That Makes Developers Pull Their Hair Out</h2>
<p>When you design infrastructure across multiple AWS regions, you expect each region to be self-contained — its own EKS clusters, databases, Lambdas, and certificates — all neatly separated by region.</p>
<p>That’s how my CDK setup was built: a clean, modular design that could deploy the same infrastructure stack in any region (ap-southeast-2, ap-south-1, etc.) just by switching configuration.</p>
<p>Everything worked perfectly… until CloudFront entered the picture.</p>
<p>The moment I added CloudFront for my frontend, deployments started failing with confusing certificate errors like:</p>
<pre><code class="lang-plaintext">Error: Certificate for alternate domain name is not issued by AWS Certificate Manager
</code></pre>
<p>Or worse:</p>
<pre><code class="lang-plaintext">The certificate that is attached to your distribution doesn't cover the alternate domain name
</code></pre>
<p>After debugging, I realized the issue wasn’t with my setup at all — it was an AWS constraint hiding in plain sight:</p>
<p><strong>CloudFront requires SSL certificates to be created in us-east-1, no matter where your infrastructure lives.</strong></p>
<p>That single requirement completely broke my otherwise predictable, region-specific deployment model. This post walks through how I solved it — a clean, battle-tested pattern to handle CloudFront’s cross-region certificate constraint using AWS CDK, without messy hacks or manual intervention.</p>
<h2 id="heading-problem-1-the-hidden-us-east-1-certificate-requirement">Problem 1: The Hidden us-east-1 Certificate Requirement</h2>
<h3 id="heading-the-problem">The Problem</h3>
<p>AWS CloudFront is a global service, but it has a peculiar requirement: SSL/TLS certificates used with CloudFront distributions <strong>must</strong> be created in the <code>us-east-1</code> region. This isn't clearly stated in error messages, and developers often waste hours trying to debug certificate validation issues.</p>
<p><strong>Common symptoms:</strong></p>
<ul>
<li><p>Certificate validation succeeds in your primary region but CloudFront still fails</p>
</li>
<li><p>"Certificate not found" errors despite the certificate existing</p>
</li>
<li><p>CloudFormation rollbacks with cryptic certificate-related errors</p>
</li>
</ul>
<h3 id="heading-the-solution">The Solution</h3>
<p>Create a dedicated stack for us-east-1 resources that extends your domain stack:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/stacks/domain/us-east1-domain.stack.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> USEast1DomainStack <span class="hljs-keyword">extends</span> DomainStack {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">scope: Construct, id: <span class="hljs-built_in">string</span>, props: IStackProps</span>) {
    <span class="hljs-built_in">super</span>(scope, id, {
      ...props,
      description: <span class="hljs-string">'Stack to create domain resources in us-east-1'</span>,
    }, <span class="hljs-literal">true</span>);

    <span class="hljs-comment">// Enforce us-east-1 deployment</span>
    <span class="hljs-keyword">if</span> (props.env?.region !== <span class="hljs-string">'us-east-1'</span> ||
        props.config.region !== <span class="hljs-string">'us-east-1'</span>) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">'This stack must be deployed in us-east-1 region'</span>);
    }

    <span class="hljs-comment">// Create wildcard certificate for CloudFront</span>
    <span class="hljs-built_in">this</span>.createWildcardCertificate();
    <span class="hljs-built_in">this</span>.createWebAppReviewCertificates();
  }
}
</code></pre>
<p><strong>Why this works:</strong> By explicitly creating a separate stack for us-east-1 resources, you maintain clean separation of concerns while ensuring certificates are in the correct region.</p>
<h2 id="heading-problem-2-cross-region-reference-failures">Problem 2: Cross-Region Reference Failures</h2>
<h3 id="heading-the-problem-1">The Problem</h3>
<p>When your main infrastructure is in <code>ap-southeast-2</code> but certificates are in <code>us-east-1</code>, CDK throws errors:</p>
<pre><code class="lang-plaintext">Error: Stack "FrontendStack" cannot reference "USEast1DomainStack" across regions without crossRegionReferences enabled
</code></pre>
<p>Even worse, CloudFormation exports don't automatically work across regions, leading to deployment failures.</p>
<h3 id="heading-the-solution-1">The Solution</h3>
<p>Enable cross-region references when creating the us-east-1 stack:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/stages/microservices-platform.stage.ts</span>
<span class="hljs-keyword">const</span> usEast1DomainStack = <span class="hljs-keyword">new</span> USEast1DomainStack(
  <span class="hljs-built_in">this</span>,
  <span class="hljs-string">'USEast1DomainStack'</span>,
  {
    ...props,
    env: {
      ...props.env,
      region: <span class="hljs-string">'us-east-1'</span>,  <span class="hljs-comment">// Override region</span>
    },
    config: {
      ...props.config,
      region: <span class="hljs-string">'us-east-1'</span>,  <span class="hljs-comment">// Update config region too</span>
    },
    crossRegionReferences: <span class="hljs-literal">true</span>,  <span class="hljs-comment">// Critical!</span>
  },
);

<span class="hljs-comment">// Frontend stack can now reference us-east-1 certificates</span>
<span class="hljs-keyword">const</span> frontendStack = <span class="hljs-keyword">new</span> FrontendStack(<span class="hljs-built_in">this</span>, <span class="hljs-string">'FrontendStack'</span>, {
  ...props,
  domainStack: usEast1DomainStack,  <span class="hljs-comment">// Pass the us-east-1 stack</span>
  crossRegionReferences: <span class="hljs-literal">true</span>,
});
</code></pre>
<p><strong>Why this works:</strong> The <code>crossRegionReferences</code> flag tells CDK to use AWS Systems Manager Parameter Store to share values between regions, working around CloudFormation's regional limitations.</p>
<h2 id="heading-problem-3-stack-dependency-and-deployment-order">Problem 3: Stack Dependency and Deployment Order</h2>
<h3 id="heading-the-problem-2">The Problem</h3>
<p>Complex dependency chains emerge when you have:</p>
<ul>
<li><p>A domain stack in your primary region (for Route53)</p>
</li>
<li><p>A us-east-1 domain stack (for certificates)</p>
</li>
<li><p>Frontend stacks that need both</p>
</li>
</ul>
<p>Incorrect dependency setup leads to:</p>
<ul>
<li><p>Circular dependency errors</p>
</li>
<li><p>Resources created in wrong order</p>
</li>
<li><p>"Export already exists" conflicts</p>
</li>
</ul>
<h3 id="heading-the-solution-2">The Solution</h3>
<p>Implement intelligent dependency management:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Conditional domain stack creation based on region</span>
<span class="hljs-keyword">let</span> domainStack: DomainStack | <span class="hljs-literal">undefined</span> = <span class="hljs-literal">undefined</span>;

<span class="hljs-keyword">if</span> (<span class="hljs-built_in">this</span>.config.region !== <span class="hljs-string">'us-east-1'</span>) {
  domainStack = <span class="hljs-keyword">new</span> DomainStack(<span class="hljs-built_in">this</span>, <span class="hljs-string">'DomainStack'</span>, props, <span class="hljs-literal">true</span>);
}

<span class="hljs-keyword">const</span> usEast1DomainStack = <span class="hljs-keyword">new</span> USEast1DomainStack(
  <span class="hljs-built_in">this</span>,
  <span class="hljs-string">'USEast1DomainStack'</span>,
  { <span class="hljs-comment">/* ... */</span> }
);

<span class="hljs-comment">// Set up dependency chain</span>
<span class="hljs-keyword">if</span> (domainStack) {
  usEast1DomainStack.addDependency(domainStack);
} <span class="hljs-keyword">else</span> {
  domainStack = usEast1DomainStack;  <span class="hljs-comment">// us-east-1 IS the domain stack</span>
}

<span class="hljs-comment">// Frontend depends on us-east-1 stack for certificates</span>
<span class="hljs-keyword">const</span> frontendStack = <span class="hljs-keyword">new</span> FrontendStack(<span class="hljs-built_in">this</span>, <span class="hljs-string">'FrontendStack'</span>, {
  ...props,
  domainStack: usEast1DomainStack,
  crossRegionReferences: <span class="hljs-literal">true</span>,
});

frontendStack.addDependency(usEast1DomainStack);
</code></pre>
<p><strong>Why this works:</strong> This pattern ensures:</p>
<ol>
<li><p>Route53 hosted zone is created first (if needed)</p>
</li>
<li><p>Certificates are created in us-east-1 with DNS validation</p>
</li>
<li><p>Frontend resources wait for certificates to be ready</p>
</li>
</ol>
<h2 id="heading-problem-4-managing-multiple-apps-and-review-deployments">Problem 4: Managing Multiple Apps and Review Deployments</h2>
<h3 id="heading-the-problem-3">The Problem</h3>
<p>Modern development workflows require:</p>
<ul>
<li><p>Multiple frontend applications (admin portal, customer app, etc.)</p>
</li>
<li><p>Review/preview deployments for pull requests</p>
</li>
<li><p>Wildcard certificates for dynamic subdomains</p>
</li>
</ul>
<p>Managing certificates for all these scenarios becomes complex.</p>
<h3 id="heading-the-solution-3">The Solution</h3>
<p>Use a combination of wildcard certificates and app-specific certificates:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Base wildcard certificate for all standard subdomains</span>
<span class="hljs-keyword">private</span> createWildcardCertificate(): <span class="hljs-built_in">void</span> {
  <span class="hljs-built_in">this</span>._wildcardCertificate = <span class="hljs-keyword">new</span> acm.Certificate(
    <span class="hljs-built_in">this</span>,
    <span class="hljs-string">'WildcardCertificate'</span>,
    {
      domainName: <span class="hljs-string">`*.<span class="hljs-subst">${<span class="hljs-built_in">this</span>.domainName}</span>`</span>,
      validation: acm.CertificateValidation.fromDns(<span class="hljs-built_in">this</span>.hostedZone),
    }
  );
}

<span class="hljs-comment">// App-specific wildcard certificates for review deployments</span>
<span class="hljs-keyword">private</span> createWebAppReviewCertificates(): <span class="hljs-built_in">void</span> {
  <span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> frontEndAppName <span class="hljs-keyword">in</span> <span class="hljs-built_in">this</span>.config.domainConfig.frontendApp) {
    <span class="hljs-keyword">const</span> enableReviews = <span class="hljs-built_in">this</span>.config.frontendApps?.find(
      <span class="hljs-function">(<span class="hljs-params">app</span>) =&gt;</span> app.name === frontEndAppName,
    )?.enableReviews;

    <span class="hljs-keyword">if</span> (!enableReviews) <span class="hljs-keyword">continue</span>;

    <span class="hljs-keyword">const</span> frontEndDomain =
      <span class="hljs-built_in">this</span>.config.domainConfig.frontendApp[frontEndAppName]?.subDomainName;

    <span class="hljs-comment">// Create wildcard for review apps: *.app.domain.com</span>
    <span class="hljs-keyword">const</span> certificate = <span class="hljs-keyword">new</span> acm.Certificate(
      <span class="hljs-built_in">this</span>,
      <span class="hljs-string">`<span class="hljs-subst">${frontEndDomain}</span>-certificate`</span>,
      {
        domainName: <span class="hljs-string">`<span class="hljs-subst">${frontEndDomain}</span>.<span class="hljs-subst">${<span class="hljs-built_in">this</span>.domainName}</span>`</span>,
        subjectAlternativeNames: [<span class="hljs-string">`*.<span class="hljs-subst">${frontEndDomain}</span>.<span class="hljs-subst">${<span class="hljs-built_in">this</span>.domainName}</span>`</span>],
        validation: acm.CertificateValidation.fromDns(<span class="hljs-built_in">this</span>.hostedZone),
      }
    );

    <span class="hljs-built_in">this</span>.webappReviewCertificates.set(frontEndAppName, certificate);
  }
}
</code></pre>
<p><strong>Why this works:</strong> This approach provides flexibility for both stable deployments and dynamic review environments without certificate proliferation.</p>
<h2 id="heading-problem-5-bootstrap-and-environment-configuration">Problem 5: Bootstrap and Environment Configuration</h2>
<h3 id="heading-the-problem-4">The Problem</h3>
<p>Cross-region deployments require:</p>
<ul>
<li><p>Both regions to be bootstrapped</p>
</li>
<li><p>Environment-specific configurations</p>
</li>
<li><p>Proper IAM trust relationships</p>
</li>
</ul>
<p>Missing any of these causes deployment failures that are hard to debug.</p>
<h3 id="heading-the-solution-4">The Solution</h3>
<ol>
<li><strong>Bootstrap both regions before deployment:</strong></li>
</ol>
<pre><code class="lang-bash"><span class="hljs-comment"># Bootstrap primary region</span>
cdk bootstrap aws://ACCOUNT_ID/ap-southeast-2

<span class="hljs-comment"># Bootstrap us-east-1 for certificates</span>
cdk bootstrap aws://ACCOUNT_ID/us-east-1
</code></pre>
<ol start="2">
<li><strong>Use environment-specific configuration:</strong></li>
</ol>
<pre><code class="lang-typescript"><span class="hljs-comment">// src/config/environments/dev/config.dev.ts</span>
<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> AUDevConfig: IConfig = {
  accountID: DEV_ACCOUNT_ID,
  region: <span class="hljs-string">'ap-southeast-2'</span>,
  env: <span class="hljs-string">'DEV'</span>,
  iluminrPrimaryRegion: <span class="hljs-string">'ap-southeast-2'</span>,
  domainConfig: devDomainConfig,
  frontendApps: devFrontendConfig,
  <span class="hljs-comment">// ... other config</span>
};
</code></pre>
<ol start="3">
<li><strong>Consume configuration in your CDK app:</strong></li>
</ol>
<pre><code class="lang-typescript"><span class="hljs-comment">// Frontend stack integration</span>
<span class="hljs-keyword">const</span> frontendStack = <span class="hljs-keyword">new</span> FrontendStack(<span class="hljs-built_in">this</span>, <span class="hljs-string">'FrontendStack'</span>, {
  ...props,
  domainStack: usEast1DomainStack,
  crossRegionReferences: <span class="hljs-literal">true</span>,
});

<span class="hljs-comment">// Angular deployment using the cross-region certificate</span>
<span class="hljs-keyword">new</span> AngularAppDeployment(<span class="hljs-built_in">this</span>, app.name, {
  appName: app.name,
  subDomainName: props.config.domainConfig.frontendApp[app.name]?.subDomainName,
  rootDomain: props.config.domainConfig.domainName,
  certificate: props.domainStack.wildcardCertificate,  <span class="hljs-comment">// From us-east-1</span>
  hostedZone: props.domainStack.hostedZone,
  env: props.config.env,
});
</code></pre>
<p><strong>Why this works:</strong> Proper bootstrapping ensures CDK has the necessary resources in both regions, while configuration management keeps your infrastructure DRY and maintainable.</p>
<h2 id="heading-best-practices">Best Practices</h2>
<ol>
<li><p><strong>Always validate certificates using DNS validation</strong> - It works across regions without manual intervention</p>
</li>
<li><p><strong>Use wildcard certificates strategically</strong> - Reduces certificate count and management overhead</p>
</li>
<li><p><strong>Tag your resources consistently</strong> - Makes debugging and cost allocation easier</p>
</li>
<li><p><strong>Export critical values</strong> - Certificate ARNs, distribution IDs for use by CI/CD pipelines</p>
</li>
<li><p><strong>Document region requirements</strong> - Add error checks that explicitly state region requirements</p>
</li>
</ol>
<h2 id="heading-common-pitfalls-to-avoid">Common Pitfalls to Avoid</h2>
<h3 id="heading-dont-forget-to-bootstrap-us-east-1">❌ Don't Forget to Bootstrap us-east-1</h3>
<p>Even if your infrastructure is elsewhere, us-east-1 needs bootstrapping for certificate creation.</p>
<h3 id="heading-dont-mix-regional-and-global-resources">❌ Don't Mix Regional and Global Resources</h3>
<p>Keep clear separation between regional stacks and us-east-1 stacks.</p>
<h3 id="heading-dont-ignore-deletion-order">❌ Don't Ignore Deletion Order</h3>
<p>When destroying stacks, delete in reverse dependency order:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Delete frontend first</span>
cdk destroy FrontendStack
<span class="hljs-comment"># Then us-east-1 resources</span>
cdk destroy USEast1DomainStack
<span class="hljs-comment"># Finally, primary region resources</span>
cdk destroy DomainStack
</code></pre>
<h3 id="heading-dont-hardcode-region-values">❌ Don't Hardcode Region Values</h3>
<p>Always use configuration to manage regions:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Bad</span>
<span class="hljs-keyword">const</span> stack = <span class="hljs-keyword">new</span> Stack(<span class="hljs-built_in">this</span>, <span class="hljs-string">'Stack'</span>, { env: { region: <span class="hljs-string">'us-east-1'</span> } });

<span class="hljs-comment">// Good</span>
<span class="hljs-keyword">const</span> stack = <span class="hljs-keyword">new</span> Stack(<span class="hljs-built_in">this</span>, <span class="hljs-string">'Stack'</span>, {
  env: { region: config.certificateRegion }
});
</code></pre>
<h2 id="heading-conclusion">Conclusion</h2>
<p>The CloudFront cross-region certificate requirement is a classic AWS gotcha that has frustrated countless developers. By understanding the underlying constraints and implementing a clean separation between regional and us-east-1 resources, you can build robust, multi-region CDK applications without the headache.</p>
<p>Key takeaways:</p>
<ul>
<li><p><strong>Always create CloudFront certificates in us-east-1</strong></p>
</li>
<li><p><strong>Use</strong> <code>crossRegionReferences: true</code> for cross-region stack dependencies</p>
</li>
<li><p><strong>Implement proper dependency chains between stacks</strong></p>
</li>
<li><p><strong>Bootstrap all regions before deployment</strong></p>
</li>
<li><p><strong>Use configuration-driven infrastructure for flexibility</strong></p>
</li>
</ul>
<p>This pattern has been battle-tested in production environments serving millions of requests. It provides a solid foundation for building globally distributed applications with AWS CDK while maintaining clean, maintainable infrastructure code.</p>
<p>Remember: The complexity is in understanding the problem. Once you know the constraints, the solution is straightforward.</p>
<hr />
<p><em>Have you encountered other cross-region challenges with AWS CDK? What patterns have worked for you? Share your experiences and let's build better infrastructure together.</em></p>
]]></content:encoded></item><item><title><![CDATA[Breaking Infrastructure Lock-in: How Dapr Simplifies Microservice Messaging]]></title><description><![CDATA[In my experience building distributed systems, I've consistently seen the need to evolve messaging infrastructure as applications mature. What starts as a simple Redis pub/sub for prototyping might need to scale to Kafka for high throughput, or switc...]]></description><link>https://blog.supercharged.dev/breaking-infrastructure-lock-in-how-dapr-simplifies-microservice-messaging</link><guid isPermaLink="true">https://blog.supercharged.dev/breaking-infrastructure-lock-in-how-dapr-simplifies-microservice-messaging</guid><category><![CDATA[dapr]]></category><category><![CDATA[infrastructure]]></category><category><![CDATA[PubSub]]></category><category><![CDATA[Microservices]]></category><category><![CDATA[distributed system]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Sat, 07 Jun 2025 09:55:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1749290347056/e963d2ce-740a-4590-b063-9e95e06ca508.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In my experience building distributed systems, I've consistently seen the need to evolve messaging infrastructure as applications mature. What starts as a simple Redis pub/sub for prototyping might need to scale to Kafka for high throughput, or switch to cloud-native solutions during migration. Even when you make the right infrastructure choice initially, requirements change—new compliance needs (e.g., encrypted messaging), higher throughput (Kafka over Redis), or cost-driven shifts (like switching to managed brokers).</p>
<p><strong>The problem? Most teams tightly couple their business logic to specific message brokers, making these transitions painful and error-prone.</strong></p>
<p>Here's what tightly coupled code typically looks like:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Tightly coupled to Kafka - mixing business logic with infrastructure</span>
<span class="hljs-keyword">import</span> { Kafka } <span class="hljs-keyword">from</span> <span class="hljs-string">'kafkajs'</span>;

<span class="hljs-keyword">const</span> kafka = <span class="hljs-keyword">new</span> Kafka({ brokers: [<span class="hljs-string">'kafka:9092'</span>] });
<span class="hljs-keyword">const</span> producer = kafka.producer();

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processPayment</span>(<span class="hljs-params">paymentData: PaymentData</span>) </span>{
  <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> chargeCard(paymentData);

  <span class="hljs-comment">// Kafka-specific code mixed with business logic</span>
  <span class="hljs-keyword">await</span> producer.send({
    topic: <span class="hljs-string">'payment-events'</span>,
    messages: [{
      key: result.paymentId,
      value: <span class="hljs-built_in">JSON</span>.stringify({
        paymentId: result.paymentId,
        orderId: result.orderId,
        status: <span class="hljs-string">'completed'</span>
      })
    }]
  });

  <span class="hljs-keyword">return</span> result;
}
</code></pre>
<p>This approach has several maintenance problems:</p>
<ul>
<li><p>Infrastructure changes require touching business logic</p>
</li>
<li><p>Testing requires complex broker setup</p>
</li>
<li><p>Different teams might implement messaging differently</p>
</li>
</ul>
<hr />
<h3 id="heading-diagram-tightly-coupled-flow-kafka-specific">Diagram: Tightly Coupled Flow (Kafka-specific)</h3>
<pre><code class="lang-mermaid">flowchart LR
  A[processPayment] --&gt; B[chargeCard]
  B --&gt; C[Kafka producer.send]
  style C fill:#fdd,stroke:#f66,stroke-width:2px
  C:::infra
  classDef infra fill:#fdd,stroke:#f66,stroke-width:2px,color:#800;
</code></pre>
<hr />
<h2 id="heading-enter-dapr-infrastructure-abstraction-done-right">Enter Dapr: Infrastructure Abstraction Done Right</h2>
<p>Dapr solves this by providing a consistent API layer between your application and infrastructure. Instead of importing broker-specific libraries, you interact with Dapr's standardized interface.</p>
<p>Here's the same payment service with Dapr:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { DaprClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@dapr/dapr'</span>;

<span class="hljs-keyword">const</span> daprClient = <span class="hljs-keyword">new</span> DaprClient();

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processPayment</span>(<span class="hljs-params">paymentData: PaymentData</span>) </span>{
  <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> chargeCard(paymentData);

  <span class="hljs-comment">// Clean, infrastructure-agnostic publish</span>
  <span class="hljs-keyword">await</span> daprClient.pubsub.publish(<span class="hljs-string">'payment-events'</span>, <span class="hljs-string">'payment.completed'</span>, {
    paymentId: result.paymentId,
    orderId: result.orderId,
    status: <span class="hljs-string">'completed'</span>
  }, {
    partitionKey: result.paymentId
  });

  <span class="hljs-keyword">return</span> result;
}
</code></pre>
<hr />
<h3 id="heading-diagram-infrastructure-agnostic-flow-with-dapr">Diagram: Infrastructure-agnostic Flow with Dapr</h3>
<pre><code class="lang-mermaid">flowchart TD
  A[processPayment] --&gt; B[chargeCard]
  B --&gt; C[pubsub.publish]
  style C fill:#ddf,stroke:#66f,stroke-width:2px
  C:::infra
  classDef infra fill:#ddf,stroke:#66f,stroke-width:2px,color:#004;
</code></pre>
<hr />
<p>The infrastructure choice becomes a configuration concern:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">dapr.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Component</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">payment-events</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">pubsub.kafka</span>
  <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
  <span class="hljs-attr">metadata:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">brokers</span>
    <span class="hljs-attr">value:</span> <span class="hljs-string">"kafka:9092"</span>
</code></pre>
<p>Need to switch to a different broker? Change the config, not the code:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">dapr.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Component</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">payment-events</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">pubsub.azure.servicebus</span>
  <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
  <span class="hljs-attr">metadata:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">connectionString</span>
    <span class="hljs-attr">value:</span> <span class="hljs-string">"Endpoint=sb://..."</span>
</code></pre>
<hr />
<h2 id="heading-real-world-example-order-processing-system">Real-World Example: Order Processing System</h2>
<p>Let me demonstrate this with a complete order processing flow. When orders are created, multiple services need to react:</p>
<p><strong>Order Service</strong> (publishes events):</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { DaprClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@dapr/dapr'</span>;

<span class="hljs-keyword">const</span> daprClient = <span class="hljs-keyword">new</span> DaprClient();

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">createOrder</span>(<span class="hljs-params">orderData: CreateOrderRequest</span>) </span>{
  <span class="hljs-keyword">const</span> order = <span class="hljs-keyword">await</span> saveOrder(orderData);

  <span class="hljs-comment">// Publish to multiple systems cleanly</span>
  <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all([
    daprClient.pubsub.publish(<span class="hljs-string">'order-events'</span>, <span class="hljs-string">'order.created'</span>, order),
    daprClient.pubsub.publish(<span class="hljs-string">'analytics-events'</span>, <span class="hljs-string">'order.metrics'</span>, {
      customerId: order.customerId,
      value: order.total,
      timestamp: <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>()
    })
  ]);

  <span class="hljs-keyword">return</span> order;
}
</code></pre>
<p><strong>Inventory Service</strong> (subscribes to events):</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { DaprServer } <span class="hljs-keyword">from</span> <span class="hljs-string">'@dapr/dapr'</span>;

<span class="hljs-keyword">const</span> daprServer = <span class="hljs-keyword">new</span> DaprServer();

<span class="hljs-comment">// Clean subscription handling</span>
<span class="hljs-keyword">await</span> daprServer.pubsub.subscribe(<span class="hljs-string">'order-events'</span>, <span class="hljs-string">'order.created'</span>, <span class="hljs-keyword">async</span> (data) =&gt; {
  <span class="hljs-keyword">const</span> order = data <span class="hljs-keyword">as</span> Order;

  <span class="hljs-comment">// Pure business logic - no infrastructure concerns</span>
  <span class="hljs-keyword">await</span> reserveInventory(order.items);
  <span class="hljs-keyword">await</span> updateStockLevels(order.items);

  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Reserved inventory for order <span class="hljs-subst">${order.id}</span>`</span>);
});

<span class="hljs-keyword">await</span> daprServer.start();
</code></pre>
<p><strong>Email Service</strong> (also subscribes):</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { DaprServer } <span class="hljs-keyword">from</span> <span class="hljs-string">'@dapr/dapr'</span>;

<span class="hljs-keyword">const</span> daprServer = <span class="hljs-keyword">new</span> DaprServer();

<span class="hljs-keyword">await</span> daprServer.pubsub.subscribe(<span class="hljs-string">'order-events'</span>, <span class="hljs-string">'order.created'</span>, <span class="hljs-keyword">async</span> (data) =&gt; {
  <span class="hljs-keyword">const</span> order = data <span class="hljs-keyword">as</span> Order;

  <span class="hljs-keyword">await</span> sendConfirmationEmail({
    to: order.customerEmail,
    orderId: order.id,
    items: order.items
  });
});

<span class="hljs-keyword">await</span> daprServer.start();
</code></pre>
<hr />
<h3 id="heading-diagram-order-processing-pubsub-sequence">Diagram: Order Processing Pub/Sub Sequence</h3>
<pre><code class="lang-mermaid">sequenceDiagram
  participant OrderService
  participant PubSub
  participant InventoryService
  participant EmailService

  OrderService-&gt;&gt;PubSub: publish(order.created)
  PubSub-&gt;&gt;InventoryService: order.created
  PubSub-&gt;&gt;EmailService: order.created
</code></pre>
<hr />
<h2 id="heading-infrastructure-evolution-made-simple">Infrastructure Evolution Made Simple</h2>
<p>As your system evolves, you can adapt the messaging layer without code changes. Here are some common scenarios:</p>
<p><strong>Development Environment</strong> (lightweight Redis):</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">dapr.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Component</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">order-events</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">pubsub.redis</span>
  <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
  <span class="hljs-attr">metadata:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">redisHost</span>
    <span class="hljs-attr">value:</span> <span class="hljs-string">"localhost:6379"</span>
</code></pre>
<p><strong>Production Environment</strong> (same Redis for consistency):</p>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">dapr.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Component</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">order-events</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">pubsub.redis</span>
  <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
  <span class="hljs-attr">metadata:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">redisHost</span>
    <span class="hljs-attr">value:</span> <span class="hljs-string">"redis-cluster:6379"</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">redisPassword</span>
    <span class="hljs-attr">secretKeyRef:</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">redis-secret</span>
      <span class="hljs-attr">key:</span> <span class="hljs-string">password</span>
</code></pre>
<blockquote>
<p>💡 Tip: Keep the same broker type across stage/prod to minimize surprises.</p>
</blockquote>
<hr />
<h3 id="heading-migrating-to-kafka-when-scale-demands-it">Migrating to Kafka (when scale demands it):</h3>
<pre><code class="lang-yaml"><span class="hljs-attr">apiVersion:</span> <span class="hljs-string">dapr.io/v1alpha1</span>
<span class="hljs-attr">kind:</span> <span class="hljs-string">Component</span>
<span class="hljs-attr">metadata:</span>
  <span class="hljs-attr">name:</span> <span class="hljs-string">order-events</span>
<span class="hljs-attr">spec:</span>
  <span class="hljs-attr">type:</span> <span class="hljs-string">pubsub.kafka</span>
  <span class="hljs-attr">version:</span> <span class="hljs-string">v1</span>
  <span class="hljs-attr">metadata:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">brokers</span>
    <span class="hljs-attr">value:</span> <span class="hljs-string">"kafka-cluster:9092"</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">consumerGroup</span>
    <span class="hljs-attr">value:</span> <span class="hljs-string">"order-processors"</span>
</code></pre>
<blockquote>
<p>Most teams wait until it's painful to migrate infra. Dapr makes it painless up front.</p>
</blockquote>
<hr />
<h2 id="heading-why-this-matters-for-maintenance">Why This Matters for Maintenance</h2>
<p><strong>Consistent Patterns</strong>: Every developer uses the same pub/sub API regardless of the underlying infrastructure. No need to become a Kafka expert or Redis specialist.</p>
<p><strong>Easier Testing</strong>: Mock the Dapr client instead of complex broker setups. Unit tests run fast without external dependencies.</p>
<p><strong>Reduced Cognitive Load</strong>: Developers focus on business logic, not infrastructure plumbing. The abstraction prevents reinventing the wheel across teams.</p>
<p><strong>Infrastructure Flexibility</strong>: Migrate brokers during planned maintenance windows without touching application code. Rollback is just a config change.</p>
<p><strong>Operational Consistency</strong>: Dapr provides built-in observability, retries, and circuit breakers across all components. No custom implementations needed.</p>
<hr />
<h2 id="heading-the-trade-offs">The Trade-offs</h2>
<p><strong>Additional Complexity</strong>: You're adding another runtime component. The sidecar pattern means more moving parts in your deployment.</p>
<p><strong>Performance Overhead</strong>: There's a small latency cost (typically 1-3ms) for the extra network hop to the Dapr sidecar.</p>
<p><strong>Learning Curve</strong>: Teams need to understand Dapr's component model and configuration patterns.</p>
<p><strong>Component Maturity</strong>: Not all Dapr components are equally battle-tested. Some have limitations you'll need to work around.</p>
<hr />
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>Dapr's value shines in long-term maintenance scenarios. When you need to evolve your messaging infrastructure—and you will—having clean abstractions makes the difference between a smooth migration and weeks of refactoring.</p>
<p>The key insight is treating infrastructure as a pluggable concern rather than a fundamental architectural decision. Your business logic shouldn't care whether messages flow through Kafka, RabbitMQ, or cloud services.</p>
<p>Start with a single service and try Dapr's pub/sub. Once you experience the clean separation, you'll want to apply it everywhere. The investment in abstraction pays dividends when inevitable infrastructure changes come.</p>
<hr />
<h2 id="heading-tldr">TL;DR</h2>
<p>Dapr lets you swap message brokers like changing your socks—just update a config file, not your code. Your future self will thank you when that inevitable infrastructure migration comes knocking.</p>
]]></content:encoded></item><item><title><![CDATA[Navigating PostgreSQL Challenges in 2023: A Backend Developer's Journey]]></title><description><![CDATA[Introduction: In the fast-paced world of backend development, working with PostgreSQL comes with its own set of hurdles. In this blog post, I'll share my experiences facing challenges like index and table bloating, an unusual performance bug related ...]]></description><link>https://blog.supercharged.dev/navigating-postgresql-challenges-in-2023-a-backend-developers-journey</link><guid isPermaLink="true">https://blog.supercharged.dev/navigating-postgresql-challenges-in-2023-a-backend-developers-journey</guid><category><![CDATA[Software Engineering]]></category><category><![CDATA[PostgreSQL]]></category><category><![CDATA[Bugs and Errors]]></category><category><![CDATA[2023]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Sun, 31 Dec 2023 10:10:33 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1704017035168/60450a70-bd2f-4e48-923e-f59f959d0e61.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p><strong>Introduction</strong>: In the fast-paced world of backend development, working with PostgreSQL comes with its own set of hurdles. In this blog post, I'll share my experiences facing challenges like index and table bloating, an unusual performance bug related to the LIMIT clause, and the perils of a full vacuum on a production database.</p>
<ol>
<li><p><strong>Index Bloating</strong>: One of the persistent issues I encountered was index bloating. PostgreSQL, while a reliable database system, sometimes lets indexes consume more disk space than necessary. This not only slows down performance but also adds unexpected storage costs. I spent significant time optimizing indexes to strike the right balance between performance and disk usage.</p>
</li>
<li><p><strong>Table Bloating</strong>: Table bloat, another common problem, occurs as tables accumulate data. This bloat can affect query performance and overall system responsiveness. To counteract this issue, I implemented regular maintenance routines. However, finding the right frequency for these routines without disrupting day-to-day operations proved to be a delicate task.</p>
</li>
<li><p><strong>Limit 1 Performance Bug</strong>: A curious bug surfaced when I encountered a performance issue related to the LIMIT clause. In an unexpected turn of events, setting a limit of 70 on a query intended to retrieve a single item actually improved performance. This showcases the intricate nature of database optimization, where solutions may not always align with conventional wisdom.</p>
</li>
<li><p><strong>Full Vacuum Fallout</strong>: Performing a full vacuum on a production database is a delicate operation. Even with careful planning to execute it during low-traffic periods, I faced an unexpected consequence. The temporary increase in table size caused the database to consume 100% of disk space, resulting in a crash. Luckily, due to strategic planning, the impact on end-users was kept minimal, underscoring the importance of cautious execution in routine maintenance tasks.</p>
</li>
</ol>
<p><strong>Conclusion</strong>: Throughout my journey in 2023, grappling with PostgreSQL has been both challenging and rewarding. Despite the hurdles of index and table bloating, peculiar performance bugs, and the cautious dance of production vacuuming, I've found immense satisfaction in working with this robust database system. Certain features, such as JSONB, timestamp with time zone and MVCC (Multi Version Concurrency Control) have proven to be invaluable tools, enhancing the overall development experience.</p>
<p>While PostgreSQL has been a reliable companion, it's crucial to remember the age-old wisdom of using the right tool for the right job. Each database system has its strengths, and understanding when to leverage PostgreSQL's capabilities and when to explore other options is key to building efficient and scalable applications. As I reflect on my experiences, I carry with me not only the lessons learned from overcoming challenges but also a deep appreciation for the diverse toolkit that empowers developers in the ever-evolving landscape of backend development.</p>
]]></content:encoded></item><item><title><![CDATA[Books that I have read in 2023.]]></title><description><![CDATA[Greetings fellow engineers,
As we bid farewell to another year filled with coding, debugging, and pushing the boundaries of what's possible, it's time to reflect on the pages that have molded our minds in 2023 and prepare for the adventures that 2024...]]></description><link>https://blog.supercharged.dev/books-that-i-have-read-in-2023</link><guid isPermaLink="true">https://blog.supercharged.dev/books-that-i-have-read-in-2023</guid><category><![CDATA[2024 Goals]]></category><category><![CDATA[books]]></category><category><![CDATA[2023]]></category><category><![CDATA[engineering]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Sun, 31 Dec 2023 09:30:02 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/9T346Ij4kGk/upload/0cd266c15d0347b8973e9d786f8ae533.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Greetings fellow engineers,</p>
<p>As we bid farewell to another year filled with coding, debugging, and pushing the boundaries of what's possible, it's time to reflect on the pages that have molded our minds in 2023 and prepare for the adventures that 2024 holds. As an engineer navigating the fast-paced world of Indian startups, I've discovered some invaluable books that not only honed my technical skills but also added unexpected dimensions to my engineering toolkit.</p>
<p><strong>1. Designing Data-Intensive Applications by Martin Kleppmann:</strong> Why it's the book of my year: Delve deep into the intricacies of data engineering. If you aim to equip your applications to handle the chaos of the modern tech landscape, this book serves as your reliable map and compass. Plus, I've learned more about how databases work internally, making it an invaluable resource.</p>
<p><strong>2. Never Split the Difference by Chris Voss:</strong> Why negotiation matters: While we may not be FBI agents, every line of code we write is a negotiation with the system. Voss shares negotiation tactics that surprisingly translate well into our tech discussions.</p>
<p><strong>3. Psychology of Money by Morgan Housel:</strong> Beyond the code: Let's discuss the green stuff. Housel's book goes beyond numbers; it's about understanding the psychology behind financial decisions. A must-read to keep both your wallet and sanity intact.</p>
<p><strong>4. Software Engineering at Google by Titus Winters, Tom Manshreck, and Hyrum Wright:</strong> Inside the Google Brain: Ever wondered how the tech behemoth handles software engineering? Gain an insider's view into Google's playbook. Spoiler: It's not all about the search bar.</p>
<p>But what's on my radar for 2024?</p>
<p><strong>1. The Design of Everyday Things by Don Norman:</strong> User-centric design for the win: Let's make our software not just functional but downright delightful. Norman's classic promises to open our eyes to the magic of design in everyday tech.</p>
<p><strong>2. Thinking, Fast and Slow by Daniel Kahneman:</strong> Get into your user's head: Our brains are peculiar creatures. Kahneman's exploration of fast and slow thinking is a goldmine for understanding our users and, well, ourselves.</p>
<p><strong>3. The Manager's Path: A Guide for Tech Leaders Navigating Growth and Change by Camille Fournier:</strong> From code to leadership: Contemplating climbing the career ladder? Fournier's got the lowdown on the transition from being the code wizard to the tech leader. Spoiler alert: It's not just about fixing bugs anymore.</p>
<p><strong>P.S.:</strong> Wondering if all these books will save me from AI taking over the software world. Understanding data, mastering negotiation, and decoding money psychology—hoping it's the secret sauce! A touch of humor might just be the extra code we need. 😄 Happy coding and happy reading!</p>
]]></content:encoded></item><item><title><![CDATA[Dependency Injection in NestJs for beginners]]></title><description><![CDATA[Introduction
Hey there, fellow developers! Today, I want to share with you a powerful technique that can take your NestJS applications to a whole new level. It's called dependency injection (DI), and trust me, once you get the hang of it, it'll becom...]]></description><link>https://blog.supercharged.dev/dependency-injection-in-nestjs-for-beginners</link><guid isPermaLink="true">https://blog.supercharged.dev/dependency-injection-in-nestjs-for-beginners</guid><category><![CDATA[nestjs]]></category><category><![CDATA[dependency injection]]></category><category><![CDATA[TypeScript]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Sat, 24 Jun 2023 06:18:43 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1687590337699/5f32e3c7-b762-45f3-9bba-3126cd0aa336.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Hey there, fellow developers! Today, I want to share with you a powerful technique that can take your NestJS applications to a whole new level. It's called dependency injection (DI), and trust me, once you get the hang of it, it'll become your secret weapon for writing clean, maintainable, and modular code. So buckle up and get ready to dive into the wonderful world of dependency injection in NestJS!</p>
<h2 id="heading-unleashing-the-power-of-dependency-injection"><strong>Unleashing the Power of Dependency Injection</strong></h2>
<p>Okay, let's break it down. Dependency injection is like having a super-smart assistant who automatically handles all the nitty-gritty stuff for you. It's a software design pattern that lets you decouple components from their dependencies, making your code more flexible and scalable.</p>
<p><em>Picture this</em>: you're building an awesome NestJS app that sends SMS notifications to users. But hey, what if you want to switch from one SMS provider to another without breaking a sweat? That's where DI comes in to save the day! With dependency injection, you can seamlessly swap out providers just by updating the module where it's injected. No more headaches or messy code changes. How cool is that? - We will get to this example as soon as we knock down the constructor injection which is one of the techniques that powers dependency injection.</p>
<h2 id="heading-simplifying-your-life-with-constructor-injection"><strong>Simplifying Your Life with Constructor Injection</strong></h2>
<p>Now, let's talk about constructor injection, a key aspect of DI. Imagine you have a complex service in your app that requires multiple dependencies to function properly. Without dependency injection, you would have to manually create and manage instances of each dependency within the service. It can quickly become a nightmare, especially when the number of dependencies increases.</p>
<p>But fear not! Dependency injection comes to the rescue. With constructor injection, you can simply declare the dependencies as constructor parameters, and NestJS injects the required instances for you. It's like having a magical genie fulfilling your service's every wish.</p>
<p>Imagine we have a <code>ComplexService</code> that needs three dependencies: <code>DependencyA</code>, <code>DependencyB</code>, and <code>DependencyC</code>. Now, let's say <code>DependencyA</code> itself requires some constructor values. With dependency injection, you don't need to worry about providing those values explicitly. Here's an example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { DependencyA } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dependency-a'</span>;
<span class="hljs-keyword">import</span> { DependencyB } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dependency-b'</span>;
<span class="hljs-keyword">import</span> { DependencyC } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dependency-c'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ComplexService {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> dependencyA: DependencyA,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> dependencyB: DependencyB,
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> dependencyC: DependencyC,
  </span>) {
    <span class="hljs-comment">// Constructor logic goes here</span>
  }

  <span class="hljs-comment">// Service methods and functionality</span>
}
</code></pre>
<p>In this example, even if <code>DependencyA</code> requires some constructor values, you don't need to pass them explicitly when creating an instance of <code>ComplexService</code>. NestJS will automatically handle the injection of all dependencies, including the required constructor values of <code>DependencyA</code>.</p>
<p>What If There's No Dependency Injection?</p>
<p>Now, imagine a scenario where you don't use dependency injection. Without DI, you would have to manually create instances of each dependency within the service. Your code might look like this:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { DependencyA } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dependency-a'</span>;
<span class="hljs-keyword">import</span> { DependencyB } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dependency-b'</span>;
<span class="hljs-keyword">import</span> { DependencyC } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dependency-c'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> ComplexService {
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> dependencyA: DependencyA;
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> dependencyB: DependencyB;
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> dependencyC: DependencyC;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"></span>) {
    <span class="hljs-built_in">this</span>.dependencyA = <span class="hljs-keyword">new</span> DependencyA(<span class="hljs-comment">/* Constructor values for DependencyA */</span>);
    <span class="hljs-built_in">this</span>.dependencyB = <span class="hljs-keyword">new</span> DependencyB();
    <span class="hljs-built_in">this</span>.dependencyC = <span class="hljs-keyword">new</span> DependencyC();
    <span class="hljs-comment">// Constructor logic goes here</span>
  }

  <span class="hljs-comment">// Service methods and functionality</span>
}
</code></pre>
<p>As you can see, without dependency injection, you need to manually create and manage instances of each dependency, including providing the required constructor values. This can quickly become cumbersome and error-prone, especially as your application grows in complexity.</p>
<h2 id="heading-switching-providers-dependency-service-with-ease">Switching Providers (Dependency Service) with Ease</h2>
<p>Let's dive into a practical example to understand how dependency injection can make our lives easier.</p>
<p>Imagine we have an <code>SmsService</code> responsible for sending SMS notifications to users, and it needs a way to interact with different SMS providers, such as Twilio or Nexmo.</p>
<p>To achieve this flexibility, we use a concept called dependency injection. It allows us to decouple the <code>SmsService</code> from any specific SMS provider implementation. But how does it work?</p>
<p>In our scenario, we define an interface called <code>ISmsProvider</code>. An interface is like a contract that specifies a set of methods that a class must implement. In our case, the <code>ISmsProvider</code> interface defines a method called <code>sendSMS</code> that takes in a phone number and a message and returns a boolean indicating whether the SMS was successfully sent.</p>
<p>Here's an example of how the <code>ISmsProvider</code> interface could look:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> ISmsProvider {
  sendSMS(phoneNumber: <span class="hljs-built_in">string</span>, message: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">boolean</span>;
}
</code></pre>
<p>By defining this interface, we're essentially saying that any class that wants to be an SMS provider must implement the <code>sendSMS</code> method with the same parameters and return type.</p>
<p>Now, let's move on to the <code>SmsService</code>. Instead of directly using a specific provider like Twilio or Nexmo, we declare a constructor parameter of type <code>ISmsProvider</code> in the <code>SmsService</code> class. This means that the <code>SmsService</code> expects an object that conforms to the <code>ISmsProvider</code> interface to be injected when creating an instance of the <code>SmsService</code>.</p>
<p>By injecting the <code>ISmsProvider</code> through the constructor, we create a loose coupling between the <code>SmsService</code> and the actual SMS provider implementation. This allows us to switch providers easily without modifying the core logic of the <code>SmsService</code>.</p>
<p>Let's see an example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> SmsService {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> smsProvider: ISmsProvider</span>) {}

  sendSMS(phoneNumber: <span class="hljs-built_in">string</span>, message: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">boolean</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.smsProvider.sendSMS(phoneNumber, message);
  }
}
</code></pre>
<p>In this example, the <code>SmsService</code> class has a method called <code>sendSMS</code> that takes a phone number and a message as parameters. It uses the injected <code>smsProvider</code> object to call the <code>sendSMS</code> method on the provider, abstracting away the specific implementation details.</p>
<p>Here's an example of the <code>TwilioSmsProvider</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { ISmsProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'./sms.provider.interface'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> TwilioSmsProvider <span class="hljs-keyword">implements</span> ISmsProvider {
  sendSMS(phoneNumber: <span class="hljs-built_in">string</span>, message: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">boolean</span>&gt; {
    <span class="hljs-comment">// Implement the Twilio SMS sending logic here</span>
  }
}
</code></pre>
<p>To switch providers, all we need to do is update the module configuration where the <code>SmsService</code> is injected. Here's an example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { SmsService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./sms.service'</span>;
<span class="hljs-keyword">import</span> { ISmsProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'./sms.provider.interface'</span>;
<span class="hljs-keyword">import</span> { TwilioSmsProvider } <span class="hljs-keyword">from</span> <span class="hljs-string">'./twilio-sms.provider'</span>;

<span class="hljs-meta">@Module</span>({
  providers: [
    {
      provide: ISmsProvider,
      useClass: TwilioSmsProvider,
    },
    SmsService,
  ],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> SmsModule {}
</code></pre>
<p>In the <code>SmsModule</code> configuration, we define that the <code>ISmsProvider</code> should be provided by the <code>TwilioSmsProvider</code> class. By simply updating this configuration, we can seamlessly switch to using Twilio as our SMS provider.</p>
<p>The beauty of dependency injection is that we don't need to touch the <code>SmsService</code> implementation. It remains blissfully unaware of the underlying provider implementation. This decoupling allows us to easily switch providers, improve flexibility, and keep our codebase clean and modular.</p>
<h2 id="heading-testability-you-bet"><strong>Testability? You Bet!</strong></h2>
<p>But wait, there's more! Dependency injection also supercharges the testability of your code. By injecting mock or stub implementations of dependencies during unit tests, you can isolate your components and ensure reliable and thorough testing. No more tangled web of dependencies ruining your testing party. It's all about that sweet, sweet isolation!</p>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>Congratulations, my fellow developer! You're now armed with the knowledge of dependency injection in NestJS. With its modularity, scalability, and testability superpowers, you can build remarkable applications that are a breeze to maintain and extend.</p>
<p>So, don't be shy—embrace dependency injection, unlock the full potential of NestJS, and watch your codebase soar to new heights. Happy coding, and may the DI force be with you!</p>
]]></content:encoded></item><item><title><![CDATA[Dockerizing NestJs application for production]]></title><description><![CDATA[Prerequisites

Docker installed https://docs.docker.com/engine/install/
A nest Js application

Containerized Nest Js Application
Creating Dockerfile with multi-stage build
create a file named Dockerfile in the root directory of the nestjs application...]]></description><link>https://blog.supercharged.dev/dockerizing-nestjs-application-for-production</link><guid isPermaLink="true">https://blog.supercharged.dev/dockerizing-nestjs-application-for-production</guid><category><![CDATA[Docker]]></category><category><![CDATA[containers]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[nest]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Wed, 17 Mar 2021 07:54:55 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1615967742550/hn5se0ey9.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h1 id="prerequisites">Prerequisites</h1>
<ul>
<li>Docker installed <a target="_blank" href="https://docs.docker.com/engine/install/">https://docs.docker.com/engine/install/</a></li>
<li>A nest Js application</li>
</ul>
<h1 id="containerized-nest-js-application">Containerized Nest Js Application</h1>
<h2 id="creating-dockerfile-with-multi-stage-build">Creating Dockerfile with multi-stage build</h2>
<p>create a file named <code>Dockerfile</code> in the root directory of the nestjs application</p>
<p>Replace <code>9009</code> with your application port</p>
<pre><code class="lang-docker">FROM node:12 As development
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM node:12-alpine As production
RUN apk update &amp;&amp; apk upgrade &amp;&amp; \
  apk add --no-cache bash git openssh
ARG NODE_ENV=production
ENV NODE_ENV=${NODE_ENV}
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install --only=production
COPY . .
COPY --from=development /usr/src/app/dist ./dist
EXPOSE 9009
CMD ["node", "dist/main"]
</code></pre>
<h2 id="creating-dockerignore">Creating .dockerignore</h2>
<p>From the <a target="_blank" href="https://docs.docker.com/engine/reference/builder/#dockerignore-file">official docs</a> of docker for .dockerignore:</p>
<blockquote>
<p>Before the docker CLI sends the context to the docker daemon, it looks for a file named .dockerignore in the root directory of the context. If this file exists, the CLI modifies the context to exclude files and directories that match patterns in it. This helps to avoid unnecessarily sending large or sensitive files and directories to the daemon and potentially adding them to images using ADD or COPY.</p>
</blockquote>
<pre><code class="lang-docker">node_modules
npm-debug.log
dist
</code></pre>
<h2 id="build-docker-image">Build Docker Image</h2>
<p>When building an image, we use the following command:</p>
<pre><code class="lang-bash">docker build -t username/image_name:tag_name .
</code></pre>
<p>in the below command replace api with your application name</p>
<pre><code class="lang-bash">docker build -t sreeteja06/api:v0.1 .
</code></pre>
<h2 id="running-the-image">Running the image</h2>
<p>replace <code>api</code> with your application name</p>
<p>replace <code>9009:9009</code> with your application port</p>
<pre><code class="lang-bash">docker run -p 9009:9009 api
</code></pre>
<p>Run detached</p>
<pre><code class="lang-bash">docker run -d -p 9009:9009 api
</code></pre>
<h1 id="docker-compose">docker-compose</h1>
<p>docker-compose helps developers with their local development. Since our application is containerized and works the same on every machine, why should our database be dependent on the developer’s machine?</p>
<p>We are going to create a docker-compose config that will initiate and wire up three services for us.</p>
<p>The <code>mariadb</code> service will, as their names imply, run containerized mariadb.</p>
<p>In the application root directory, create a file called <code>docker-compose.yml</code> and fill it with the following content:</p>
<p>replace <code>api</code> with your application name and <code>9009:9009</code> with your port</p>
<pre><code class="lang-yaml"><span class="hljs-attr">version:</span> <span class="hljs-string">'3.7'</span>

<span class="hljs-attr">services:</span>
  <span class="hljs-attr">db:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">mariadb</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span>
    <span class="hljs-attr">environment:</span>
      <span class="hljs-attr">MYSQL_ROOT_PASSWORD:</span> <span class="hljs-string">example</span>
      <span class="hljs-attr">MYSQL_DATABASE:</span> <span class="hljs-string">mydb</span>
      <span class="hljs-attr">MYSQL_USER:</span> <span class="hljs-string">user</span>
      <span class="hljs-attr">MYSQL_PASSWORD:</span> <span class="hljs-string">user</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-number">3306</span><span class="hljs-string">:3306</span>
    <span class="hljs-attr">volumes:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">mariadb-data:/data</span>

  <span class="hljs-attr">api:</span>
    <span class="hljs-attr">image:</span> <span class="hljs-string">api</span>
    <span class="hljs-attr">restart:</span> <span class="hljs-string">always</span>
    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-number">9009</span><span class="hljs-string">:9009</span>

<span class="hljs-attr">volumes:</span>
  <span class="hljs-attr">mariadb-data:</span>
</code></pre>
<h3 id="running-the-application-in-development"><strong>Running the application in development</strong></h3>
<p>To run the application, we now have to use the following command:</p>
<pre><code class="lang-bash">docker-compose up
</code></pre>
<p>Run Detached</p>
<pre><code class="lang-bash">docker-compose up -d
</code></pre>
<p>And Docker will take care of everything for us.</p>
<p>Stop docker-compose by running</p>
<pre><code class="lang-bash">docker-compose down
</code></pre>
<p>Remove volumes by running</p>
<pre><code class="lang-bash">docker-compose down -v
</code></pre>
]]></content:encoded></item><item><title><![CDATA[How to log express HTTP requests using morgan with style?]]></title><description><![CDATA[In this cookbook, I am gonna help you setup morgan with express to log HTTP requests like this,

at the end of this post, you will be able to log the following details

date and time of the request ( formatted as hh:mm a ddd, MMMM Do YYYY )
HTTP Meth...]]></description><link>https://blog.supercharged.dev/how-to-log-express-http-requests-using-morgan-with-style</link><guid isPermaLink="true">https://blog.supercharged.dev/how-to-log-express-http-requests-using-morgan-with-style</guid><category><![CDATA[Node.js]]></category><category><![CDATA[Express]]></category><category><![CDATA[logging]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Tue, 02 Mar 2021 12:50:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1614689371530/f2sJq5TCK.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this cookbook, I am gonna help you setup morgan with express to log HTTP requests like this,</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1614685439439/cRWpbN52u.png" alt="image.png" /></p>
<p>at the end of this post, you will be able to log the following details</p>
<ul>
<li><strong><em>date and time of the request</em></strong> ( formatted as <strong>hh:mm a ddd, MMMM Do YYYY</strong> )</li>
<li><strong><em>HTTP Method</em></strong>  (ex: GET, POST, PUT, DELETE)</li>
<li><strong><em>endpoint path</em></strong> (ex: /, /users, /payments)</li>
<li><strong><em>response time</em></strong> ( The time between the request coming into morgan and when the response headers are written, in milliseconds. )</li>
<li><strong><em>remote-address</em></strong> ( The remote address of the request. This will use req.ip, otherwise the standard req.connection.remoteAddress value.)</li>
<li><strong><em>remote-user</em></strong> ( The user authenticated as part of Basic auth for the request. )</li>
<li><strong><em>user-agent</em></strong> ( The User-Agent request header is a characteristic string that lets servers and network peers identify the application, operating system, vendor, and/or version of the requesting user agent. )</li>
</ul>
<h1 id="install-dependencies">Install Dependencies</h1>
<pre><code><span class="hljs-built_in">npm</span> i morgan moment-timezone

<span class="hljs-comment"># or if you are using yarn</span>
yarn add morgan moment-timezone
</code></pre><h1 id="setting-up-morgan-tokens">Setting up morgan tokens</h1>
<p>morgan logger allows you to customize with the .token() method. The .token() method takes in name of the token as the first argument, following a callback function. morgan will run the callback function each time a log occurs using the token.</p>
<pre><code>morgan.token(<span class="hljs-string">'date'</span>, <span class="hljs-function"><span class="hljs-params">(req, res, tz: string)</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> moment()
    .tz(tz)
    .format(<span class="hljs-string">'hh:mm a ddd, MMMM Do YYYY'</span>);
});
morgan.token(<span class="hljs-string">'splitter'</span>, <span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> {
  <span class="hljs-keyword">return</span> <span class="hljs-string">'\x1b[36m--------------------------------------------\x1b[0m\n'</span>;
});
morgan.token(<span class="hljs-string">'statusColor'</span>, <span class="hljs-function"><span class="hljs-params">(req, res)</span> =&gt;</span> {
  const status = (<span class="hljs-keyword">typeof</span> res.headersSent !== <span class="hljs-string">'boolean'</span>
  ? <span class="hljs-built_in">Boolean</span>(res.header)
  : res.headersSent)
    ? res.statusCode
    : <span class="hljs-literal">undefined</span>;
  const color =
    status &gt;= <span class="hljs-number">500</span>
      ? <span class="hljs-number">31</span>
      : status &gt;= <span class="hljs-number">400</span>
      ? <span class="hljs-number">33</span>
      : status &gt;= <span class="hljs-number">300</span>
      ? <span class="hljs-number">36</span>
      : status &gt;= <span class="hljs-number">200</span>
      ? <span class="hljs-number">32</span>
      : <span class="hljs-number">0</span>;

  <span class="hljs-keyword">return</span> <span class="hljs-string">'\x1b['</span> + color + <span class="hljs-string">'m'</span> + status + <span class="hljs-string">'\x1b[0m'</span>;
});
</code></pre><h1 id="morgan-in-express-middleware">Morgan in express middleware</h1>
<pre><code>  app.use(
    morgan(
      `:splitter :<span class="hljs-type">date</span>[Asia/Kolkata]   \x1b[<span class="hljs-number">33</span>m:<span class="hljs-keyword">method</span>\x1b[<span class="hljs-number">0</span>m \x1b[<span class="hljs-number">36</span>m:url\x1b[<span class="hljs-number">0</span>m :statusColor \x1b[<span class="hljs-number">35</span>m:response-<span class="hljs-type">time</span> ms\x1b[<span class="hljs-number">0</span>m | \x1b[<span class="hljs-number">35</span>m:remote-addr\x1b[<span class="hljs-number">0</span>m | :remote-<span class="hljs-keyword">user</span> | \x1b[<span class="hljs-number">30</span>m:<span class="hljs-keyword">user</span>-agent\x1b[<span class="hljs-number">0</span>m`,
    ),
  );
</code></pre><p>here I have used my local timezone, you can change Asia/Kolkata to your local timezone.</p>
<h2 id="skipping-logs">Skipping logs</h2>
<p>if you want to skip logging a specific request that's called frequently but you don't need to have the log you can use the below code and replace startsWith argument with the request URL of yours</p>
<pre><code>app.use(
    morgan(
      `:splitter :<span class="hljs-type">date</span>[Asia/Kolkata]    \x1b[<span class="hljs-number">33</span>m:<span class="hljs-keyword">method</span>\x1b[<span class="hljs-number">0</span>m \x1b[<span class="hljs-number">36</span>m:url\x1b[<span class="hljs-number">0</span>m :statusColor \x1b[<span class="hljs-number">35</span>m:response-<span class="hljs-type">time</span> ms\x1b[<span class="hljs-number">0</span>m | \x1b[<span class="hljs-number">35</span>m:remote-addr\x1b[<span class="hljs-number">0</span>m | :remote-<span class="hljs-keyword">user</span> | \x1b[<span class="hljs-number">30</span>m:<span class="hljs-keyword">user</span>-agent\x1b[<span class="hljs-number">0</span>m`,
      {
        skip: (req, res) =&gt; {
          <span class="hljs-keyword">return</span> req.originalUrl.startsWith(<span class="hljs-string">'/metrics'</span>);
        },
      },
    ),
  );
</code></pre>]]></content:encoded></item><item><title><![CDATA[Easy steps to make your Node.js express app a lot more secure🔐]]></title><description><![CDATA[In this post, we will look into how to increase the security of the node.js express app in preventing DOS, XSS, SQL injections, and brute force attacks easily by using specific packages.
Preventing DOS Attacks
DOS attacks will crash the server, which...]]></description><link>https://blog.supercharged.dev/easy-steps-to-make-your-nodejs-express-app-a-lot-more-secure</link><guid isPermaLink="true">https://blog.supercharged.dev/easy-steps-to-make-your-nodejs-express-app-a-lot-more-secure</guid><category><![CDATA[Security]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Express]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Tue, 02 Feb 2021 18:00:37 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1612288786559/9erxO4HWu.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this post, we will look into how to increase the security of the node.js express app in preventing DOS, XSS, SQL injections, and brute force attacks easily by using specific packages.</p>
<h1 id="preventing-dos-attacks">Preventing DOS Attacks</h1>
<p>DOS attacks will crash the server, which makes the API's inaccessible. For example, the attacker sends plenty of requests and large amounts of data to overwhelm and exhaust the system resources which will lead to a server crash.</p>
<h3 id="rate-limiting">Rate-limiting</h3>
<p>Rate limiting is a very powerful feature for securing backend APIs from malicious attacks and for handling unwanted streams of requests from users. You can rate limit your API's by using this simple npm package  <a target="_blank" href="https://www.npmjs.com/package/express-rate-limit">express-rate-limit</a>.</p>
<pre><code><span class="hljs-keyword">const</span> express = <span class="hljs-keyword">require</span>(<span class="hljs-string">'express'</span>);
<span class="hljs-keyword">const</span> rateLimt = <span class="hljs-keyword">require</span>(<span class="hljs-string">'express-rate-limit'</span>);

<span class="hljs-keyword">const</span> app = express();

<span class="hljs-keyword">const</span> limiter = rateLimit({
    windowMs: <span class="hljs-number">20</span> * <span class="hljs-number">60</span> * <span class="hljs-number">1000</span>, <span class="hljs-comment">// 20 minutes</span>
    max: <span class="hljs-number">100</span> <span class="hljs-comment">// limit each ip to 100 requests per windowMs</span>
});

app.<span class="hljs-keyword">use</span>(limiter);
</code></pre><h3 id="limit-the-body-payload">Limit the Body payload</h3>
<p> In this type of attack, the server is sent a large payload, which the server then attempts to decode, but is compelled to use an excessive amount of memory, thus overwhelming the system and crashing the service. We can restrict the size of the payload by using the  <a target="_blank" href="https://www.npmjs.com/package/body-parser">body-parser</a>  and also we can restrict it in a web server like Nginx.</p>
<pre><code><span class="hljs-keyword">const</span> bodyParser = <span class="hljs-keyword">require</span>(<span class="hljs-string">'body-parser'</span>)
app.<span class="hljs-keyword">use</span>(bodyParser.json({ limit: <span class="hljs-string">"1mb"</span> }))
</code></pre><h1 id="preventing-xss-attacks">Preventing XSS Attacks</h1>
<p>Untrusted data that is sent down to the browser might get executed instead of just being displayed, this is commonly being referred to as a cross-site-scripting (XSS) attack.</p>
<h3 id="data-validation-and-sanitization">Data Validation and sanitization</h3>
<p>Always perform input data validation and sanitization, use  <a target="_blank" href="https://www.npmjs.com/package/xss">XSS</a>  or  <a target="_blank" href="https://www.npmjs.com/package/xss-clean">xss-clean</a></p>
<pre><code><span class="hljs-keyword">const</span> xss = <span class="hljs-keyword">require</span>(<span class="hljs-string">'xss-clean'</span>)
<span class="hljs-comment">// Make sure that this comes before any other routes</span>
app.<span class="hljs-keyword">use</span>(xss())
</code></pre><h3 id="headers">Headers</h3>
<p>The Content Security Policy
you can apply the HTTP Content-Security-Policy (CSP) header to prevent unauthorized code execution. CSP supports many directives that help you to control how content can be combined in your HTML page.
You can use the  <a target="_blank" href="https://www.npmjs.com/package/helmet">helmet</a> to set up the appropriate header</p>
<pre><code><span class="hljs-keyword">const</span> helmet = <span class="hljs-keyword">require</span>(<span class="hljs-string">'helmet'</span>)
app.<span class="hljs-keyword">use</span>(helmet())
</code></pre><p>Helmet enables the following HTTP headers.</p>
<ul>
<li>Strict-Transport-Security</li>
<li>X-frame-Options</li>
<li>X-XSS-Protection</li>
<li>X-Content-Type-Protection</li>
<li>Content-Security-Policy</li>
<li>Cache-Control</li>
<li>Expect-CT</li>
<li>Disable X-Powered-By</li>
</ul>
<p>These headers prevent malicious users from various types of attacks such as clickjacking, cross-site scripting, etc.</p>
<h1 id="preventing-sqlnosql-injections">Preventing SQL/NoSQL Injections</h1>
<p>To prevent SQL/NoSQL injection and other malicious attacks, always make use of an ORM/ODM or a database library that escapes data or supports named or indexed parameterized queries, and takes care of validating user input for expected types. Never just use JavaScript template strings or string concatenation to inject values into queries as this opens your application to a wide spectrum of vulnerabilities. All the reputable Node.js data access libraries (e.g.  <a target="_blank" href="https://www.npmjs.com/package/sequelize">Sequelize</a> ,  <a target="_blank" href="https://www.npmjs.com/package/knex">Knex</a> ,  <a target="_blank" href="https://www.npmjs.com/package/mongoose">mongoose</a> ) have built-in protection against injection attacks</p>
<h1 id="preventing-brute-force-attacks">Preventing Brute Force Attacks</h1>
<ul>
<li>The most efficient way is to limit the number of login attempts.</li>
<li>Use Bcrypt to encrypt the passwords, which will slow down the attacker when guessing.</li>
<li>You could use express-rate-limit, which works for both DOS attack and brute force attack.</li>
<li>Implement 2 step verification.</li>
</ul>
<h1 id="check-dependencies">Check dependencies</h1>
<p>With the npm ecosystem, it is common to have many dependencies for a project. Dependencies should always be kept in check as new vulnerabilities are found. Use tools like <code>npm audit, nsp, or snyk to track</code>, monitor and patch vulnerable dependencies. Integrate these tools with your CI setup so you catch a vulnerable dependency before it makes it to production.</p>
]]></content:encoded></item><item><title><![CDATA[ESLint and Prettier Setup with Git Pre-commit hook🎣]]></title><description><![CDATA[In this post, we will look at how to integrate ESLint and Prettier into your vs-code setup and project in order to ensure cleaner code and consistent across the team.
We might not be perfect all the time, as developers sometimes we may push code in a...]]></description><link>https://blog.supercharged.dev/eslint-and-prettier-setup-with-git-pre-commit-hook</link><guid isPermaLink="true">https://blog.supercharged.dev/eslint-and-prettier-setup-with-git-pre-commit-hook</guid><category><![CDATA[eslint]]></category><category><![CDATA[Prettier]]></category><category><![CDATA[Visual Studio Code]]></category><category><![CDATA[Git]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Wed, 25 Nov 2020 06:28:42 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1606285898983/fho1KPK_b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this post, we will look at how to integrate ESLint and Prettier into your vs-code setup and project in order to ensure cleaner code and consistent across the team.
We might not be perfect all the time, as developers sometimes we may push code in a hurry and miss like a closing bracket, declaring a variable, or importing a function.
so we will also look at how to ensure code integrity and validity on every commit you make by watching for errors and warnings in your project code by ESlint and Prettier.
First, let us look at what are ESLint and Prettier</p>
<h2 id="eslint">ESLint</h2>
<p>ESLint is a tool for identifying and reporting on patterns found in ECMAScript/JavaScript code, with the goal of making code more consistent and avoiding bugs.  <a target="_blank" href="https://eslint.org/docs/user-guide/getting-started">ESLINT</a> </p>
<h2 id="prettier">Prettier</h2>
<p>Prettier is very popular because it improves code readability and makes the coding style consistent for teams. Developers are more likely to adopt a standard rather than writing their own code style from scratch, so tools like Prettier will make your code look good without you ever having to dabble in the formatting.<a target="_blank" href="https://prettier.io/docs/en/why-prettier.html">Prettier</a> </p>
<h2 id="setting-up-vs-code">Setting up VS-Code</h2>
<p>Make sure you installed the vs code extensions for  <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">Prettier </a> and  <a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint">ESLint</a> .</p>
<h2 id="installing-dev-dependencies">Installing Dev Dependencies</h2>
<p>Make sure you are inside a node project or create a package.json file by running the <strong><em>npm init</em></strong> command and initialize the git by running <strong><em>git init</em></strong>.</p>
<pre><code>npm <span class="hljs-keyword">install</span> -D eslint prettier
npx <span class="hljs-keyword">install</span>-peerdeps <span class="hljs-comment">--dev eslint-config-airbnb</span>
npm <span class="hljs-keyword">install</span> -D eslint-config-prettier eslint-<span class="hljs-keyword">plugin</span>-prettier husky lint-staged
</code></pre><h2 id="configuring-eslint">Configuring ESLint</h2>
<p>Create a file by name <strong><em>.eslintrc.json</em></strong> and copy the below lines into the file</p>
<pre><code>{
  <span class="hljs-attr">"extends"</span>: [<span class="hljs-string">"airbnb"</span>, <span class="hljs-string">"prettier"</span>],
  <span class="hljs-attr">"plugins"</span>: [<span class="hljs-string">"prettier"</span>],
  <span class="hljs-attr">"rules"</span>: {
    <span class="hljs-attr">"prettier/prettier"</span>: [<span class="hljs-string">"error"</span>]
  },
}
</code></pre><h2 id="configuring-prettier">Configuring Prettier</h2>
<p>Create a file by name <strong><em>.prettierrc</em></strong> and copy the below lines into the file</p>
<pre><code>{
  <span class="hljs-attr">"printWidth"</span>: <span class="hljs-number">100</span>,
  <span class="hljs-attr">"singleQuote"</span>: <span class="hljs-literal">true</span>
}
</code></pre><h2 id="enable-format-on-save">Enable format on save</h2>
<p>to quickly format your code you can enable formatOnSave on vs-code which enables formatting when you press <strong><em>CTRL + S</em></strong>. You can enable this in vs-code settings, you can open the setting by <strong><em>CTRL +, </em></strong> and search for formatonsave and enable it.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606286108594/MrERkHigA.png" alt="image.png" /></p>
<h2 id="configure-git-pre-commit-hook">Configure git pre-commit hook</h2>
<p>In package.json on the same level as dependencies paste the following lines</p>
<pre><code><span class="hljs-string">"husky"</span>: {
    <span class="hljs-string">"hooks"</span>: {
      <span class="hljs-string">"pre-commit"</span>: <span class="hljs-string">"lint-staged"</span>
    }
  },
  <span class="hljs-string">"lint-staged"</span>: {
    <span class="hljs-string">"*.{js,jsx,ts,tsx}"</span>: [
      <span class="hljs-string">"eslint --fix"</span>,
      <span class="hljs-string">"prettier --write"</span>
    ]
  }
</code></pre><p>you can skip the pre-commit check while committing if you don't need for a single commit by providing the --no-verify flag</p>
<pre><code>git <span class="hljs-keyword">commit</span> -m "no check" <span class="hljs-comment">--no-verify</span>
</code></pre><h2 id="testing-pre-commit-hook">Testing pre-commit hook</h2>
<p>create an index.js file and copy the contents</p>
<pre><code><span class="hljs-keyword">const</span> fs = <span class="hljs-keyword">require</span>(<span class="hljs-string">'fs'</span>);
<span class="hljs-keyword">const</span> os = <span class="hljs-keyword">require</span>(<span class="hljs-string">'os'</span>);
</code></pre><p>ESLint warns you about the unused variables, as a push first, fix after developer we are gonna commit the files by</p>
<pre><code>git <span class="hljs-keyword">add</span> .
git <span class="hljs-keyword">commit</span> -m "test"
</code></pre><p>Now if everything is working correct you will see this error</p>
<pre><code><span class="hljs-keyword">index</span>.js
  <span class="hljs-number">1</span>:<span class="hljs-number">7</span>  error  <span class="hljs-string">'fs'</span> <span class="hljs-keyword">is</span> assigned a <span class="hljs-keyword">value</span> but never used  <span class="hljs-keyword">no</span>-unused-vars
  <span class="hljs-number">2</span>:<span class="hljs-number">7</span>  error  <span class="hljs-string">'os'</span> <span class="hljs-keyword">is</span> assigned a <span class="hljs-keyword">value</span> but never used  <span class="hljs-keyword">no</span>-unused-vars

✖ <span class="hljs-number">2</span> problems (<span class="hljs-number">2</span> errors, <span class="hljs-number">0</span> warnings)

husky &gt; pre-<span class="hljs-keyword">commit</span> hook failed (<span class="hljs-keyword">add</span> <span class="hljs-comment">--no-verify to bypass)</span>
</code></pre>]]></content:encoded></item><item><title><![CDATA[Add Open Windows Terminal on the context menu📄]]></title><description><![CDATA[I always like shortcuts, and windows terminal by default doesn't add open windows terminal on the context menu. And this little shortcut comes really handy to open the project from the file explorer.
Before we get started
Install Windows terminal fro...]]></description><link>https://blog.supercharged.dev/add-open-windows-terminal-on-the-context-menu</link><guid isPermaLink="true">https://blog.supercharged.dev/add-open-windows-terminal-on-the-context-menu</guid><category><![CDATA[Windows]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Tue, 24 Nov 2020 12:21:48 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1606221698298/5o9KYib9q.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I always like shortcuts, and windows terminal by default doesn't add open windows terminal on the context menu. And this little shortcut comes really handy to open the project from the file explorer.</p>
<h2 id="before-we-get-started">Before we get started</h2>
<p>Install Windows terminal from the  <a target="_blank" href="https://www.microsoft.com/en-in/p/windows-terminal/9n0dx20hk701">Windows Store</a> </p>
<h2 id="create-a-text-file">Create a text file</h2>
<p>create a text file and paste the below lines in the file.
replace {username} with the username of the system you can find it by running <strong><em>echo %USERNAME%</em></strong> in the cmd.</p>
<pre><code>Windows Registry Editor <span class="hljs-keyword">Version</span> <span class="hljs-number">5.00</span>

[HKEY_CLASSES_ROOT\Directory\Background\shell\wt]

@="Open Windows terminal"

"Icon"="C:\\Users\\{username}\\AppData\\Local\\Microsoft\\WindowsApps\\terminal.ico"

[HKEY_CLASSES_ROOT\Directory\Background\shell\wt\command]

@="\"C:\\Users\\{username}}\\AppData\\<span class="hljs-keyword">Local</span>\\Microsoft\\WindowsApps\\wt.exe\" -d %V.\"\""
</code></pre><p>once you have copied it into the text file, now rename the file extension to .reg. If you are unable to do this enable file name extensions in the view panel of the file explorer.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1606220841895/ORz-JWGvx.png" alt="File name extenstion.png" /></p>
<p>once you edited the file extension from .txt to .reg, now run the file.
Windows asks for confirmation, and after you give the green signal you can now see the windows terminal here on the context menu.</p>
]]></content:encoded></item><item><title><![CDATA[Using async-await in array iteration methods [JS]⌚]]></title><description><![CDATA[You are new to the javascript world, and you just found out the simplicity of using array iterations and the clean look they provide. Now, you start async-await in conjunction with array iteration methods, and all of a sudden you start to notice that...]]></description><link>https://blog.supercharged.dev/using-async-await-in-array-iteration-methods-js</link><guid isPermaLink="true">https://blog.supercharged.dev/using-async-await-in-array-iteration-methods-js</guid><category><![CDATA[JavaScript]]></category><category><![CDATA[array]]></category><dc:creator><![CDATA[Sree Teja]]></dc:creator><pubDate>Tue, 24 Nov 2020 07:26:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1606203261595/caUv4H7Mm.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>You are new to the javascript world, and you just found out the simplicity of using array iterations and the clean look they provide. Now, you start async-await in conjunction with array iteration methods, and all of a sudden you start to notice that the result it gives isn't the one you are looking for. Look at the example below</p>
<pre><code><span class="hljs-keyword">const</span> { <span class="hljs-keyword">default</span>: Axios } = require(<span class="hljs-string">'axios'</span>);

<span class="hljs-keyword">const</span> urls = [<span class="hljs-string">'https://supercharged.dev'</span>, <span class="hljs-string">'https://blog.supercharged.dev'</span>];

<span class="hljs-keyword">const</span> getUrlStatus = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> statuses = <span class="hljs-keyword">await</span> urls.map(<span class="hljs-keyword">async</span> (item) =&gt; {
    <span class="hljs-keyword">const</span> urlResponse = <span class="hljs-keyword">await</span> Axios.<span class="hljs-keyword">get</span>(item);
    <span class="hljs-keyword">return</span> urlResponse.status;
  });
  <span class="hljs-keyword">return</span> statuses;
};

<span class="hljs-keyword">const</span> main = <span class="hljs-keyword">async</span> () =&gt; {
  console.log(<span class="hljs-keyword">await</span> getUrlStatus());
};

main();
</code></pre><p>When you run the above example you expect it to provide the status returned by the URL's, but you get the following result</p>
<pre><code>[ Promise { <span class="hljs-tag">&lt;<span class="hljs-name">pending</span>&gt;</span> }, Promise { <span class="hljs-tag">&lt;<span class="hljs-name">pending</span>&gt;</span> } ]
</code></pre><p>The problem here is we are awaiting an array of promises rather than the promise.
To fix this all we have to do is use Promise.all function.</p>
<p>The Promise.all() method takes an iterable of promises as an input and returns a single Promise that resolves to an array of the results of the input promises. This returned promise will resolve when all of the input's promises have resolved, or if the input iterable contains no promises. It rejects immediately upon any of the input promises rejecting or non-promises throwing an error and will reject with this first rejection message/error.  <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all">MDN docs</a></p>
<p>So after making changes to the example above we have</p>
<pre><code><span class="hljs-keyword">const</span> { <span class="hljs-keyword">default</span>: Axios } = require(<span class="hljs-string">'axios'</span>);

<span class="hljs-keyword">const</span> urls = [<span class="hljs-string">'https://supercharged.dev'</span>, <span class="hljs-string">'https://blog.supercharged.dev'</span>];

<span class="hljs-keyword">const</span> getUrlStatus = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> statuses = <span class="hljs-keyword">await</span> Promise.all(
    urls.map(<span class="hljs-keyword">async</span> (item) =&gt; {
      <span class="hljs-keyword">const</span> urlResponse = <span class="hljs-keyword">await</span> Axios.<span class="hljs-keyword">get</span>(item);
      <span class="hljs-keyword">return</span> urlResponse.status;
    })
  );
  <span class="hljs-keyword">return</span> statuses;
};

<span class="hljs-keyword">const</span> main = <span class="hljs-keyword">async</span> () =&gt; {
  console.log(<span class="hljs-keyword">await</span> getUrlStatus());
};

main();
</code></pre><p>And the response is.... <em>(Drumroll 🥁)</em></p>
<pre><code>[ <span class="hljs-number">200</span>, <span class="hljs-number">200</span> ]
</code></pre><p><em>If you want to allow failures in promise.all you can use the below snippet
</em></p>
<pre><code><span class="hljs-keyword">const</span> getUrlStatus = <span class="hljs-keyword">async</span> () =&gt; {
  let statuses = urls.map(<span class="hljs-keyword">async</span> (item) =&gt; {
    <span class="hljs-keyword">const</span> urlResponse = <span class="hljs-keyword">await</span> Axios.<span class="hljs-keyword">get</span>(item);
    <span class="hljs-keyword">return</span> urlResponse.status;
  });
  statuses = <span class="hljs-keyword">await</span> Promise.all(
    statuses.map((promise) =&gt; promise.<span class="hljs-keyword">catch</span>((err) =&gt; <span class="hljs-keyword">null</span>))
  );
  <span class="hljs-keyword">return</span> statuses;
};
</code></pre><p>you will get a null for the promises that failed.</p>
]]></content:encoded></item></channel></rss>