<script data-pm-proxy="intercept"></script><?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" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Implementing]]></title><description><![CDATA[Explore coding tutorials, lessons learned, personal projects and more from a curious software engineer.]]></description><link>https://implementing.substack.com</link><image><url>https://substackcdn.com/image/fetch/$s_!U0Xz!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png</url><title>Implementing</title><link>https://implementing.substack.com</link></image><generator>Substack</generator><lastBuildDate>Thu, 03 Sep 2026 03:23:43 GMT</lastBuildDate><atom:link href="/__u/implementing.substack.com/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[Marco Moauro]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[implementing@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[implementing@substack.com]]></itunes:email><itunes:name><![CDATA[Marco Moauro]]></itunes:name></itunes:owner><itunes:author><![CDATA[Marco Moauro]]></itunes:author><googleplay:owner><![CDATA[implementing@substack.com]]></googleplay:owner><googleplay:email><![CDATA[implementing@substack.com]]></googleplay:email><googleplay:author><![CDATA[Marco Moauro]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[Sync GitHub Dependabot alerts into Asana]]></title><description><![CDATA[An open-source tool that bridges Dependabot alerts into the workflow tool your team already uses. One Docker command.]]></description><link>https://implementing.substack.com/p/sync-github-dependabot-alerts-into-your-workflow</link><guid isPermaLink="false">https://implementing.substack.com/p/sync-github-dependabot-alerts-into-your-workflow</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 25 May 2026 05:57:51 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/6c738e09-41c8-4c82-8fa3-c1f9b3a5dc77_1708x1001.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I&#8217;m <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>A few months ago I noticed the same pattern across multiple teams:</p><p>Dependabot alerts were technically enabled, but nobody was really looking at them.</p><p>Not because people didn&#8217;t care about security. The problem was simpler: developers spend their day in Asana, Jira, or Linear, not in GitHub&#8217;s Security tab.</p><p>So vulnerabilities stayed open for weeks, sometimes months, and eventually became background noise.</p><p>To fix that, I built <strong>security-workflow-sync</strong>.</p><p>It&#8217;s a small open source tool that reads Dependabot alerts from GitHub and syncs them into the workflow system your team already uses.</p><p>Today it supports Asana. Jira, Linear, and GitHub Issues are planned next.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h1>&#128295; The solution</h1><p><strong>security-workflow-sync</strong> connects GitHub Dependabot with your task management tool.</p><p>It fetches open Dependabot alerts from a GitHub organization and creates matching tasks in Asana.</p><p>The tool itself does not scan dependencies and it does not replace existing security tooling. Dependabot still handles detection. This project only handles synchronization and task ownership.</p><p>Everything runs from a single Docker command, so you can run it locally, from CI, or from a scheduled cron job.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!IIah!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!IIah!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png 424w, /__u/substackcdn.com/image/fetch/$s_!IIah!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png 848w, /__u/substackcdn.com/image/fetch/$s_!IIah!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png 1272w, /__u/substackcdn.com/image/fetch/$s_!IIah!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!IIah!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png" width="1456" height="627" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:627,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:799341,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://implementing.substack.com/i/199045992?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!IIah!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png 424w, /__u/substackcdn.com/image/fetch/$s_!IIah!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png 848w, /__u/substackcdn.com/image/fetch/$s_!IIah!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png 1272w, /__u/substackcdn.com/image/fetch/$s_!IIah!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62696686-8a9f-4c0e-8944-3aae6b6c23ae_1696x730.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Dependabot handles detection. security-workflow-sync handles ownership and synchronization.</figcaption></figure></div><div><hr></div><h2>&#128273; Prerequisites</h2><p>Before running the tool, two things must be enabled on the GitHub side for each repository you want to monitor:</p><ul><li><p><strong>Dependency graph</strong>: GitHub parses your manifest files (package.json, requirements.txt, pom.xml, &#8230;)</p></li><li><p><strong>Dependabot alerts</strong>: GitHub matches your dependencies against the Advisory Database and produces alerts</p></li></ul><p>Both settings can be enabled at organization level.</p><p>One important detail: enable &#8220;Automatically enable for new repositories&#8221;, otherwise newly-created repositories will silently miss Dependabot coverage.</p><p>You'll also need a GitHub Personal Access Token with the `security_events` scope (authorized for the organization) and an Asana Personal Access Token.</p><h3>&#128230; Step 1: Bootstrap the Asana project</h3><p>The `bootstrap` command creates a new Asana project with the right sections and custom fields. Run it once:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;76da8872-bb0c-40f1-b154-be768f193115&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">docker run --rm --pull always \
  -e ASANA_ACCESS_TOKEN=... \
  marcomoauro/security-workflow-sync:latest bootstrap</code></pre></div><p>If your token has access to a single Asana workspace, it gets auto-detected. If you belong to multiple workspaces, the command lists them and asks you to pick one via <code>ASANA_WORKSPACE_GID</code>.</p><p>The command prints the generated <code>ASANA_PROJECT_GID</code>. You&#8217;ll need it for the sync step.</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;1ccef658-bf6f-4db1-8b69-993bdf95b3f7&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">marcomoauro@MacBook-Pro-2 ~ % docker run --rm --pull always \              
  -e ASANA_ACCESS_TOKEN=XYZ \                   
  marcomoauro/security-workflow-sync:latest bootstrap
[info] Auto-detected Asana workspace: Acme (991745504083).
[info] Creating Asana project "Security Findings" in workspace 991745504083&#8230;
[info] Created project 1215096078675826.
[info] Created section "Critical".
[info] Created section "High".
[info] Created section "Medium".
[info] Created section "Low".
[info] Created section "Team Assignment".
[info] Reusing existing custom field "SWS: Severity" (1215098554617643).
[info] Reusing existing custom field "SWS: Repository" (1215095156543835).
[info] Reusing existing custom field "SWS: Package" (1215095954783217).
[info] Reusing existing custom field "SWS: Tech Team" (1215094188188106).
[info] Reusing existing custom field "SWS: Advisory" (1215294138228970).
[info] Reusing existing custom field "SWS: Advisory URL" (1245094997344211).
[info] Reusing existing custom field "SWS: Deduplication ID" (1215194138115263).

Bootstrap complete.
Export the following env var when running `sws sync`:

  ASANA_PROJECT_GID=1215093077675836

Next steps:
  1. Run `sws sync` to pull current Dependabot alerts into the project.
     The first sync also creates one placeholder task in the "Team Assignment"
     section for each repository it encounters.
  2. After that first sync, open the Asana project and set the
     "SWS: Tech Team" field on each placeholder.
  3. From the next sync onward, every alert for that repository will
     inherit the team automatically.</code></pre></div><h3>&#128260; Step 2: Sync</h3><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;b64ec570-0909-456e-9cda-5008ef0e3786&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">docker run --rm --pull always \
  -e GITHUB_TOKEN=... \
  -e GITHUB_ORG=... \
  -e ASANA_ACCESS_TOKEN=... \
  -e ASANA_PROJECT_GID=... \
  marcomoauro/security-workflow-sync:latest sync</code></pre></div><p>The first sync creates one task for each open vulnerability and places it into the corresponding severity section.</p><p>The task name follows the format <code>[Severity] package - owner/repo</code>. </p><p>The task notes include:</p><ul><li><p>advisory link</p></li><li><p>vulnerable version range</p></li><li><p>affected manifest files</p></li><li><p>first patched version.</p></li></ul><p>Running the sync multiple times is safe. Existing alerts are updated instead of recreated.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!0RI6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!0RI6!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png 424w, /__u/substackcdn.com/image/fetch/$s_!0RI6!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png 848w, /__u/substackcdn.com/image/fetch/$s_!0RI6!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png 1272w, /__u/substackcdn.com/image/fetch/$s_!0RI6!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!0RI6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png" width="1456" height="1057" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1057,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:400273,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://implementing.substack.com/i/199045992?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!0RI6!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png 424w, /__u/substackcdn.com/image/fetch/$s_!0RI6!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png 848w, /__u/substackcdn.com/image/fetch/$s_!0RI6!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png 1272w, /__u/substackcdn.com/image/fetch/$s_!0RI6!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffb2c9a88-b906-4a16-a2a0-e8a909189d76_2182x1584.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2><strong>&#128101; Team ownership</strong></h2><p>When the sync sees a repository for the first time, it creates a placeholder record in the <strong>Team Assignment</strong> section with the repo name. You manually set the <strong>Tech Team</strong> value on that placeholder once.</p><p>From that moment, every alert for that repository automatically inherits the assigned team, including across syncs and reopened alerts. The team field is <strong>append-only</strong>: once set, the tool never overwrites it on individual tasks. Manual edits made directly inside Asana stick.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!C-0v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!C-0v!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png 424w, /__u/substackcdn.com/image/fetch/$s_!C-0v!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png 848w, /__u/substackcdn.com/image/fetch/$s_!C-0v!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png 1272w, /__u/substackcdn.com/image/fetch/$s_!C-0v!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!C-0v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png" width="1456" height="809" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:809,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:186512,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://implementing.substack.com/i/199045992?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!C-0v!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png 424w, /__u/substackcdn.com/image/fetch/$s_!C-0v!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png 848w, /__u/substackcdn.com/image/fetch/$s_!C-0v!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png 1272w, /__u/substackcdn.com/image/fetch/$s_!C-0v!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a37f281-bbb3-473c-ad6d-d06a6b4e848c_2146x1192.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This avoids having to assign ownership manually for every new alert.</p><div><hr></div><h2><strong>&#127919; Filtering by repository</strong></h2><p>If you want to roll this out gradually, you can limit the sync to a subset of repositories:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;bash&quot;,&quot;nodeId&quot;:&quot;fd4f0338-7df5-448e-a003-6874798f1655&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-bash">docker run --rm --pull always &lt;env vars&gt; marcomoauro/security-workflow-sync:latest sync \
  --include-repos acme/web-app,acme/billing-service</code></pre></div><p>When <code>--include-repos</code> is set, the tool fetches alerts only from those repos via GitHub&#8217;s per-repo Dependabot endpoint. For small rollouts this is also much faster than scanning the whole organization.</p><p><code>--exclude-repos</code> can be used to skip archived or noisy repositories.</p><div><hr></div><h2><strong>&#128336; Putting it on a cron</strong></h2>
      <p>
          <a href="/__u/implementing.substack.com/p/sync-github-dependabot-alerts-into-your-workflow">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[3 Essential Alarms for your AWS SQS Queue]]></title><description><![CDATA[Create them with the Serverless Framework!]]></description><link>https://implementing.substack.com/p/3-essential-alarms-for-aws-sqs-queue</link><guid isPermaLink="false">https://implementing.substack.com/p/3-essential-alarms-for-aws-sqs-queue</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 23 Jun 2025 06:12:15 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/61b0d84d-ff9f-4346-9f87-71a73fec4562_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>When implementing event driven architectures based on queues, it is essential to monitor that the pipeline is functioning.</p><p>For AWS queues using the SQS service, you can create these <strong>3</strong> <strong>Cloudwatch</strong> alarms to help you ensure everything is working correctly:</p><ul><li><p>Message production</p></li><li><p>Consumer is inactive, there are messages in the queue but the consumer is not retriev&#8230;</p></li></ul>
      <p>
          <a href="/__u/implementing.substack.com/p/3-essential-alarms-for-aws-sqs-queue">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[MCP Server for Substack]]></title><description><![CDATA[Automate post drafts creation and more!]]></description><link>https://implementing.substack.com/p/mcp-server-for-substack</link><guid isPermaLink="false">https://implementing.substack.com/p/mcp-server-for-substack</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 19 May 2025 06:13:16 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f7bb2d14-423d-4288-841c-3b5b69976a1e_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>In this episode, I'm going to introduce you to the MCP server that I made for Substack.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/substack-mcp">https://github.com/marcomoauro/substack-mcp</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2><strong>&#128274; Substack lacks public APIs</strong></h2><p>Substack lacks public APIs, so I reverse-engineered the platform to understand the data exchanged between the platform's UI and backend. </p><p>This allowed me to use the same mechanism to request operations.</p><p>I've discovered that the session is managed through a cookie, which is exchanged in all calls between the client and the backend. This cookie is used to verify if the user is authenticated and authorized for the operations they're requesting.</p><blockquote><p>Using the same mechanism, I created an e-mail sequence platform for Substack that allows for creating customized workflows to send e-mails every day. </p><p>You can find the post here:</p></blockquote><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a956b018-4f02-4236-8f05-32e6b97e6358&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter!&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;How to Create Email Sequences on Substack&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 10+ years of experience in software design and development. The solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null},{&quot;id&quot;:6835984,&quot;name&quot;:&quot;Luca Rossi&quot;,&quot;bio&quot;:&quot;I write everyday about how to make great software and work well with humans, to 60K+ friends.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6107486-b701-4109-8f21-f450fed6e277_652x690.png&quot;,&quot;is_guest&quot;:true,&quot;bestseller_tier&quot;:1000,&quot;primaryPublicationSubscribeUrl&quot;:&quot;https://refactoring.fm/subscribe?&quot;,&quot;primaryPublicationUrl&quot;:&quot;https://refactoring.fm&quot;,&quot;primaryPublicationName&quot;:&quot;Refactoring&quot;,&quot;primaryPublicationId&quot;:64099}],&quot;post_date&quot;:&quot;2024-02-12T06:39:14.998Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b994c390-af59-460f-9466-4ddbb4aea628_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/how-to-create-email-sequences-on&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:141435927,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:17,&quot;comment_count&quot;:5,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div><hr></div><h2><strong>&#128421;&#65039; What is an MCP Server?</strong></h2><p>as well explained by <a href="https://modelcontextprotocol.io/introduction">modelcontextprotocol.io</a>:</p><blockquote><p>MCP is an open protocol that standardizes how applications provide context to LLMs. It provides a standardized way to connect AI models to different data sources and tools.</p><p>MCP follows a client-server architecture where a host application can connect to multiple servers:</p><ul><li><p><strong>MCP Hosts</strong>: Programs like Claude Desktop, IDEs, or AI tools that want to access data through MCP</p></li><li><p><strong>MCP Clients</strong>: Protocol clients that maintain 1:1 connections with servers</p></li><li><p><strong>MCP Servers</strong>: Lightweight programs that each expose specific capabilities through the standardized Model Context Protocol</p></li><li><p><strong>Local Data Sources</strong>: Your computer&#8217;s files, databases, and services that MCP servers can securely access</p></li><li><p><strong>Remote Services</strong>: External systems available over the internet (e.g., through APIs) that MCP servers can connect to</p></li></ul></blockquote><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!omMX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!omMX!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png 424w, /__u/substackcdn.com/image/fetch/$s_!omMX!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png 848w, /__u/substackcdn.com/image/fetch/$s_!omMX!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png 1272w, /__u/substackcdn.com/image/fetch/$s_!omMX!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!omMX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png" width="568" height="387.19767441860466" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:938,&quot;width&quot;:1376,&quot;resizeWidth&quot;:568,&quot;bytes&quot;:106358,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://implementing.substack.com/i/163262717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!omMX!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png 424w, /__u/substackcdn.com/image/fetch/$s_!omMX!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png 848w, /__u/substackcdn.com/image/fetch/$s_!omMX!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png 1272w, /__u/substackcdn.com/image/fetch/$s_!omMX!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fb265c64a-8d99-4f7a-9f2b-7d568de32cee_1376x938.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">ref: <a href="https://modelcontextprotocol.io/introduction">https://modelcontextprotocol.io/introduction</a></figcaption></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128273; <strong>Retrieve your Substack credentials</strong></h2><p>To use the server, you need to retrieve 3 parameters:</p><ul><li><p>Session token</p></li><li><p>Publication URL</p></li><li><p>User ID</p></li></ul><h4>Session token</h4><p>This information is exchanged in all authenticated calls between the UI and the backend. You can retrieve it using your browser's devtools, such as Chrome in my case.</p><p>Go to <em>Network</em>, filter the calls by <em>Fetch/XHR</em> and look for the call <em><strong>drafts?offset=.....</strong></em></p><p>Among the request headers, look for <em>Cookie</em>, which contains a list of information in the <em>&#8220;key=value;&#8221;</em> format. From these, retrieve the session token found in the <strong>substack.sid</strong> or <strong>connect.sid</strong> key. Only one of these will be present, so simply retrieve the value you find!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!MAce!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!MAce!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png 424w, /__u/substackcdn.com/image/fetch/$s_!MAce!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png 848w, /__u/substackcdn.com/image/fetch/$s_!MAce!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png 1272w, /__u/substackcdn.com/image/fetch/$s_!MAce!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!MAce!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png" width="642" height="459.0123626373626" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1041,&quot;width&quot;:1456,&quot;resizeWidth&quot;:642,&quot;bytes&quot;:225365,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://implementing.substack.com/i/163262717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!MAce!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png 424w, /__u/substackcdn.com/image/fetch/$s_!MAce!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png 848w, /__u/substackcdn.com/image/fetch/$s_!MAce!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png 1272w, /__u/substackcdn.com/image/fetch/$s_!MAce!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3875ece2-13a2-4272-8486-060a76dbc13f_2272x1624.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>In my case, I have the substack.sid cookie. Please note the value we'll need later for the MCP Server.</p><h4>Publication URL</h4><p>This is the domain of your newsletter, which you can find in the address bar. In my case, it's <strong>https://implementing.substack.com</strong></p><h4>User ID</h4><p>Just like the Session token process, open the network and search for the <em>publication_user</em> call. </p><p>Go to the response, <em>Preview</em> section, and retrieve the <strong>id</strong> from the <strong>user</strong> key. If you have multiple users in your newsletter, retrieve the id associated with the user with your name.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!pKjy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!pKjy!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png 424w, /__u/substackcdn.com/image/fetch/$s_!pKjy!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png 848w, /__u/substackcdn.com/image/fetch/$s_!pKjy!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png 1272w, /__u/substackcdn.com/image/fetch/$s_!pKjy!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!pKjy!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png" width="683" height="392.1620879120879" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:836,&quot;width&quot;:1456,&quot;resizeWidth&quot;:683,&quot;bytes&quot;:225660,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://implementing.substack.com/i/163262717?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!pKjy!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png 424w, /__u/substackcdn.com/image/fetch/$s_!pKjy!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png 848w, /__u/substackcdn.com/image/fetch/$s_!pKjy!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png 1272w, /__u/substackcdn.com/image/fetch/$s_!pKjy!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4c261142-9833-437a-a30b-d114d0408c40_2498x1434.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2><strong>&#128216; How to start the MCP server</strong></h2><p>You can use the MCP server in two ways, via <em>NPX</em> (Node.js) or via <em>Docker</em>.</p><h4>NPX (Node.js)</h4>
      <p>
          <a href="/__u/implementing.substack.com/p/mcp-server-for-substack">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Deploy AWS SQS Queue with Serverless framework]]></title><description><![CDATA[Deploy FIFO queue - Edition #32]]></description><link>https://implementing.substack.com/p/deploy-aws-sqs-queue-with-serverless</link><guid isPermaLink="false">https://implementing.substack.com/p/deploy-aws-sqs-queue-with-serverless</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 22 Jul 2024 05:36:57 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/01a6880b-87cd-434f-96cb-eb7395cd9b73_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I show you how to deploy a FIFO queue with a producer and a consumer with the Serverless framework.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/sqs-queue-lambda">https://github.com/marcomoauro/sqs-queue-lambda</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128260; What are Queues?</h2><p>A queue is an architecture component that manages tasks or messages in a specific order. </p><p>Queues are helpful because they allow systems to handle tasks efficiently and avoid being overwhelmed. They make sure that tasks are completed in the right order and can be processed when resources are available. </p><p>This leads to better performance, easier management of tasks, and more reliable systems.</p><p>Advantages of using queues<strong>:</strong></p><ul><li><p><strong>Load Balancing:</strong> By managing the flow of tasks, queues prevent systems from being overloaded. When too many tasks arrive, the queue holds them until the system is ready to handle them, thus maintaining a balanced workload and preventing crashes or slowdowns.</p></li><li><p><strong>Reliability:</strong> Queues ensure that every task gets processed, even if the system is busy or experiencing issues. This reduces the risk of losing tasks and ensures that all operations are completed successfully.</p></li><li><p><strong>Scalability:</strong> Queues can handle a growing number of tasks without a drop in performance. As the demand on the system increases, queues allow it to scale up smoothly, ensuring that additional tasks are managed efficiently.</p></li><li><p><strong>Decoupling producer and consumer rates:</strong> Queues allow the producer and consumer to operate at different speeds. If the producer generates tasks faster than the consumer can process them, the queue temporarily stores the excess tasks until the consumer is ready. This decoupling helps manage traffic spikes allowing the system to handle peak loads without overwhelming the consumer. Only the component producing messages needs to be scaled, while the consumer can remain unchanged.</p></li></ul><h4>AWS Simple Queue Service (SQS)</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Yvsq!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Yvsq!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png 424w, /__u/substackcdn.com/image/fetch/$s_!Yvsq!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png 848w, /__u/substackcdn.com/image/fetch/$s_!Yvsq!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Yvsq!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Yvsq!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png" width="578" height="274.705376344086" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:442,&quot;width&quot;:930,&quot;resizeWidth&quot;:578,&quot;bytes&quot;:74885,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Yvsq!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png 424w, /__u/substackcdn.com/image/fetch/$s_!Yvsq!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png 848w, /__u/substackcdn.com/image/fetch/$s_!Yvsq!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Yvsq!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9a7b4acf-35e6-478f-80a4-7dbbca530aef_930x442.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>SQS is a cloud service that helps manage and store messages between software components. It ensures that messages are sent and received reliably. </p><p>SQS offers two types of queues: <strong>Standard</strong> and <strong>FIFO</strong>. </p><ul><li><p><strong>Standard queue</strong>:</p></li></ul><p>Standard queues provide high throughput, allowing a large number of messages to be processed quickly. </p><p>They are designed for applications where occasional duplicate messages and out-of-order processing are acceptable. This type of queue is ideal for scenarios where speed and scalability are important, such as processing tasks in parallel or distributing work across multiple consumers. </p><p>Messages are delivered <strong>at least once </strong>and there is <strong>no guarantee of the order of delivery</strong>.</p><ul><li><p><strong>FIFO queue</strong>:</p></li></ul><p>FIFO (First In First Out) queues ensure that messages are processed exactly once and in the exact order they are sent. </p><p>This makes them suitable for tasks that require strict order and exactly once processing, such as financial transactions or inventory updates. </p><p>FIFO queues have a limited throughput compared to <strong>Standard</strong> queues, but they provide stronger guarantees about message delivery and processing. </p><p><strong>Each message is delivered once</strong> and remains available until it is processed and deleted.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128104;&#8205;&#128187; Let's implement together</h2><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/sqs-queue-lambda">https://github.com/marcomoauro/sqs-queue-lambda</a></p></blockquote><p>We implement a Lambda function that exposes an API via AWS API Gateway to process HTTP calls and queue messages. </p><p>The presence of a queued message triggers a second Lambda function, which acts as the consumer of the message.</p><h4>serverless.yml</h4><p>We can create resources in this way:</p><pre><code>org: implementing
service: sqs-queue-lambda

provider:
  name: aws
  runtime: nodejs20.x
  region: eu-west-2
  tags:
    Name: sqs-queue-lambda
  environment:
    QUEUE_URL: ${self:custom.queue.url}
  iamRoleStatements:
    - Effect: "Allow"
      Action:
        - sqs:SendMessage
      Resource: ${self:custom.queue.arn}

plugins:
  - serverless-offline

resources:
  Resources:
    queue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: queue.fifo
        FifoQueue: true

functions:
  app:
    handler: lambda.handler
    events:
      - httpApi:
          path: /{proxy+}
          method: ANY
  consumer:
    handler: consumer.handler
    events:
      - sqs:
          arn: ${self:custom.queue.arn}
          batchSize: 1

custom:
  serverless-offline:
    reloadHandler: true
  queue:
    arn: !GetAtt queue.Arn
    url: !Ref queue</code></pre><ul><li><p>Queue definition:</p></li></ul>
      <p>
          <a href="/__u/implementing.substack.com/p/deploy-aws-sqs-queue-with-serverless">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Deploy AWS DynamoDB Table with Serverless framework]]></title><description><![CDATA[Deploy DynamoDB table - Edition #31]]></description><link>https://implementing.substack.com/p/deploy-aws-dynamodb-table-with-serverless</link><guid isPermaLink="false">https://implementing.substack.com/p/deploy-aws-dynamodb-table-with-serverless</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 15 Jul 2024 05:39:37 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/69961953-ae0d-4359-9bb8-e4bf330b6299_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I&#8217;ll show you how to deploy a DynamoDB table and how to configure a Lambda that reads and writes to it.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/lambda-dynamodb">https://github.com/marcomoauro/lambda-dynamodb</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128452;&#65039; DynamoDB</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!63m2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!63m2!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png 424w, /__u/substackcdn.com/image/fetch/$s_!63m2!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png 848w, /__u/substackcdn.com/image/fetch/$s_!63m2!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png 1272w, /__u/substackcdn.com/image/fetch/$s_!63m2!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!63m2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png" width="574" height="273.38321167883214" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:522,&quot;width&quot;:1096,&quot;resizeWidth&quot;:574,&quot;bytes&quot;:138467,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!63m2!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png 424w, /__u/substackcdn.com/image/fetch/$s_!63m2!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png 848w, /__u/substackcdn.com/image/fetch/$s_!63m2!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png 1272w, /__u/substackcdn.com/image/fetch/$s_!63m2!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4f5d666e-de48-4ea1-86e1-0c3fbbb2c307_1096x522.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Ref: <a href="https://abiabi0707.medium.com/overview-of-aws-dynamodb-844bf943f209">https://abiabi0707.medium.com/overview-of-aws-dynamodb-844bf943f209</a></figcaption></figure></div><p>DynamoDB is a NoSQL database service provided by Amazon Web Services. </p><p>It is fully managed, which means AWS takes care of all the maintenance and scaling, so you don't have to worry about managing the infrastructure. </p><p>It&#8217;s schemaless, meaning it does not require a fixed data structure, making it flexible to store different types of data.</p><h4>Partition key and sort key</h4><p>In DynamoDB, data is organized using a primary key, which can be a partition key alone or a combination of a partition key and a sort key. </p><ul><li><p><strong>partition key</strong>:</p></li></ul><p>The partition key is a unique identifier for each item in the table and determines how data is distributed across partitions. This helps ensure even distribution and efficient access. </p><p>The partition key must be unique for each item in the table when used alone.</p><ul><li><p><strong>sort key</strong>:</p></li></ul><p>The sort key is used in combination with the partition key to create a composite primary key. This allows multiple items with the same partition key to be stored, with the sort key providing additional uniqueness and enabling items to be sorted within each partition.</p><p>The sort key allows you to perform more refined queries, such as retrieving items within a specific range, filtering results based on sort key values and sorting.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><h4>Search operators: Query and Scan</h4><p>In DynamoDB, searching data can be done using two main operations: Query and Scan. </p><ul><li><p><strong>query</strong>:</p></li></ul><p>The Query operation is efficient and retrieves items based on the primary key values, which can include both the partition key and sort key. By specifying the partition key, you can quickly find all items that share the same partition key value.</p><p>Additionally, you can use conditions on the sort key to filter the results. </p><p>Query are ideal when you know the specific partition key value and optionally want to filter or sort items within that partition.</p><ul><li><p><strong>scan</strong>:</p></li></ul><p>The Scan operation, on the other hand, examines every item in the table. While this can retrieve all items that match the specified criteria, it is less efficient than Query, especially for large datasets, because it must read every item in the table. </p><p>Scans are useful when you need to retrieve a broad set of data and don't have a specific partition key to narrow down the search.</p><p>It is more flexible but should be used sparingly due to their higher resource consumption and slower performance compared to Query.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128104;&#8205;&#128187; Let's implement together</h2><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/lambda-dynamodb">https://github.com/marcomoauro/lambda-dynamodb</a></p></blockquote><p>I show you how to create a DynamoDB table and a Lambda that can read and write to it.</p><h4>DynamoDB table Users</h4><p>We add the following resource to the serverless.yml file:</p><pre><code>(serverless.yml)
...

resources:
  Resources:
    DynamoDBTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: UsersTable
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
...</code></pre><p>This small snippet lets us define the UsersTable. </p><p>The <strong>AttributeDefinitions</strong> and <strong>KeySchema</strong> sections define the table's structure, only the fields for the partition key and sort key are required; other fields can be added later.</p><p>In this case, we've set the <strong>id</strong> field as a string (S) and as the partition key (HASH). Since there's no sort key, this means we can have at most one user with the same id.</p><p>With &#8220;<strong>BillingMode: PAY_PER_REQUEST&#8221;</strong> you are charged based on the actual read and write requests your application makes to the table, rather than provisioning a fixed amount of read and write capacity units.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><h4>Lambda</h4><p>Similarly to what we saw in the last episode we define a lambda that will act as a wrapper for the entire Koa.js application:</p>
      <p>
          <a href="/__u/implementing.substack.com/p/deploy-aws-dynamodb-table-with-serverless">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Deploy a Koa.js server on an AWS Lambda function using Serverless]]></title><description><![CDATA[Deploy Koa.js server - Edition #30]]></description><link>https://implementing.substack.com/p/deploy-koajs-server-aws-lambda-using-serverless</link><guid isPermaLink="false">https://implementing.substack.com/p/deploy-koajs-server-aws-lambda-using-serverless</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 08 Jul 2024 05:43:58 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/bffb6854-f7e1-4b36-92c0-0c94b476a652_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I show you how to deploy your Koa.js application in a Lambda function with AWS.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/lambda-node-backend-template">https://github.com/marcomoauro/lambda-node-backend-template</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>In the previous episode, we saw how to deploy a Lambda function using Serverless, with the trigger calling a function in a JavaScript module.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;baae4d6a-49a4-4752-b495-64084d04cf6a&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Deploy AWS Lambda functions with Serverless Framework and Node.js&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-07-01T05:36:59.234Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b1b97f96-6374-442e-8fbf-434caea3bdf8_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/deploy-aws-lambda-functions-with-serverless-node&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:145972538,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:10,&quot;comment_count&quot;:2,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><pre><code>(serverless.yml)
...

functions:
  hello:
    handler: handler.hello
...

(handler.js)
...
export const hello = async (event) =&gt; {
  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Hello from Implementing!'
    })
  };
};
...</code></pre><p>With the Serverless framework it is also possible to deploy applications made with technologies such as Express, Koa.js and many others, with minimal overhead.</p><p>The result will be a single Lambda function will be deployed that exposes the application and delegates routing management to it, if configured appropriately.</p><p>In this way, development can continue as usual with minimal changes to the developer experience, making it easy to introduce the framework even to teams unfamiliar with Serverless technology.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128104;&#8205;&#128187; Let's implement together</h2><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/lambda-node-backend-template">https://github.com/marcomoauro/lambda-node-backend-template</a></p></blockquote><p>The structure of the application is similar to the one I use in all my projects that I then deploy on Heroku, a detailed explanation can be found here:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;6577b90f-48ff-4920-a62c-c6633f94a38b&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;My Backend Template for Node.js&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-01-08T06:33:29.923Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9763a243-10fc-46c4-b67b-5ee83413e1e6_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/my-backend-template-for-nodejs&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:140322610,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:4,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h4>Create Koa.js app</h4><p>Similar to the template I always use, the only difference is that the app created with the <strong>Koa</strong> library is not used to create an HTTP server. </p><p>Middleware and routes are registered in the app and then exported:</p><pre><code>import cors from '@koa/cors';
import Koa from 'koa';
import json from 'koa-better-json';
import {koaBody} from 'koa-body';
import {APIError404, APIError405, APIError415, apiErrorManager} from './errors.js';
import <em>log </em>from './log.js';
import {
  initAsyncStorage,
  logIncomingCall,
  <em>routeSummaryLog
</em>} from './middlewares.js';
import <em>router </em>from './router.js';

<em>process</em>.on('uncaughtException', (e) =&gt; <em>log</em>.error('uncaughtException', e));
<em>process</em>.on('unhandledRejection', (e) =&gt; <em>log</em>.error('unhandledRejection', e));

const <em>app </em>= new Koa();

const body_limits = {
  formLimit: '64mb',
  jsonLimit: '64mb',
  formidable: {maxFileSize: '64mb', multiples: true},
  multipart: true,
};

<em>app</em>.use(cors({exposeHeaders: ['x-version']}));
<em>app</em>.use(koaBody(body_limits));
<em>app</em>.use(json());
<em>app</em>.use(initAsyncStorage);
<em>app</em>.use(<em>routeSummaryLog</em>);
<em>app</em>.use(logIncomingCall);

<em>app</em>.use(async (ctx, next) =&gt; {
  try {
    ctx.set('x-version', <em>process</em>.env.npm_package_version);
    await next();
    if (!ctx.body) {
      // if body is not defined at this moment, it means that no route matched the request, so a 404 error is fired.
      throw new APIError404();
    }
  } catch (error) {
    apiErrorManager(ctx, error); // error handler
  }
});

<em>app</em>.use(<em>router</em>.routes());
<em>app</em>.use(
  <em>router</em>.allowedMethods({
    throw: true,
    notImplemented: () =&gt; new APIError415(),
    methodNotAllowed: () =&gt; new APIError405(),
  }),
);

export default <em>app</em>;</code></pre><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><h4>Expose app with serverless-http</h4><p>To expose the app we can use the <a href="https://www.npmjs.com/package/serverless-http">serverless-http</a>, this library allows you to &#8220;wrap&#8221; your API for serverless use.</p><p>We can install it by executing:</p><pre><code>npm i serverless-http</code></pre><p>We create a <strong>lambda.js</strong> module like this one:</p><pre><code>import slsHttp from 'serverless-http'
import <em>app </em>from './src/app.js'

export const <em>handler </em>= slsHttp(<em>app</em>)</code></pre><p>and we will configure the handler in the <strong>serverless.yml</strong> configuration file:</p><pre><code>(serverless.yml)
...

functions:
  app:
    <strong>handler: lambda.handler</strong>
    events:
      - httpApi:
          path: /{proxy+}
          method: ANY

...</code></pre><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><h4>Environmental variables management</h4>
      <p>
          <a href="/__u/implementing.substack.com/p/deploy-koajs-server-aws-lambda-using-serverless">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Deploy AWS Lambda functions with Serverless Framework and Node.js]]></title><description><![CDATA[Deploy test lambda - Edition #29]]></description><link>https://implementing.substack.com/p/deploy-aws-lambda-functions-with-serverless-node</link><guid isPermaLink="false">https://implementing.substack.com/p/deploy-aws-lambda-functions-with-serverless-node</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 01 Jul 2024 05:36:59 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/b1b97f96-6374-442e-8fbf-434caea3bdf8_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, you will learn how to deploy Lambda functions so that they can be invoked via an HTTP call using the AWS API Gateway.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/hello-world-lambda">https://github.com/marcomoauro/hello-world-lambda</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>Serverless technology is very interesting because it allows you to focus on your product goals without worrying about managing servers. This makes the development process much easier and more enjoyable. I discovered the benefits of serverless computing thanks to a <a href="https://www.linkedin.com/in/andrea-valenzi/">former colleague</a> who introduced me to it.</p><p>I will guide you through the process of creating and deploying your first AWS Lambda function. </p><p>You will learn how to set up the function so it can be invoked through an HTTP call using AWS API Gateway. This will be a great starting point for understanding how serverless applications work and how you can leverage them to build scalable and efficient solutions.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128104;&#8205;&#128187; Let's implement together</h2><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/hello-world-lambda">https://github.com/marcomoauro/hello-world-lambda</a></p></blockquote><p>You will need the setup I showed here:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a1b3bae0-3bb1-499c-80d1-22f6320c7f8a&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;How to setup Serverless framework to deploy AWS Lambda, Queues and DynamoDB with Node.js&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-06-24T05:40:49.225Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e8626753-d5dc-473c-94f5-da4400f76d29_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/how-to-setup-serverless-framework&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:145748775,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:13,&quot;comment_count&quot;:4,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h4>Initialize project</h4><p>let's create a serverless project, to do so we can open the terminal and run the command:</p><pre><code>sls // or "serveless"</code></pre><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!5r-v!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!5r-v!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png 424w, /__u/substackcdn.com/image/fetch/$s_!5r-v!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png 848w, /__u/substackcdn.com/image/fetch/$s_!5r-v!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png 1272w, /__u/substackcdn.com/image/fetch/$s_!5r-v!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!5r-v!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png" width="1456" height="609" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5478a955-0584-4c40-9dff-4037235eecff_1706x714.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:609,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:352471,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!5r-v!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png 424w, /__u/substackcdn.com/image/fetch/$s_!5r-v!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png 848w, /__u/substackcdn.com/image/fetch/$s_!5r-v!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png 1272w, /__u/substackcdn.com/image/fetch/$s_!5r-v!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5478a955-0584-4c40-9dff-4037235eecff_1706x714.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>we choose:</p><p> <em>AWS / Node.js / Simple Function</em> </p><p>and then:</p><p> <em>Skip Adding An App</em></p><p>choose a project name, once done enter the project folder and initialize an NPM project with:</p><pre><code>npm init -y</code></pre><p>within the project you will see that there are two files:</p><ul><li><p><strong>serverless.yml</strong></p></li><li><p><strong>handler.js</strong></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><h4>serverless.yml</h4><p>serverless.yml is a configuration file used in serverless applications.</p><p>It defines the functions, events, and resources for your serverless service. With this file, you can specify how your functions should be deployed, what triggers them, and what permissions they need. It simplifies managing and deploying serverless functions.</p><p>This is an example:</p><pre><code>org: implementing
service: hello-world-lambda

provider:
  name: aws
  runtime: nodejs20.x
  region: eu-west-2

functions:
  hello:
    handler: handler.hello</code></pre><p>the sections we find are:</p>
      <p>
          <a href="/__u/implementing.substack.com/p/deploy-aws-lambda-functions-with-serverless-node">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[How to setup Serverless framework to deploy AWS Lambda, Queues and DynamoDB with Node.js]]></title><description><![CDATA[Setup serverless framework - Edition #28]]></description><link>https://implementing.substack.com/p/how-to-setup-serverless-framework</link><guid isPermaLink="false">https://implementing.substack.com/p/how-to-setup-serverless-framework</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 24 Jun 2024 05:40:49 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e8626753-d5dc-473c-94f5-da4400f76d29_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I show you how to configure all the tools you will need to u&#8230;</p>
      <p>
          <a href="/__u/implementing.substack.com/p/how-to-setup-serverless-framework">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[1,000+ Subscribers, Paid plan and Sponsor Product Hunt launches]]></title><description><![CDATA[Achievements and paid plan - Edition #27]]></description><link>https://implementing.substack.com/p/1000-subscribers-paid-plan-and-producthunt</link><guid isPermaLink="false">https://implementing.substack.com/p/1000-subscribers-paid-plan-and-producthunt</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 17 Jun 2024 05:34:50 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f78627f1-e4f5-4cb2-a672-3cd599e3fb38_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>This episode of Implementing is a bit different from the previous ones, you will find:</p><ul><li><p>&#127881; Achievements, subscribers and views.</p></li><li><p>&#127775; Announcement of the paid plan.</p></li><li><p>&#129309; Start collaborations with founders to sponsor launches on <a href="https://www.producthunt.com/">Product Hunt</a>.</p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#127881; 1,000+ Subscribers!</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!mnDm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!mnDm!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png 424w, /__u/substackcdn.com/image/fetch/$s_!mnDm!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png 848w, /__u/substackcdn.com/image/fetch/$s_!mnDm!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png 1272w, /__u/substackcdn.com/image/fetch/$s_!mnDm!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!mnDm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png" width="727" height="449.38186813186815" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/343434c2-0205-4ed1-b076-766f22084014_1926x1190.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:900,&quot;width&quot;:1456,&quot;resizeWidth&quot;:727,&quot;bytes&quot;:172642,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!mnDm!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png 424w, /__u/substackcdn.com/image/fetch/$s_!mnDm!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png 848w, /__u/substackcdn.com/image/fetch/$s_!mnDm!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png 1272w, /__u/substackcdn.com/image/fetch/$s_!mnDm!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F343434c2-0205-4ed1-b076-766f22084014_1926x1190.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Subscribers growth trend</figcaption></figure></div><p>Last week Implementing reached 1,000+ subscribers, an achievement I never imagined six months ago when I started the newsletter.</p><p>Thank you! &#128591;</p><p>Knowing that so many people read my posts makes me happy and motivates me to keep going.</p><p>Writing for Implementing allows me to do what I love: explore new technologies, discover new approaches, meet people and create mini projects.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!l8kl!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!l8kl!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png 424w, /__u/substackcdn.com/image/fetch/$s_!l8kl!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png 848w, /__u/substackcdn.com/image/fetch/$s_!l8kl!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png 1272w, /__u/substackcdn.com/image/fetch/$s_!l8kl!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!l8kl!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png" width="727" height="342.52884615384613" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:686,&quot;width&quot;:1456,&quot;resizeWidth&quot;:727,&quot;bytes&quot;:108564,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!l8kl!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png 424w, /__u/substackcdn.com/image/fetch/$s_!l8kl!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png 848w, /__u/substackcdn.com/image/fetch/$s_!l8kl!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png 1272w, /__u/substackcdn.com/image/fetch/$s_!l8kl!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc435a525-b4f1-4e69-9389-9b6865401dd1_1804x850.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Views trend per week</figcaption></figure></div><div><hr></div><h2>&#127775; Paid plan</h2><p>I've decided to introduce a paid plan, this will help me to:</p><ul><li><p>Cover the costs of tools and services like Heroku, OpenAI API, Bubble, Canva, AWS, and Grammarly.</p></li><li><p>Buy online courses to learn new technologies.</p></li><li><p>Have a budget to invest in enhancing Implementing.</p></li></ul><h4>What is included in the paid plan?</h4><p>Paid plan is a single subscription that allows you to:</p><ul><li><p><strong>Use all the tools I develop</strong>: with the free plan you can still use them but a limited number of times.</p></li><li><p><strong>Read all posts</strong> <strong>of Implementing</strong>: for free subscriptions a paywall will be applied to all posts older than one month from the current day.</p></li></ul><p>Among the projects you can use, there are:</p><ol><li><p><a href="https://quickview.email/try-summary">Youtube video summarizer</a>: get YouTube video summaries in your preferred language sent directly to your email.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!46hU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!46hU!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png 424w, /__u/substackcdn.com/image/fetch/$s_!46hU!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png 848w, /__u/substackcdn.com/image/fetch/$s_!46hU!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png 1272w, /__u/substackcdn.com/image/fetch/$s_!46hU!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!46hU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png" width="404" height="342.4010989010989" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1234,&quot;width&quot;:1456,&quot;resizeWidth&quot;:404,&quot;bytes&quot;:529282,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!46hU!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png 424w, /__u/substackcdn.com/image/fetch/$s_!46hU!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png 848w, /__u/substackcdn.com/image/fetch/$s_!46hU!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png 1272w, /__u/substackcdn.com/image/fetch/$s_!46hU!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9227b0dc-dd0c-48fd-8781-3fe5d0e22c1b_1796x1522.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p><a href="https://substack-summarizer.bubbleapps.io/version-test">Substack articles summarizer</a>: summarize Substack articles directly in your preferred language.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!r2v6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!r2v6!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png 424w, /__u/substackcdn.com/image/fetch/$s_!r2v6!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png 848w, /__u/substackcdn.com/image/fetch/$s_!r2v6!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png 1272w, /__u/substackcdn.com/image/fetch/$s_!r2v6!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!r2v6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png" width="422" height="550.2267573696145" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1150,&quot;width&quot;:882,&quot;resizeWidth&quot;:422,&quot;bytes&quot;:750077,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!r2v6!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png 424w, /__u/substackcdn.com/image/fetch/$s_!r2v6!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png 848w, /__u/substackcdn.com/image/fetch/$s_!r2v6!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png 1272w, /__u/substackcdn.com/image/fetch/$s_!r2v6!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe9ce188f-5c77-4674-ab7e-b3d6e55956fc_882x1150.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div></li><li><p><a href="/__u/implementing.substack.com/p/how-to-create-email-sequences-on">Email sequence for Substack creators</a>: I have created a system for sending recurring emails on Substack, you simply create a post draft and select filters to retrieve the users you want to send the email.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!RI0F!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!RI0F!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png 424w, /__u/substackcdn.com/image/fetch/$s_!RI0F!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png 848w, /__u/substackcdn.com/image/fetch/$s_!RI0F!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png 1272w, /__u/substackcdn.com/image/fetch/$s_!RI0F!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!RI0F!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png" width="408" height="287.0315789473684" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:802,&quot;width&quot;:1140,&quot;resizeWidth&quot;:408,&quot;bytes&quot;:273334,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!RI0F!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png 424w, /__u/substackcdn.com/image/fetch/$s_!RI0F!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png 848w, /__u/substackcdn.com/image/fetch/$s_!RI0F!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png 1272w, /__u/substackcdn.com/image/fetch/$s_!RI0F!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc29229e0-2edc-4d9c-b73d-6d1d01013915_1140x802.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Workflows created by Refactoring newsletter</figcaption></figure></div></li><li><p><a href="/__u/quickviewai.substack.com/">Free subscription to Quickview's paid plan</a>: every day sends an email with summaries of Youtube videos on cryptocurrencies by top creators. With Implementing paid subscription you receive Quickview paid plan for free.</p></li></ol><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!AYBI!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!AYBI!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png 424w, /__u/substackcdn.com/image/fetch/$s_!AYBI!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png 848w, /__u/substackcdn.com/image/fetch/$s_!AYBI!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png 1272w, /__u/substackcdn.com/image/fetch/$s_!AYBI!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!AYBI!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png" width="386" height="355.24725274725273" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1340,&quot;width&quot;:1456,&quot;resizeWidth&quot;:386,&quot;bytes&quot;:1205494,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!AYBI!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png 424w, /__u/substackcdn.com/image/fetch/$s_!AYBI!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png 848w, /__u/substackcdn.com/image/fetch/$s_!AYBI!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png 1272w, /__u/substackcdn.com/image/fetch/$s_!AYBI!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F99122e97-4246-419b-9de9-751877c5fd62_1682x1548.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#129309; Sponsor Product Hunt launches</h2><p><a href="https://www.producthunt.com/">Product Hunt</a> is a platform where you can discover and share new products, apps, and tech innovations. Users post their latest finds, and the community votes on the best ones, helping you stay updated on the coolest new tools and gadgets.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!mQ3O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!mQ3O!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png 424w, /__u/substackcdn.com/image/fetch/$s_!mQ3O!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png 848w, /__u/substackcdn.com/image/fetch/$s_!mQ3O!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png 1272w, /__u/substackcdn.com/image/fetch/$s_!mQ3O!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!mQ3O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png" width="620" height="332.14285714285717" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:780,&quot;width&quot;:1456,&quot;resizeWidth&quot;:620,&quot;bytes&quot;:636233,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!mQ3O!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png 424w, /__u/substackcdn.com/image/fetch/$s_!mQ3O!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png 848w, /__u/substackcdn.com/image/fetch/$s_!mQ3O!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png 1272w, /__u/substackcdn.com/image/fetch/$s_!mQ3O!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7111fb41-0215-41c0-b1f9-21b2d0732fb7_2824x1512.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Before I started with Implementing, I worked on various projects with the goal of launching them on Product Hunt. As good developers, we can build great systems, but we face challenges when it comes to market them.</p><p>That's why I decided to open up to collaborations to support the launch of tools on Product Hunt. In each episode you will find a short section with a picture of the tool, a description, and a link to support the product on the platform.</p><p>The goal is to help the founders to increase their visibility and let you know about their great products.</p><p>If I can, I'll try to get some discounts! &#128513;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.notion.site/Working-with-Implementing-11dbed6db11843eca99ed4b6d4786953&quot;,&quot;text&quot;:&quot;Sponsor your launch &#128227;&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://implementing.notion.site/Working-with-Implementing-11dbed6db11843eca99ed4b6d4786953"><span>Sponsor your launch &#128227;</span></a></p><div><hr></div><h2>&#127775; Top lectures of the week</h2><p><a href="https://newsletter.systemdesign.one/p/instagram-infrastructure?r=oshyp&amp;utm_campaign=post&amp;utm_medium=web">How Instagram Scaled to 2.5 Billion Users</a> <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Neo Kim&quot;,&quot;id&quot;:135589200,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c103940f-0d8b-47e7-9a33-013202e17bb8_389x389.jpeg&quot;,&quot;uuid&quot;:&quot;158cca45-2e93-4e63-9b59-5176012a68d9&quot;}" data-component-name="MentionToDOM"></span></p><p><a href="https://www.theeuropeanengineer.com/p/lets-collect-salaries-and-saving?r=oshyp&amp;utm_campaign=post&amp;utm_medium=web">I Created a Google Sheet for Devs in Europe to Share Salaries and Saving Rates</a> <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Nicola Amadio&quot;,&quot;id&quot;:131766168,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3b3bb1ac-d285-4c77-8fd4-7047a674b800_3421x3421.jpeg&quot;,&quot;uuid&quot;:&quot;d77cae09-0372-45f8-b098-6ea763c85aab&quot;}" data-component-name="MentionToDOM"></span></p><p><a href="https://blog.algomaster.io/p/uml-class-diagram-explained-with-examples?r=oshyp&amp;utm_campaign=post&amp;utm_medium=web">UML Class Diagram Explained with Examples</a> <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Ashish Pratap Singh&quot;,&quot;id&quot;:83602743,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0a3654fc-7584-4098-a656-7bda89568f83_612x612.jpeg&quot;,&quot;uuid&quot;:&quot;bcf7c928-c1f7-414b-94d4-9281dd717ab0&quot;}" data-component-name="MentionToDOM"></span></p><p><a href="/__u/open.substack.com/pub/thehustlingengineer/p/5-toxic-behaviors-to-avoid-if-you?r=oshyp&amp;utm_campaign=post&amp;utm_medium=web">5 Toxic Behaviors to Avoid if you are a Software Engineer</a> <span class="mention-wrap" data-attrs="{&quot;name&quot;:&quot;Hemant Pandey&quot;,&quot;id&quot;:58770480,&quot;type&quot;:&quot;user&quot;,&quot;url&quot;:null,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd5d8aef1-0399-40a0-9537-5615ca0fe8d4_1166x1167.jpeg&quot;,&quot;uuid&quot;:&quot;5fc20c7c-a11a-41f0-996d-3df2d13a2788&quot;}" data-component-name="MentionToDOM"></span></p><div><hr></div><p>And that&#8217;s it for today! If you are finding this newsletter valuable, consider doing any of these:</p><ol><li><p>&#127867; <strong>Read with your friends</strong> &#8212; Implementing lives thanks to word of mouth. Share the article with someone who would like it.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/p/1000-subscribers-paid-plan-and-producthunt?utm_source=substack&utm_medium=email&utm_content=share&action=share&quot;,&quot;text&quot;:&quot;Share&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/implementing.substack.com/p/1000-subscribers-paid-plan-and-producthunt?utm_source=substack&amp;utm_medium=email&amp;utm_content=share&amp;action=share"><span>Share</span></a></p></li><li><p>&#128227; <strong>Provide your feedback</strong> &#8212; We welcome your thoughts! Please share your opinions or suggestions for improving the newsletter, your input helps us adapt the content to your tastes.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/p/1000-subscribers-paid-plan-and-producthunt/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/implementing.substack.com/p/1000-subscribers-paid-plan-and-producthunt/comments"><span>Leave a comment</span></a></p></li><li><p>&#128172; <strong>Chat with me</strong> &#8212; If you have any doubts or curiosity, please write to me, I will be happy to answer you!</p></li></ol><div class="directMessage button" data-attrs="{&quot;userId&quot;:41640433,&quot;userName&quot;:&quot;Marco Moauro&quot;,&quot;canDm&quot;:null,&quot;dmUpgradeOptions&quot;:null,&quot;isEditorNode&quot;:true}" data-component-name="DirectMessageToDOM"></div><p>I wish you a great day! &#9728;&#65039;</p><p>Marco</p>]]></content:encoded></item><item><title><![CDATA[Uses Bcrypt Algorithm to Securely store Passwords in the Database]]></title><description><![CDATA[Bcrypt algorithm - Edition #26]]></description><link>https://implementing.substack.com/p/uses-bcrypt-algorithm-to-store-password-database</link><guid isPermaLink="false">https://implementing.substack.com/p/uses-bcrypt-algorithm-to-store-password-database</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 10 Jun 2024 05:33:02 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/f3c5662e-30f8-4545-bdb7-55616adede09_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I will introduce the Bcrypt algorithm, compare it to SHA-256, and a possible implementation in Node.js.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/bcrypt-user-password">https://github.com/marcomoauro/bcrypt-user-password</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#9888;&#65039; Why it is important to avoid storing passwords in plain?</h2><p>Storing passwords in plain text is a serious security risk. </p><p>If a database is hacked, all user passwords are exposed, potentially resulting in unauthorized access to accounts and sensitive information. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!LRjK!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!LRjK!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png 424w, /__u/substackcdn.com/image/fetch/$s_!LRjK!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png 848w, /__u/substackcdn.com/image/fetch/$s_!LRjK!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png 1272w, /__u/substackcdn.com/image/fetch/$s_!LRjK!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!LRjK!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png" width="440" height="282.05128205128204" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:600,&quot;width&quot;:936,&quot;resizeWidth&quot;:440,&quot;bytes&quot;:1000932,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!LRjK!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png 424w, /__u/substackcdn.com/image/fetch/$s_!LRjK!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png 848w, /__u/substackcdn.com/image/fetch/$s_!LRjK!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png 1272w, /__u/substackcdn.com/image/fetch/$s_!LRjK!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b4a5286-f86c-4a80-91cb-4d810aa44d5a_936x600.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Reference: <a href="https://www.cybertrends.it/scoperto-nuovo-database-di-credenziali-rubate-violate-25-milioni-di-password/">https://www.cybertrends.it/scoperto-nuovo-database-di-credenziali-rubate-violate-25-milioni-di-password/</a></figcaption></figure></div><p>Attackers can easily exploit passwords in the clear, causing identity theft, financial losses and damaging an organization's reputation. </p><p>To safeguard user data, you can use secure hashing algorithms. These algorithms encrypt passwords, making them extremely difficult for attackers to crack.</p><h4>Bcrypt algorithm</h4><p>Bcrypt is a widely used cryptographic hash function.</p><p>It employs a technique called adaptive hashing to protect passwords from brute force and rainbow table attacks. </p><p>Bcrypt uses a <strong>salted hashing approach</strong>, adding a random string to each password before hashing, which increases security by preventing the use of pre-calculated hash tables.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128274; How does Bcrypt work?</h2><p>The information the algorithm needs includes:</p><ul><li><p><strong>password</strong></p></li><li><p><strong>cost factor</strong>: a number indicating how many iterations the algorithm must perform before producing the result. Higher values require more time.</p></li></ul><p>From this information, the algorithm produces a 22-character salt that is added as a prefix to the resulting hashed password. The salt makes hash dictionary and brute force attacks virtually impossible.</p><p>The output of the algorithm will always be 60 characters, structured as follows:</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!wK4O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!wK4O!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png 424w, /__u/substackcdn.com/image/fetch/$s_!wK4O!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png 848w, /__u/substackcdn.com/image/fetch/$s_!wK4O!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png 1272w, /__u/substackcdn.com/image/fetch/$s_!wK4O!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!wK4O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png" width="688" height="192.35677530017153" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:326,&quot;width&quot;:1166,&quot;resizeWidth&quot;:688,&quot;bytes&quot;:65827,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!wK4O!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png 424w, /__u/substackcdn.com/image/fetch/$s_!wK4O!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png 848w, /__u/substackcdn.com/image/fetch/$s_!wK4O!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png 1272w, /__u/substackcdn.com/image/fetch/$s_!wK4O!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F6370da4b-2eb8-46a8-8060-c39308819250_1166x326.png 1456w" sizes="100vw" loading="lazy"></picture><div></div></div></a><figcaption class="image-caption">Reference: <a href="https://stackoverflow.com/questions/20394137/yii-cpasswordhelper-hashpassword-and-verifypassword/20399775#20399775">https://stackoverflow.com/questions/20394137/yii-cpasswordhelper-hashpassword-and-verifypassword/20399775#20399775</a></figcaption></figure></div><p>The cost factor is what makes the algorithm secure; it determines the number of iterations that must be performed, influencing the time and resources required to produce the final hash.</p><h4>Password verification</h4><p>Let's imagine we generated this hash: <strong>$2y$10$n0UIs5kJ7naTuTFkBy1veuKOkSxUFXfua0KdOKf9xYTOKKIGSJwFa</strong> from the password <strong>implementing</strong>.</p><p>The algorithm extracts the salt (<strong>n0UIs5kJ7naTuTFkBy1veu</strong>), the cost factor (<strong>10</strong>), and applies the hashing procedure again to the given password.</p><p>The computation will require 2^cost_factor (10) iterations before producing the final hash. </p><p>If the final hash matches the initial hash, the password is correct, otherwise, it is incorrect.</p><h4>If we add a pepper?</h4><p>A classic approach to enhancing password security is to use a pepper, an additional secret string added to the password, similar to a salt, before hashing.</p><p>The pepper is typically stored as an environment variable or in a secrets manager.</p><p>However, applying a pepper with the Bcrypt algorithm is not necessarily a good idea for several reasons:</p>
      <p>
          <a href="/__u/implementing.substack.com/p/uses-bcrypt-algorithm-to-store-password-database">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Implementing Leaderboards with Redis Sorted Sets and Node.js]]></title><description><![CDATA[Redis data structure - Edition #25]]></description><link>https://implementing.substack.com/p/implement-leaderboard-with-redis-sorted-sets</link><guid isPermaLink="false">https://implementing.substack.com/p/implement-leaderboard-with-redis-sorted-sets</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 03 Jun 2024 05:36:47 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/3e87a396-fecf-465e-9d2f-33aa1aa12166_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I'll show you how to use Redis to efficiently manage leaderb&#8230;</p>
      <p>
          <a href="/__u/implementing.substack.com/p/implement-leaderboard-with-redis-sorted-sets">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[How to Summarize Substack Articles using ChatGPT Api and Node.js]]></title><description><![CDATA[Scraping and OpenAI's chat completions API - Edition #24]]></description><link>https://implementing.substack.com/p/summarize-substack-articles-using-chatgpt-nodejs</link><guid isPermaLink="false">https://implementing.substack.com/p/summarize-substack-articles-using-chatgpt-nodejs</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 27 May 2024 05:38:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/648707b9-40c3-4b94-af00-f3753329107b_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I show you how you can summarize Substack articles using OpenAI and scraping, at the end of the article you will find a graphical interface through which you can summarize your favourite articles.</p><blockquote><p>You can summarize the articles for free via this link: <a href="https://substack-summarizer.bubbleapps.io/version-test">https://substack-summarizer.bubbleapps.io/version-test</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>Over time, I have subscribed to numerous newsletters, each of which offers interesting and valuable content. However, the volume has become excessive and it is impossible for me to read them all. To solve this problem, I decided to implement an article summary. </p><p>This tool allows you to paste the link to any article and provides a concise summary of the content. In addition, it can translate the summary into any language you prefer, making it easier and smoother to read.</p><p>I implemented a similar solution to summarize YouTube videos in the user's preferred language, you can retrieve the episode here, inside you will find a link to access the UI:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;1c213c7a-3d80-4e49-adb6-503e7448da6d&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;How to Summarize Youtube Video using ChatGPT Api and Node.js&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-01-02T06:32:04.268Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52d02190-15f2-4e4b-884d-7eb0601c40c0_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/how-to-summarize-youtube-video-using&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:139964037,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:10,&quot;comment_count&quot;:2,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128736;&#65039; Solution design</h2><p>The idea is to use scraping and OpenAI's chat completions API as shown below:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!ug6O!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!ug6O!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png 424w, /__u/substackcdn.com/image/fetch/$s_!ug6O!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png 848w, /__u/substackcdn.com/image/fetch/$s_!ug6O!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png 1272w, /__u/substackcdn.com/image/fetch/$s_!ug6O!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!ug6O!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png" width="915" height="415" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:415,&quot;width&quot;:915,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:32225,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!ug6O!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png 424w, /__u/substackcdn.com/image/fetch/$s_!ug6O!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png 848w, /__u/substackcdn.com/image/fetch/$s_!ug6O!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png 1272w, /__u/substackcdn.com/image/fetch/$s_!ug6O!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F51278694-e30b-4ee5-a5b7-ef6662c82581_915x415.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Sequence diagram illustrating the interaction between actors</figcaption></figure></div><ol><li><p>The user initiates the process by entering the desired language and the URL of the Substack article they want to summarize and translate.</p></li><li><p>The client sends a request to the server using the <strong>GET /summarize-article </strong>API endpoint. This request includes the language and URL provided by the user.</p></li><li><p>The server performs web scraping on the provided Substack URL to retrieve the article content. This involves fetching the webpage and extracting the text of the article.</p></li><li><p>The Substack platform responds to the server's request by returning the full content of the specified article.</p></li><li><p>The server sends the content of the article together with the specified language to the OpenAI API. It asks OpenAI to generate a summary of the article and translate it into the desired language.</p></li><li><p>The OpenAI API processes the server's request, generating a summary of the article and translating it into the specified language. The results are then sent back to the server.</p></li><li><p>The server returns the result of the operation to the client.</p></li><li><p>The client receives the summarized content and displays it to the user.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p></li></ol><div><hr></div><h2>&#128104;&#8205;&#128187; Let's implement together</h2><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/substack-summarizer">https://github.com/marcomoauro/substack-summarizer</a></p></blockquote><p>We start as usual with the backend template for Node.js that I have shown you here:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;411dc421-b3a1-4862-83d7-bbf628652e4d&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;My Backend Template for Node.js&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-01-08T06:33:29.923Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9763a243-10fc-46c4-b67b-5ee83413e1e6_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/my-backend-template-for-nodejs&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:140322610,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><h4>Model</h4><p>we start by creating the <strong>Article.js</strong> model, with the aim of retrieving the content by scraping and summarizing it via the OpenAI chat completions API:</p>
      <p>
          <a href="/__u/implementing.substack.com/p/summarize-substack-articles-using-chatgpt-nodejs">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[How to Make the Best use of API Pagination with Node.js]]></title><description><![CDATA[Offset-based vs cursor-based - Edition #23]]></description><link>https://implementing.substack.com/p/how-to-make-the-best-use-of-api-pagination</link><guid isPermaLink="false">https://implementing.substack.com/p/how-to-make-the-best-use-of-api-pagination</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 20 May 2024 05:35:35 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/7250bf4b-eeaf-49df-a934-3e8503208c8f_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I want to show you the differences between the offset-based and cursor-based approach to pagination and a possible implementation in Node.js.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/pagination-offset-cursor">https://github.com/marcomoauro/pagination-offset-cursor</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128195; Pagination</h2><p>Imagine having millions of records stored in a database and having to retrieve them via an API. This can become problematic as the huge volume of data causes delays and performance problems.</p><p>With such a large volume of data, the recovery process can quickly become resource-intensive. The size of the data set introduces challenges such as latency issues, where the time required to retrieve and transmit data increases as the volume increases. In addition, the pressure on server resources increases, potentially leading to slowdowns or even system crashes.</p><p>Pagination is a simple but effective solution to this problem, consists of dividing the data into manageable parts or &#8220;pages&#8221;, facilitating retrieval and processing for the server and management on the client, as displaying a lot of data on the interface can cause performance problems due to the size of the data to be managed.</p><p>In detail, we will analyse two techniques:</p><ul><li><p><strong>Offset-based pagination</strong></p></li><li><p><strong>Cursor-based pagination</strong></p></li></ul><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128290; Offset-based pagination</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!EoD2!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!EoD2!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif 424w, /__u/substackcdn.com/image/fetch/$s_!EoD2!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif 848w, /__u/substackcdn.com/image/fetch/$s_!EoD2!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif 1272w, /__u/substackcdn.com/image/fetch/$s_!EoD2!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!EoD2!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif" width="614" height="438.57142857142856" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:560,&quot;resizeWidth&quot;:614,&quot;bytes&quot;:36563,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!EoD2!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif 424w, /__u/substackcdn.com/image/fetch/$s_!EoD2!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif 848w, /__u/substackcdn.com/image/fetch/$s_!EoD2!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif 1272w, /__u/substackcdn.com/image/fetch/$s_!EoD2!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3211fe7d-b4bd-41e1-9aaa-458ef59c25fa_560x400.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><pre><code>select *
from customers
order by id asc
limit 3
offset 0</code></pre><p>Pagination based on limit and offset is a common technique used in databases to retrieve a subset of data at a time.</p><ul><li><p><strong>limit</strong>: The limit refers to the maximum number of records that you want to retrieve in a single query. For example, if you set the limit to 10, the query will return a maximum of 10 elements.</p></li><li><p><strong>offset</strong>: The offset refers to the starting point from which you wish to retrieve data. It indicates the number of records you wish to skip before starting to retrieve data. For example, if you set the offset to 3, the query will start retrieving data from the 4 record onwards, skipping the first 3 records.</p></li></ul><p>To retrieve subsequent data, simply increase the offset as shown below:</p>
      <p>
          <a href="/__u/implementing.substack.com/p/how-to-make-the-best-use-of-api-pagination">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Reduce Latency in HTTP calls using Compression with Node.js]]></title><description><![CDATA[HTTP payload compression algorithms - Edition #22]]></description><link>https://implementing.substack.com/p/reduce-latency-http-using-compression-in-nodejs</link><guid isPermaLink="false">https://implementing.substack.com/p/reduce-latency-http-using-compression-in-nodejs</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 13 May 2024 05:34:50 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/0727bd1c-55f9-4768-a6c2-70e021d25f77_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I'll explain what HTTP response payload compression is, including the algorithms involved and how to implement support for them in a Node.js server.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/magic-link-auth">https://github.com/marcomoauro/magic-link-auth</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>Consider that you have an API needs to transmit a large JSON file over the Internet. Sending such a large file could take a long time to transfer and could consume a significant amount of bandwidth.</p><p>Compression techniques allow the API to reduce the size of the JSON file before sending it over the Internet. By compressing the file, the data is encoded more efficiently, resulting in a smaller packet. This compression process not only speeds up transmission times, but also reduces the bandwidth required for the transfer.</p><p>Therefore, when the API compresses the JSON file before sending it, it benefits in several ways. Firstly, it ensures that the data reaches its destination more quickly, improving overall efficiency. Secondly, it reduces the pressure on Internet resources, making the transmission lighter.</p><h4>How to request compression from the server?</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!OAJf!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!OAJf!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif 424w, /__u/substackcdn.com/image/fetch/$s_!OAJf!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif 848w, /__u/substackcdn.com/image/fetch/$s_!OAJf!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif 1272w, /__u/substackcdn.com/image/fetch/$s_!OAJf!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!OAJf!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif" width="530" height="378.57142857142856" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:560,&quot;resizeWidth&quot;:530,&quot;bytes&quot;:71731,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!OAJf!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif 424w, /__u/substackcdn.com/image/fetch/$s_!OAJf!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif 848w, /__u/substackcdn.com/image/fetch/$s_!OAJf!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif 1272w, /__u/substackcdn.com/image/fetch/$s_!OAJf!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2a3941b5-1667-4c64-85eb-149af689c39c_560x400.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It is the client that decides to request compression and uses the <strong>Accept-Encoding</strong> header where it makes explicit all the compression formats it can handle.</p><p>the server receives the API call, processes it and before returning the response to the client, compresses it by choosing one of the algorithms made explicit by the client, if supported. </p><p>Finally it returns the compressed response to the client by adding the <strong>Content Encoding</strong> header, so the client knows how to decompress the response to process it correctly.</p><h4>Pros vs cons</h4><p>In addition to the benefits of lower bandwidth occupancy and consequent reduction in overall latency, compression introduces inefficiencies.</p><p>Pros include:</p><ul><li><p>&#9989; <strong>Reduced file size</strong>: compression significantly reduces file size. This enables faster transfer of data over the network, especially in conditions of limited bandwidth such as mobile devices.</p></li><li><p>&#9989; <strong>Improved website performance</strong>: file compression helps to reduce the loading time of web pages. As file sizes are reduced, browsers can download content faster, improving the user experience and helping to reduce site abandonment rates.</p></li><li><p>&#9989; <strong>Reduced latency due to smaller payloads</strong>: Compression leads to smaller file sizes, resulting in reduced latency. Compressed files take less time to be transferred over the network because there is less data to transmit. As a result, HTTP requests can be processed faster, reducing the overall response time of the server.</p></li></ul>
      <p>
          <a href="/__u/implementing.substack.com/p/reduce-latency-http-using-compression-in-nodejs">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Do you really need Foreign Keys?]]></title><description><![CDATA[Relational database - Edition #21]]></description><link>https://implementing.substack.com/p/do-you-really-need-foreign-keys</link><guid isPermaLink="false">https://implementing.substack.com/p/do-you-really-need-foreign-keys</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 06 May 2024 05:40:01 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/ab1eb339-71b3-4a6c-86bf-0476dd1a8a51_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I introduce the concept of foreign keys in relational databases such as MySQL by showing the advantages and disadvantages of using them</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>Imagine we want to represent a reality where we have <strong>customers</strong> and the <strong>orders</strong> they have placed, with a one-to-many relationship.</p><p>In UML we could represent it like this:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!hsMc!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!hsMc!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png 424w, /__u/substackcdn.com/image/fetch/$s_!hsMc!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png 848w, /__u/substackcdn.com/image/fetch/$s_!hsMc!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png 1272w, /__u/substackcdn.com/image/fetch/$s_!hsMc!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!hsMc!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png" width="188" height="346.7012987012987" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:284,&quot;width&quot;:154,&quot;resizeWidth&quot;:188,&quot;bytes&quot;:7406,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!hsMc!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png 424w, /__u/substackcdn.com/image/fetch/$s_!hsMc!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png 848w, /__u/substackcdn.com/image/fetch/$s_!hsMc!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png 1272w, /__u/substackcdn.com/image/fetch/$s_!hsMc!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F860c566b-0a7e-408a-8de3-dc2e514b5d18_154x284.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">customers &#8594; orders relation</figcaption></figure></div><p>that in MySQL is reflected in this DDL:</p><pre><code><code>CREATE TABLE customers
(
    id    INT AUTO_INCREMENT PRIMARY KEY,
    name  VARCHAR(50),
    email VARCHAR(100)
);

CREATE TABLE orders
(
    id          INT AUTO_INCREMENT PRIMARY KEY,
    customer_id INT,
    order_date  DATE,
    amount      DECIMAL(10, 2)
);</code></code></pre><p>To establish a 1-to-many relationship, we create the foreign key <strong>customer_id</strong> in the orders table. This allows each order to be associated with the respective customer who placed it. In this way, we created a connection from the orders table to the customers table.</p><h4>Foreign keys</h4><p>The purpose of foreign keys is to facilitate navigation and linking between two tables, managed through a <strong>CONSTRAINT</strong> in the database. This means that when inserting new records in tables containing foreign keys, the database ensures that the value entered for the FK exists in the reference table, thus guaranteeing so-called <em>referential integrity</em>.</p><p>The foreign key constraint is specified during the definition of the database tables. In the previous example of customers and orders, we can make the constraint explicit like this:</p><pre><code><code>CREATE TABLE customers
(
    id    INT AUTO_INCREMENT PRIMARY KEY,
    name  VARCHAR(50),
    email VARCHAR(100)
);

CREATE TABLE orders
(
    id          INT AUTO_INCREMENT PRIMARY KEY,
    customer_id INT,
    order_date  DATE,
    amount      DECIMAL(10, 2),
    </code><strong>FOREIGN KEY (customer_id) REFERENCES customers (id)</strong><code>
);</code></code></pre><p>this constraint introduces advantages and disadvantages in its use, which will be addressed in the following sections.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>Pros</h2><h4>&#9989; Database consistency</h4>
      <p>
          <a href="/__u/implementing.substack.com/p/do-you-really-need-foreign-keys">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Secure your API with Rate Limiting using Redis]]></title><description><![CDATA[Fixed window rate limiting - Edition #20]]></description><link>https://implementing.substack.com/p/secure-your-api-with-rate-limiting-using-redis</link><guid isPermaLink="false">https://implementing.substack.com/p/secure-your-api-with-rate-limiting-using-redis</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 29 Apr 2024 05:34:43 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/1fc88a03-653e-48e4-b9de-2cb7df4d61a6_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode I want to show you how to create a rate limiter using Redis with its atomic and transactional methods.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/redis-rate-limiter">https://github.com/marcomoauro/redis-rate-limiter</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>Rate limiting is a technique employed to restrict the number of requests a client can make to a server, ensuring the security and stability of the application. By implementing rate limiting, we can prevent overload scenarios that may impact essential resources such as the database.</p><p>This technique is crucial in countering various cyber attacks, including:</p><ul><li><p><strong>Brute force attacks</strong>: By limiting the number of requests, we prevent attackers from using server resources to systematically attempt to guess user passwords and gain unauthorised access to the application.</p></li><li><p><strong>Denial of Service attacks (DoS)</strong>: Rate limiting prevents attackers from flooding the server with a barrage of requests, thus limiting attempts to overload and disrupt the server's operations.</p></li><li><p><strong>Scraping</strong>: Limiting the number of requests per IP address prevents attackers from scraping sensitive data from our application by restricting their ability to make excessive requests.</p></li></ul><h4>Possible solutions</h4><p>We can use various strategies to implement a rate limiting mechanism in our application, one does not exclude the other, in fact mixed systems are usually employed:</p><ul><li><p><strong>Fixed-window</strong>: this consists of checking how many calls are made by the client in a fixed window such as 1 minute, if more are made then all subsequent calls are rejected until the start of the next window.</p></li><li><p><strong>Sliding-window</strong>: differs from fixed-window in that the window runs over time, e.g. we could take into account the calls made in the last 5 minutes, this approach allows us to better adapt to traffic spikes.</p></li><li><p><strong>Token bucket</strong>: a bucket is used which contains tokens, each of which represents a call that can be made and with each invocation the tokens are decremented. Once finished, the client cannot call again until the tokens in the bucket are restored, so the server can manage the rate of calls. This approach is efficient in memory but may be susceptible to race conditions in multi-threaded environments or when processes share the same resources.</p></li></ul><p>In our case, we are going to implement the <strong>fixed-window</strong> mechanism using <strong>Redis</strong> via the atomic function <strong>INCR</strong> and the use of <strong>TTL</strong>. </p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#9989; <strong>Fixed-window</strong> strategy</h2><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!O6rr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!O6rr!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png 424w, /__u/substackcdn.com/image/fetch/$s_!O6rr!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png 848w, /__u/substackcdn.com/image/fetch/$s_!O6rr!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png 1272w, /__u/substackcdn.com/image/fetch/$s_!O6rr!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!O6rr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png" width="688" height="515.0282485875706" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:530,&quot;width&quot;:708,&quot;resizeWidth&quot;:688,&quot;bytes&quot;:38027,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!O6rr!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png 424w, /__u/substackcdn.com/image/fetch/$s_!O6rr!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png 848w, /__u/substackcdn.com/image/fetch/$s_!O6rr!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png 1272w, /__u/substackcdn.com/image/fetch/$s_!O6rr!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F55906e0a-f079-40e1-9ed8-138acef8c5db_708x530.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Sequence diagram illustrating the interaction among different components and the flow of execution</figcaption></figure></div><ol><li><p>The client calls the server API identifying itself by the API key.</p></li><li><p>The server queries the database to verify the validity of the API key.</p></li><li><p>The database returns the result of the key validity check to the server.</p></li><li><p>The server verifies the use of the API key in the cache.</p></li><li><p>The cache increments the API key usage counter within the time window.</p></li><li><p>The cache checks whether the API key usage is within the limits allowed by the time window.</p></li><li><p><em>If the API key usage is within limits</em>, cache informs the server that the usage is within limits.</p></li><li><p><em>If the API key usage is within limits</em>, server tells the client that it can continue with processing.</p></li><li><p><em>If the API key usage exceeds the allowed limits</em>, cache informs the server that the usage has exceeded the limits.</p></li><li><p><em>If the API key usage exceeds the allowed limits</em>, server stops API execution by responding to the client that API key usage has exceeded limits.</p><p></p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div></li></ol><h2>&#9889;&#65039; Redis: MULTI, INCR and EXPIRE commands</h2><p>I used Redis in this way to limit requests within a fixed window of one minute:</p><p>First, I created a key in this format: "<strong>rate_limit/{api-key-id}/{time-format}/{time}</strong>", where:</p><ul><li><p> <strong>api-key-id</strong>: is the ID of the API key in our database.</p></li><li><p><strong>time-format</strong>: is the format used, in our case is minutes ("m"). </p></li><li><p><strong>time</strong>: represents the specific minute when a client makes a call.</p></li></ul><p>if a call is made at minute 3 of the api key with ID 1 we would have the following Redis key:</p>
      <p>
          <a href="/__u/implementing.substack.com/p/secure-your-api-with-rate-limiting-using-redis">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Increase 10x API Read speed with cache using Redis]]></title><description><![CDATA[Cache aside strategy - Edition #19]]></description><link>https://implementing.substack.com/p/increase-10x-api-read-with-cache-using-redis</link><guid isPermaLink="false">https://implementing.substack.com/p/increase-10x-api-read-with-cache-using-redis</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 22 Apr 2024 05:34:47 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/07f40e2f-bd6f-4095-b64f-84403794c779_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode I show you how to introduce a caching system like Redis by showing you how I did it for the Magic Link-based authentication app.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/magic-link-auth">https://github.com/marcomoauro/magic-link-auth</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>Let us imagine that we have an API that aims to retrieve information from the database and then serve it up on a web page by the client.</p><p>Managing numerous database calls that repeatedly return very similar data can cause inefficiency problems because the database must be queried each time, consuming time and resources to obtain the same data over and over again.</p><p><strong>Employing a cache can significantly alleviate this problem.</strong> </p><p>By caching frequently accessed data, subsequent requests for the same data can be served directly from the cache, reducing the need to query the database repeatedly. This speeds up response times and reduces the load on the database server, resulting in improved overall system performance.</p><h4>What if the data are changed?</h4><p>Cache introduces a trade-off between consistency and performance. </p><p>While caching can still improve performance by reducing the number of database queries, it may lead to stale data being served from the cache if updates are not properly synchronized. </p><p>In such cases, the system must balance the benefits of improved performance against the risk of serving outdated information. Strategies such as implementing cache invalidation mechanisms or setting shorter cache expiration times can help mitigate this trade-off by ensuring that the cached data remains relatively fresh. </p><p>It's essential to carefully evaluate the requirements of the application and the frequency of data updates to determine the most suitable caching strategy.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#9989; Cache aside strategy</h2><p>One possible strategy that can be used to introduce a caching mechanism is Cache Aside (or Lazy loading).</p><p><strong>Data is cached only when it&#8217;s requested.</strong></p><p>When an application requests data, it first checks if it is present in the cache, if present, it is returned directly from the cache otherwise it is retrieved from the source (e.g. a database), stored in the cache for future requests and then returned to the application.</p><p>in this way we obtain the following advantages:</p><ol><li><p><strong>Reduced latency</strong>: frequently requested data is cached, reducing the time required to access it compared to retrieval from slower storage systems such as databases.</p></li><li><p><strong>Scalability</strong>: by reducing the load on back-end systems such as databases, the effective use of caching can help improve the overall scalability of the system.</p></li><li><p><strong>Improved user experience:</strong> By serving frequently accessed data from the cache, users experience faster response times and smoother interactions with applications or websites. This leads to a more satisfying experience.</p></li></ol><p>and disadvantages:</p><ol><li><p><strong>Waste of resources:</strong> when storing infrequently used data.</p></li><li><p><strong>Data consistency</strong>: introduces the need to manage synchronization and cache invalidation to ensure that the data are up-to-date and consistent with the source.</p><div><hr></div></li></ol><h2>&#128100; User caching in the Magic Link login app</h2><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;41486ec8-a510-4d9d-9d04-c50582681371&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;How to Implement a Magic Link Authentication using Node.js and JSON Web Token (JWT)&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-04-08T05:38:48.106Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e87028e8-13a8-4c4f-90bf-429908596eb0_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/how-to-implement-a-magic-link-authentication&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:143180239,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:10,&quot;comment_count&quot;:4,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Once the user has logged in, the client calls the server api <strong>GET /users/me</strong> to retrieve the user's data, here we can introduce a caching mechanism to avoid querying the database.</p><p>Let us introduce the mechanism using the following sequence diagram:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!QrTA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!QrTA!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png 424w, /__u/substackcdn.com/image/fetch/$s_!QrTA!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png 848w, /__u/substackcdn.com/image/fetch/$s_!QrTA!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QrTA!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!QrTA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png" width="509" height="448.59120879120877" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/46007a62-be31-4556-9d2c-547120f744dc_455x401.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:401,&quot;width&quot;:455,&quot;resizeWidth&quot;:509,&quot;bytes&quot;:24406,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!QrTA!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png 424w, /__u/substackcdn.com/image/fetch/$s_!QrTA!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png 848w, /__u/substackcdn.com/image/fetch/$s_!QrTA!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png 1272w, /__u/substackcdn.com/image/fetch/$s_!QrTA!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F46007a62-be31-4556-9d2c-547120f744dc_455x401.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">use of caching via the &#8220;Cache aside&#8221; strategy to retrieve user information</figcaption></figure></div><ol><li><p>Client calls the server api <strong>GET /users/me.</strong></p></li><li><p>Server checks if the user is in the cache.</p></li></ol>
      <p>
          <a href="/__u/implementing.substack.com/p/increase-10x-api-read-with-cache-using-redis">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[Reduce Database Load with Bloom Filters]]></title><description><![CDATA[Probabilistic data structure - Edition #18]]></description><link>https://implementing.substack.com/p/reduce-database-load-by-bloom-filters</link><guid isPermaLink="false">https://implementing.substack.com/p/reduce-database-load-by-bloom-filters</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 15 Apr 2024 05:33:58 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/84bba168-4b3c-40ac-bf8d-982d18e57c52_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I show you how the Bloom Filter data structure works and a possible implementation in Redis.</p><blockquote><p>You can find the implementation here: <a href="https://github.com/marcomoauro/magic-link-auth/blob/main/src/usernameBloomFilter.js">https://github.com/marcomoauro/magic-link-auth/blob/main/src/usernameBloomFilter.js</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#127922; Bloom Filter</h2><p>A Bloom Filter is a probabilistic data structure, it allows representing a large amount of data using minimal memory. <strong>Its main feature is the ability to decisively state the absence of an element while admitting a certain probability for its presence. </strong></p><p>It is represented by a finite array of bits, which are initially set to 0.</p><p>Unlike a HashMap, a Bloom filter doesn't save the actual values of the elements in the domain. Instead, <strong>it uses a bit array to store 0 and 1</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!r0aA!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!r0aA!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png 424w, /__u/substackcdn.com/image/fetch/$s_!r0aA!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png 848w, /__u/substackcdn.com/image/fetch/$s_!r0aA!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png 1272w, /__u/substackcdn.com/image/fetch/$s_!r0aA!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!r0aA!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png" width="394" height="281.42857142857144" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:560,&quot;resizeWidth&quot;:394,&quot;bytes&quot;:9570,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!r0aA!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png 424w, /__u/substackcdn.com/image/fetch/$s_!r0aA!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png 848w, /__u/substackcdn.com/image/fetch/$s_!r0aA!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png 1272w, /__u/substackcdn.com/image/fetch/$s_!r0aA!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F5662dad7-3a88-472c-aa41-377fa8942a0f_560x400.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">array of bits with the values 0 and 1 representing the Bloom Filter</figcaption></figure></div><p>This efficiency is achieved through the use of K hash functions, which map elements onto a bit array. However, due to the finite size of the array and potential hash collisions, false positives can occur, indicating the presence of an element that isn't actually there.</p><p>The size cannot be changed once it has been established since doing so would result in the loss of references between bit array locations with hash function results. Changing the size requires recreating the filter all over again.</p><p>This efficiency makes Bloom Filters a top choice in many applications where fast operations and memory-saving are key priorities.</p><h4>Hash functions</h4><p>To ensure swift performance, it's essential for hash functions to distribute the domain values evenly across the filter and generate collisions infrequently. It's good practice to test the filter with elements from your domain to understand its performance and make adjustments as necessary.</p><p>Typical hash functions used are:</p><ul><li><p>SHA256</p></li><li><p>MurmurHash</p></li><li><p>Fowler&#8211;Noll&#8211;Vo (FNV)</p></li></ul><h4>Search of an item</h4><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!4b02!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!4b02!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif 424w, /__u/substackcdn.com/image/fetch/$s_!4b02!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif 848w, /__u/substackcdn.com/image/fetch/$s_!4b02!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif 1272w, /__u/substackcdn.com/image/fetch/$s_!4b02!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!4b02!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif" width="462" height="330" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:560,&quot;resizeWidth&quot;:462,&quot;bytes&quot;:94192,&quot;alt&quot;:&quot;&quot;,&quot;title&quot;:null,&quot;type&quot;:&quot;image/gif&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" title="" srcset="/__u/substackcdn.com/image/fetch/$s_!4b02!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif 424w, /__u/substackcdn.com/image/fetch/$s_!4b02!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif 848w, /__u/substackcdn.com/image/fetch/$s_!4b02!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif 1272w, /__u/substackcdn.com/image/fetch/$s_!4b02!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe7fe7a25-c6f0-4e27-aca0-bb821dcc5abd_560x400.gif 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">search for &#8220;Marco&#8220; element in the Bloom Filter</figcaption></figure></div>
      <p>
          <a href="/__u/implementing.substack.com/p/reduce-database-load-by-bloom-filters">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[How to Implement a Magic Link Authentication using Node.js and JSON Web Token (JWT)]]></title><description><![CDATA[Common passwordless authentication method - Edition #17]]></description><link>https://implementing.substack.com/p/how-to-implement-a-magic-link-authentication</link><guid isPermaLink="false">https://implementing.substack.com/p/how-to-implement-a-magic-link-authentication</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Mon, 08 Apr 2024 05:38:48 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/e87028e8-13a8-4c4f-90bf-429908596eb0_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>in this episode I will explain how the magic link authentication mechanism works by showing you an example of the implementation.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/magic-link-auth">https://github.com/marcomoauro/magic-link-auth</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>Passwordless login is a modern authentication method that allows users to access their accounts without entering a traditional password. </p><p>Instead of relying on passwords, users receive a secure authentication link or code via email, SMS, or other communication channels. This approach enhances security by reducing the risks associated with password-based authentication, such as password theft or phishing attacks. </p><p>This approach provides a seamless and user-friendly authentication experience while maintaining a high level of security</p><h4>Substack login</h4><p>Substack also uses this approach for its users' logins.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!Zvhd!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!Zvhd!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png 424w, /__u/substackcdn.com/image/fetch/$s_!Zvhd!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png 848w, /__u/substackcdn.com/image/fetch/$s_!Zvhd!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Zvhd!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!Zvhd!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png" width="402" height="278.5141903171953" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:830,&quot;width&quot;:1198,&quot;resizeWidth&quot;:402,&quot;bytes&quot;:101543,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!Zvhd!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png 424w, /__u/substackcdn.com/image/fetch/$s_!Zvhd!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png 848w, /__u/substackcdn.com/image/fetch/$s_!Zvhd!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png 1272w, /__u/substackcdn.com/image/fetch/$s_!Zvhd!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7d2e2757-8269-4fd6-8691-938c9bf43cc7_1198x830.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Substack login: <a href="/__u/substack.com/sign-in?redirect=%2Fhome-i">https://substack.com/sign-in</a></figcaption></figure></div><p>If the login is successful, a <strong>session</strong> token is generated. It is configured as a Set-Cookie, so each time the client contacts the server, the token is automatically sent, ensuring correct identification. This approach is stateful, meaning that a state is managed on the database side.</p><p><strong>How do I know this information?</strong> </p><p>I made a system that allows email sequences to be sent in Substack, to make it I used the internals calls that the client makes to the backend, to make them work I reverse engineered the platform to understand how the communication happens. I documented everything in this episode:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;939d811e-f71b-4369-ad8a-379f3c3457bf&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;How to Create Email Sequences on Substack&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null},{&quot;id&quot;:6835984,&quot;name&quot;:&quot;Luca Rossi&quot;,&quot;bio&quot;:&quot;I write everyday about how to make great software and work well with humans, to 60K+ friends.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2Ff6107486-b701-4109-8f21-f450fed6e277_652x690.png&quot;,&quot;is_guest&quot;:true,&quot;bestseller_tier&quot;:1000,&quot;primaryPublicationSubscribeUrl&quot;:&quot;https://refactoring.fm/subscribe?&quot;,&quot;primaryPublicationUrl&quot;:&quot;https://refactoring.fm&quot;,&quot;primaryPublicationName&quot;:&quot;Refactoring&quot;,&quot;primaryPublicationId&quot;:64099}],&quot;post_date&quot;:&quot;2024-02-12T06:39:14.998Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/b994c390-af59-460f-9466-4ddbb4aea628_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/how-to-create-email-sequences-on&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:141435927,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p><strong>JSON Web Tokens</strong> simplify this mechanism. Firstly, the protocol is stateless, which means the token contains all necessary information for verification such as issuer, expiration, and authenticity. It also allows for a payload (claim) to store useful information like user ID or email. This payload mustn't contain sensitive information since the claim is often sent with only Base64 encoding; for sensitive data, encryption is recommended.</p><blockquote><p>Are you curious about how JSON Web Tokens work and the encryption methods that can be used? Sign up, I'll share a post with you in the upcoming weeks!</p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#10067; How it works</h2><p>We can use this sequence diagram to explain how magic link authentication works:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="/__u/substackcdn.com/image/fetch/$s_!7b5a!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="/__u/substackcdn.com/image/fetch/$s_!7b5a!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png 424w, /__u/substackcdn.com/image/fetch/$s_!7b5a!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png 848w, /__u/substackcdn.com/image/fetch/$s_!7b5a!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png 1272w, /__u/substackcdn.com/image/fetch/$s_!7b5a!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_webp, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png 1456w" sizes="100vw"><img src="/__u/substackcdn.com/image/fetch/$s_!7b5a!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png" width="706" height="559.152" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:792,&quot;width&quot;:1000,&quot;resizeWidth&quot;:706,&quot;bytes&quot;:64193,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:null,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="/__u/substackcdn.com/image/fetch/$s_!7b5a!, /__u/implementing.substack.com/w_424, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png 424w, /__u/substackcdn.com/image/fetch/$s_!7b5a!, /__u/implementing.substack.com/w_848, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png 848w, /__u/substackcdn.com/image/fetch/$s_!7b5a!, /__u/implementing.substack.com/w_1272, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png 1272w, /__u/substackcdn.com/image/fetch/$s_!7b5a!, /__u/implementing.substack.com/w_1456, /__u/implementing.substack.com/c_limit, /__u/implementing.substack.com/f_auto, /__u/implementing.substack.com/q_auto:good, /__u/implementing.substack.com/fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F486fa3cd-19be-4fc6-8d79-50b2b8686708_1000x792.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Sequence diagram representing interactions for magic link authentication process</figcaption></figure></div><ol><li><p>User starts the registration process by entering their email address</p></li></ol>
      <p>
          <a href="/__u/implementing.substack.com/p/how-to-implement-a-magic-link-authentication">
              Read more
          </a>
      </p>
   ]]></content:encoded></item><item><title><![CDATA[How to Create a Mailer in Node.js using Gmail account]]></title><description><![CDATA[Edition #16]]></description><link>https://implementing.substack.com/p/how-to-create-mailer-nodejs-using-gmail-account</link><guid isPermaLink="false">https://implementing.substack.com/p/how-to-create-mailer-nodejs-using-gmail-account</guid><dc:creator><![CDATA[Marco Moauro]]></dc:creator><pubDate>Tue, 02 Apr 2024 05:38:06 GMT</pubDate><enclosure url="https://substack-post-media.s3.amazonaws.com/public/images/003d2dc6-4a5b-4a14-8fed-7be21af6c31e_560x400.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey, I'm <a href="https://www.linkedin.com/in/marco-moauro-b49489162/">Marco</a> and welcome to my newsletter!</p><p>As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.</p><p>In this episode, I'll show you how to set up an email sending system using Node.js with a Gmail account.</p><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/mailer">https://github.com/marcomoauro/mailer</a></p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128075; Introduction</h2><p>One of the first projects I did was to create a simple script for sending e-mails. I was excited about the idea of sending messages for free, just like most websites do.</p><p>Email is a straightforward and effective system. All you need is an address to send a message.</p><p>We will refer to Gmail, but the same applies to other email providers. If you are interested in how to do the setup, let me know in the comments.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/p/how-to-create-mailer-nodejs-using-gmail-account/comments&quot;,&quot;text&quot;:&quot;Leave a comment&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="/__u/implementing.substack.com/p/how-to-create-mailer-nodejs-using-gmail-account/comments"><span>Leave a comment</span></a></p><h4>Alternatives</h4><p>Another simple notification system, besides e-mail, could be the use of a Telegram group where a Bot sends messages to the channel via Webhook.</p><p> A downside is that, unlike e-mail, it requires an initial set-up where users have to be added to the group. </p><p>I show how to create Telegram bots and set up webhooks in this post:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;32e38813-bbc0-4b0e-803c-b2f4b00e34ca&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;How to Create a Bot that Notifies you on Telegram&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-01-22T06:36:40.051Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/61da3d00-366a-40c9-b9f2-a257f2eb1de0_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/how-to-create-a-bot-that-notifies&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:140740475,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#9881;&#65039; Configure Gmail account</h2><p>To use your Gmail account for sending emails, you'll first need to create a new &#8220;app&#8221; within your account settings. Here are the steps to follow:</p><ul><li><p><strong>enable 2FA</strong></p></li></ul><p>Go to the <strong>Security</strong> panel of your Google account via this link <a href="https://myaccount.google.com/u/2/security">https://myaccount.google.com/u/2/security</a> and activate the two-step verification, it is a necessary step to proceed with the creation of the app.</p><ul><li><p><strong>create new app</strong></p></li></ul><p>from this link <a href="https://myaccount.google.com/apppasswords">https://myaccount.google.com/apppasswords</a> proceed to create the app, all you have to do is choose a name. A password will be generated, which you will use to send emails with the <strong>nodemailer</strong> library.</p><blockquote><p>I found this information on <a href="https://stackoverflow.com/questions/71477637/nodemailer-and-gmail-after-may-30-2022/72477193#72477193">stackoverflow</a>, it saved me from wasting hours trying to configure it myself. &#128591;</p></blockquote><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://implementing.substack.com/subscribe&quot;,&quot;text&quot;:&quot;Subscribe to Implementing &#128187;&quot;,&quot;action&quot;:null,&quot;class&quot;:&quot;button-wrapper&quot;}" data-component-name="ButtonCreateButton"><a class="button primary button-wrapper" href="/__u/implementing.substack.com/subscribe"><span>Subscribe to Implementing &#128187;</span></a></p><div><hr></div><h2>&#128104;&#8205;&#128187; Let&#8217;s get down to practice</h2><blockquote><p>You can download all the code shown directly from my Github repository: <a href="https://github.com/marcomoauro/mailer">https://github.com/marcomoauro/mailer</a></p></blockquote><h4>Nodemailer</h4><p>For sending e-mails, I relied on the <a href="/__u/implementing.substack.com/i/142535901/nodemailer">nodemailer</a> library, which is the default solution for most Node.js users.</p><h4>Implementation</h4><p>For the implementation I used my template in Node.js, you can find it here:</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;362d0b52-966e-46d9-8477-0bddfd654388&quot;,&quot;caption&quot;:&quot;Hey, I'm Marco and welcome to my newsletter! As a software engineer, I created this newsletter to share my first-hand knowledge of the development world. Each topic we will explore will provide valuable insights, with the goal of inspiring and helping all of you on your journey.&quot;,&quot;cta&quot;:null,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;My Backend Template for Node.js&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:41640433,&quot;name&quot;:&quot;Marco Moauro&quot;,&quot;bio&quot;:&quot;Senior Software Engineer with 8+ years of experience in software design and development.\nThe solutions I developed in the last 2 years are currently used by companies such Airbnb, Uber and Skyscanner.&quot;,&quot;photo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1a131b28-eb85-4afb-a225-ea9231564158_1891x2950.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2024-01-08T06:33:29.923Z&quot;,&quot;cover_image&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9763a243-10fc-46c4-b67b-5ee83413e1e6_560x400.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://implementing.substack.com/p/my-backend-template-for-nodejs&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:140322610,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:null,&quot;publication_name&quot;:&quot;Implementing&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdaba889f-fab1-4b3e-b9d9-140c181fa0a1_512x512.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Set up the environment variables by specifying in the <strong>.env</strong> file the email and password previously generated</p><pre><code><code>MAILER_USER=&lt;YOUR-GOOGLE-MAIL&gt;
MAILER_PASSWORD=&lt;APP-PASSWORD&gt;</code></code></pre><p>We create the file <strong>mailer.js</strong>, it takes care of exposing the primitives of the nodemailer library to enable the correct sending of e-mails:</p><pre><code>import nodemailer from 'nodemailer';
import <em>log </em>from "../log.js";

import {<em>strict </em>as assert} from 'assert';

<em>assert</em>(<em>process</em>.env.MAILER_USER, 'MAILER_USER env is required, define it in .env file')
<em>assert</em>(<em>process</em>.env.MAILER_PASSWORD, 'MAILER_PASSWORD env is required, define it in .env file')

const transporter = nodemailer.createTransport({
  service: 'gmail',
  auth: {
    user: <em>process</em>.env.MAILER_USER,
    pass: <em>process</em>.env.MAILER_PASSWORD
  }
});

export const sendMailApi = async ({email, subject, body}) =&gt; {
  <em>log</em>.info('API::Mailer::sendMailApi', {email, subject, body});

  const response = await transporter.sendMail({
    from: <em>process</em>.env.MAILER_USER,
    to: email,
    subject,
    text: body,
  });

  return response;
}</code></pre><p>we create the controller <strong>mailer.js</strong> which will be responsible for receiving parameters from the api and sending them to the service:</p><pre><code>import <em>log </em>from "../log.js";
import {sendMailApi} from "../api/mailer.js";

export const sendMail = async ({email, subject, body}) =&gt; {
  <em>log</em>.info('Controller::Mailer::sendMail', {email, subject, body});

  await sendMailApi({email, subject, body});

  return {
    message: 'Mail sent'
  };
}</code></pre><p>and finally create a new api in the <strong>router.js</strong> file:</p><pre><code>import {sendMail} from "./controllers/mailer.js";

<em>router</em>.post('/send-mail', routeToFunction(sendMail));</code></pre><h4>How to test</h4><p>You can verify the proper operation by starting the server with:</p><pre><code>yarn serve:development</code></pre><p>and making a call to the new endpoint with:</p><pre><code>curl --location 'http://localhost/send-mail' \
--header 'Content-Type: application/json' \
--data-raw '{
  "email": "marcomoauro@hotmail.it",
  "subject": "Test Subject from Node.js Mailer",
  "body": "Example body for Implementing post"
}'</code></pre><h4>Deploy</h4>
      <p>
          <a href="/__u/implementing.substack.com/p/how-to-create-mailer-nodejs-using-gmail-account">
              Read more
          </a>
      </p>
   ]]></content:encoded></item></channel></rss>