<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: One Beyond</title>
    <description>The latest articles on Forem by One Beyond (@one-beyond).</description>
    <link>https://forem.com/one-beyond</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Forganization%2Fprofile_image%2F3332%2F18237b7a-c3e0-4b35-9ca0-868bc31ba343.png</url>
      <title>Forem: One Beyond</title>
      <link>https://forem.com/one-beyond</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/one-beyond"/>
    <language>en</language>
    <item>
      <title>Deploying a React + Vite SPA to a Private S3 Bucket with CloudFront and OAC</title>
      <dc:creator>Pablo Eliseo</dc:creator>
      <pubDate>Wed, 19 Feb 2025 14:19:32 +0000</pubDate>
      <link>https://forem.com/one-beyond/deploying-a-react-vite-spa-to-a-private-s3-bucket-with-cloudfront-and-oac-mhh</link>
      <guid>https://forem.com/one-beyond/deploying-a-react-vite-spa-to-a-private-s3-bucket-with-cloudfront-and-oac-mhh</guid>
      <description>&lt;p&gt;Deploying a React + Vite single-page application (SPA) to a private AWS S3 bucket while using CloudFront with Origin Access Control (OAC) requires careful setup, especially to handle client-side routing and asset paths properly. This guide will walk you through the complete process, highlighting critical aspects such as &lt;code&gt;custom_error_response&lt;/code&gt; in CloudFront and the &lt;code&gt;base&lt;/code&gt; config in &lt;code&gt;vite.config.js&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Understanding How OAC, CloudFront, and S3 Work Together&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;What is Origin Access Control (OAC)?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;OAC is a mechanism that allows CloudFront to securely access private content stored in an S3 bucket without exposing the bucket to the public internet. It replaces the older Origin Access Identity (OAI) with better security and fine-grained access control.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;How CloudFront Works with S3 and OAC&lt;/strong&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;S3 Bucket:&lt;/strong&gt; Stores your static site files (HTML, JS, CSS, images, etc.). Since it's private, it cannot be accessed directly via a public URL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CloudFront Distribution:&lt;/strong&gt; Acts as a content delivery network (CDN), caching and serving requests efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;OAC:&lt;/strong&gt; Grants CloudFront permission to fetch content from the private S3 bucket.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Custom Error Handling:&lt;/strong&gt; Ensures deep links and client-side routing work properly by redirecting 404 errors for non-existing objects to &lt;code&gt;index.html&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With this setup, users access CloudFront, which in turn retrieves the content from the private S3 bucket, ensuring security and performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Setting Up the S3 Bucket&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Since the S3 bucket is private, it must be configured to allow CloudFront access via OAC.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Terraform Configuration:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"spa_bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"react-vite-app"&lt;/span&gt;
  &lt;span class="nx"&gt;acl&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"private"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_policy"&lt;/span&gt; &lt;span class="s2"&gt;"bucket_policy"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spa_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

  &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Sid&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"AllowCloudFrontAccess"&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Service&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"cloudfront.amazonaws.com"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;
        &lt;span class="nx"&gt;Resource&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"${aws_s3_bucket.spa_bucket.arn}/*"&lt;/span&gt;
        &lt;span class="nx"&gt;Condition&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;StringEquals&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"AWS:SourceArn"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_cloudfront_distribution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spa_distribution&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;3. Creating a CloudFront Distribution with Custom Error Handling&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;A major challenge when deploying an SPA is handling client-side routing. When a user directly visits &lt;code&gt;/dashboard&lt;/code&gt; or &lt;code&gt;/profile&lt;/code&gt;, CloudFront will look for &lt;code&gt;dashboard/index.html&lt;/code&gt; or &lt;code&gt;profile/index.html&lt;/code&gt; in S3, which doesn't exist. To fix this, we use &lt;code&gt;custom_error_response&lt;/code&gt; to serve &lt;code&gt;index.html&lt;/code&gt; whenever CloudFront encounters a 404 error.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why Use &lt;code&gt;custom_error_response&lt;/code&gt;?&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;SPAs rely on client-side routing.&lt;/strong&gt; The React app should handle the routes, not CloudFront.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prevents 404 errors.&lt;/strong&gt; Instead of returning a 404 from S3, CloudFront serves &lt;code&gt;index.html&lt;/code&gt;, allowing React to handle the routing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Terraform Configuration:&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_cloudfront_distribution"&lt;/span&gt; &lt;span class="s2"&gt;"spa_distribution"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;enabled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

  &lt;span class="nx"&gt;origin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;domain_name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;spa_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket_regional_domain_name&lt;/span&gt;
    &lt;span class="nx"&gt;origin_id&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"spa-s3-origin"&lt;/span&gt;
    &lt;span class="nx"&gt;origin_access_control_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_cloudfront_origin_access_control&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;oac&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;default_cache_behavior&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;allowed_methods&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"HEAD"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;cached_methods&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"GET"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"HEAD"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="nx"&gt;target_origin_id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"spa-s3-origin"&lt;/span&gt;
    &lt;span class="nx"&gt;viewer_protocol_policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"redirect-to-https"&lt;/span&gt;

    &lt;span class="nx"&gt;forwarded_values&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;query_string&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="nx"&gt;cookies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;forward&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"none"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;custom_error_response&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;error_code&lt;/span&gt;         &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;
    &lt;span class="nx"&gt;response_code&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
    &lt;span class="nx"&gt;response_page_path&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"/index.html"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It is very important here not to use the &lt;code&gt;origin_request_policy_id = "216adef6-5c7f-47e4-b989-5492eafa07d3" # AllViewer - Default ID&lt;/code&gt; as the AllViewer request policy forwards the host to the S3 bucket which will be configured to only accept requests from Cloudfront.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4. Why Use Vite Instead of Webpack?&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Advantages of Vite&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Faster Development:&lt;/strong&gt; Vite uses native ES modules, significantly improving development speed compared to Webpack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Better Performance:&lt;/strong&gt; It only rebuilds changed files instead of bundling everything together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimized Build Output:&lt;/strong&gt; Vite produces highly optimized static assets, reducing bundle size and improving load times.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For SPAs, especially with React, Vite provides a better developer experience and faster deployments.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;5. When to Use This Approach vs. Other Alternatives&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Use This Approach When:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need a &lt;strong&gt;pure client-side application&lt;/strong&gt; without server-side rendering (SSR).&lt;/li&gt;
&lt;li&gt;You want &lt;strong&gt;cost-effective static hosting&lt;/strong&gt; with high security.&lt;/li&gt;
&lt;li&gt;You want full control over AWS infrastructure.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Consider Other Options When:&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js:&lt;/strong&gt; If you need SSR or static site generation (SSG), Next.js on Vercel or AWS Lambda may be a better choice.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gatsby:&lt;/strong&gt; If your site is primarily static content with pre-built pages.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AWS Amplify:&lt;/strong&gt; If you prefer a managed service that simplifies the deployment process.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;6. Configuring Vite for Correct Asset Paths&lt;/strong&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why the &lt;code&gt;base&lt;/code&gt; Option in &lt;code&gt;vite.config.js&lt;/code&gt;?&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Vite's &lt;code&gt;base&lt;/code&gt; configuration determines how URLs are resolved in the generated output. If not set correctly, assets (JavaScript, CSS, favicon) may try to load from incorrect paths when navigating to deeper routes.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Why Use &lt;code&gt;base: '/'&lt;/code&gt;?&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vite&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;react&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@vitejs/plugin-react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Ensures all assets use absolute paths from the root&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;react&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;outDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;dist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;7. Deploying with GitHub Actions&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;To automate deployment, we use GitHub Actions to build and upload the React app to the S3 bucket. I am using &lt;a href="https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#using-secrets-in-a-workflow" rel="noopener noreferrer"&gt;Github Actions Secrets and Variables&lt;/a&gt; for configuring the workflow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy to S3&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;main&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout Code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v3&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Node.js&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;18&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Application&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run build&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Configure&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws-actions/configure-aws-credentials@v4.0.2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;aws-region&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;vars.AWS_REGION&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}"&lt;/span&gt;
          &lt;span class="na"&gt;role-to-assume&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:iam::${{&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;vars.AWS_ACCOUNT_ID&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;}}:role/github-actions_role"&lt;/span&gt;
          &lt;span class="na"&gt;role-session-name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GitHub-Actions_Publish_Static_Site"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Deploy static site to S3 bucket&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;aws s3 sync ./dist/ s3://${{ vars.AWS_S3_BUCKET_NAME }} --delete --region ${{ vars.AWS_REGION }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, I am configuring the AWS credentials by using a IAM role. See &lt;a href="https://aws.amazon.com/blogs/security/use-iam-roles-to-connect-github-actions-to-actions-in-aws/" rel="noopener noreferrer"&gt;this guide&lt;/a&gt; for more information on the topic.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This guide covered deploying a React + Vite SPA securely on AWS using S3, CloudFront, and OAC. By setting up CloudFront with &lt;code&gt;custom_error_response&lt;/code&gt;, using Vite for efficient builds, and automating deployment with GitHub Actions, you ensure a smooth, performant, and cost-effective solution for hosting your SPA.&lt;br&gt;
You can find the full code (with some more improvements) in this &lt;a href="https://github.com/pabloelisseo/react-vite-s3-cloudfront" rel="noopener noreferrer"&gt;GitHub repository&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>vite</category>
      <category>s3</category>
      <category>aws</category>
    </item>
    <item>
      <title>Stress Management</title>
      <dc:creator> Anna Csurgai</dc:creator>
      <pubDate>Wed, 24 Apr 2024 09:30:37 +0000</pubDate>
      <link>https://forem.com/one-beyond/stress-management-32l5</link>
      <guid>https://forem.com/one-beyond/stress-management-32l5</guid>
      <description>&lt;p&gt;As we reviewed in the &lt;a href="https://dev.to/one-beyond/stress-awareness-33pb"&gt;first part of this blog series&lt;/a&gt;, the starting point for stress management is awareness of our stress levels. Once we realize we are stressed, we often unconsciously ask ourselves the following questions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can we &lt;strong&gt;manage&lt;/strong&gt; the situation? &lt;/li&gt;
&lt;li&gt;Is it within our &lt;strong&gt;control&lt;/strong&gt;? &lt;/li&gt;
&lt;li&gt;Can we &lt;strong&gt;solve&lt;/strong&gt; it? &lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;solutions&lt;/strong&gt; do we see? &lt;/li&gt;
&lt;li&gt;If we can't manage it, how should we &lt;strong&gt;cope&lt;/strong&gt;? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In this blog, we delve into various aspects of stress management, exploring concepts like the three main arousal responses to stress and the difference between problem-focused and emotion-focused coping strategies. The stress container self-reflective task helps us analyse our mood and identify actions we can take. Additionally, we'll discuss tips for managing workplace stress and the importance of our shields, which act as protective factors against stress and anxiety. Towards the end, you'll find thought-provoking questions to reflect on your coping mechanisms. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fight vs flight vs freeze (&amp;amp; fawn)&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;There is a general concept of how we and our bodies react when we perceive threats.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;fight&lt;/strong&gt; response activates a person to cope with perceived threats by &lt;strong&gt;taking action&lt;/strong&gt; to &lt;strong&gt;eliminate&lt;/strong&gt; the &lt;strong&gt;danger&lt;/strong&gt;. It results in physical changes like increased heart rate, higher blood pressure, adrenaline rush, and tightened jaw.
&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;flight&lt;/strong&gt; response involves &lt;strong&gt;escaping&lt;/strong&gt; the danger, seeking safety and distance from the source of the stress. This response triggers a cascade of physiological changes, including a surge in adrenaline, rapid heartbeat, shallow breathing, and tense muscles. The body readies itself for swift escape, prioritizing survival above all else. &lt;/li&gt;
&lt;li&gt;In contrast, the &lt;strong&gt;freeze&lt;/strong&gt; response involves a state of &lt;strong&gt;immobility&lt;/strong&gt;, where the individual becomes momentarily &lt;strong&gt;paralyzed&lt;/strong&gt; in the face of danger. Rather than confront or flee, they may find themselves unable to act, as if caught in a state of suspended animation. This response is characterized by a decrease in heart rate and muscle tension, often accompanied by a sense of detachment or dissociation from the surrounding environment. &lt;/li&gt;
&lt;li&gt;Lately, research has identified a fourth stress reaction pattern: &lt;strong&gt;fawn&lt;/strong&gt;. This is a little bit similar to the freeze response, but its core aspect is that we try to &lt;strong&gt;please&lt;/strong&gt; and &lt;strong&gt;appease the needs of someone else&lt;/strong&gt;, &lt;strong&gt;instead&lt;/strong&gt; of &lt;strong&gt;prioritizing&lt;/strong&gt; our &lt;strong&gt;own well-being&lt;/strong&gt;, so in the end we become more submissive in the situation. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Problem-focused or emotional-focused&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;problem-focused coping strategies aim&lt;/strong&gt; to &lt;strong&gt;chang&lt;/strong&gt;e or &lt;strong&gt;eliminate a stressor&lt;/strong&gt;. When you employ a strategy aimed at directly addressing the stressor itself, you are engaging in problem-focused coping. For instance, devising plans, solving problems, or removing the stressor altogether are all forms of problem-focused coping. &lt;br&gt;
&lt;strong&gt;Emotion-focused coping&lt;/strong&gt; is when you &lt;strong&gt;try to deal with your emotional response to the stressor&lt;/strong&gt;. If you are trying to reduce, eliminate, or simply tolerate your emotional response to a stressor, then you’re using emotion-focused coping. Examples include withdrawal, expressing anger and frustration, seeking emotional support, distracting oneself, engaging in rumination, and accepting resignation (acknowledging that the problem may persist). &lt;br&gt;
For example, if we have a higher workload, prioritizing our tasks or delegating them is a problem-focused solution, but acknowledging and celebrating small victories or milestones to stay motivated is more about emotion-focused coping. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Our Stress Container&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The Stress Container model illustrates &lt;strong&gt;how individuals manage&lt;/strong&gt; everyday &lt;strong&gt;stresses based on their level of vulnerability&lt;/strong&gt;. Those with low vulnerability possess larger containers, making them less susceptible to mental health issues. The size of the container can be due to a lot of factors from someone’s background, like the patterns that we went through in the previous part of this blog series. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfyq2kwpz62dapep1to8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flfyq2kwpz62dapep1to8.PNG" alt="Image description" width="800" height="472"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the container overflows, individuals may experience mental and physical illness. This is a &lt;strong&gt;learning process&lt;/strong&gt; to &lt;strong&gt;check &amp;amp; identify when our container is filling&lt;/strong&gt; and we have to &lt;strong&gt;actively manage&lt;/strong&gt; what is in there. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workplace stress&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Most of us experience stress during our personal lives but experience it more heavily during work. Most of the time we cannot show or express that we are stressed when we work, so we must minimize what our environment sees from it. In this case it is truly important to have some time for ourselves after a harsh meeting or project demo or the day itself where we can express it or reward ourselves after a hard day or period. &lt;/p&gt;

&lt;p&gt;Some key tips to manage our daily stress: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Taking a break&lt;/strong&gt; from work is needed, especially since our &lt;strong&gt;need for rest&lt;/strong&gt; is &lt;strong&gt;rising&lt;/strong&gt; with the &lt;strong&gt;increased spent time without rest&lt;/strong&gt;, so we should install breaks within our days and our schedule. Sometimes it is hard especially when we work remotely, to just walk around, or have a few minutes as a break while when we work in the office. Our environment can help us like having a coffee together or just chatting about something. However, &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Morning routine&lt;/strong&gt; can be key when it comes to keeping balance within our lives. Having some activity to do before we jump to our laptops can be hugely beneficial. Since remote working is truly part of our DNAS, we intend to start our day with coffee and our duties. Well, I cannot say that it never occurred to me, but I enjoy my day more if I have some time before I start working. This can be reading or doing sports, having your big walk with your dog or learning something. It does not have to be long activity, even 20-30 minutes are sufficient to have the feeling that you have already done something for yourself. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Setting up boundaries&lt;/strong&gt; is not an easy task to do. We have a lot of priorities and duties, and we can be overwhelmed with these and the feeling that we want to execute as many tasks as we want to and help as many colleagues as possible. However, &lt;strong&gt;assertively declining extra commitments&lt;/strong&gt; and clearly &lt;strong&gt;communicating availability&lt;/strong&gt; and &lt;strong&gt;preferred communication&lt;/strong&gt; methods are needed to create transparency and take care of ourselves. &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Leaving work behind&lt;/strong&gt; is not easy, switching off our working- mode, work-persona is essential, here are some tips: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Develop a shutdown routine&lt;/strong&gt; to signal the end of the workday. This could include tidying your workspace, reviewing your tasks for the next day, and mentally transitioning out of work mode.
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Prioritize Tasks:&lt;/strong&gt; Before leaving work, prioritize your tasks for the next day. Knowing what needs to be done can ease your mind and help you relax during your time off. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unplug:&lt;/strong&gt; Disconnect from work-related communication channels, such as email and work chat apps, when you are off the clock. Consider turning off notifications or even deleting work apps from your personal devices.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;strong&gt;Our shields&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;We can say that we can &lt;strong&gt;arm ourselves against stress&lt;/strong&gt;; this is what we can call &lt;strong&gt;“protective factors”&lt;/strong&gt;. This includes elements that can be obvious for some of us, but we can easily look over these under a stressful period and let go of the elements of a healthy lifestyle with charging and cheerful relationships. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sports:&lt;/strong&gt; Being active and taking care of our physical fitness is a protective factor against stress. It helps us to create balance within our lives, so it helps to relieve stress unconsciously. Additionally, we can use it as a conscious coping strategy, when after a hard-working day we decide to go for a run or a walk with our dog, or during a weekend having a trip in nature – all of these help us to manage our stress level and we can experience an eustress after an activity that we made it. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Nutrition&lt;/strong&gt; plays a huge part in how we feel daily. Whether we feel energized or fatigued depends on the micro and macro nutrients that we give to our body through foods. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sleep:&lt;/strong&gt; Rest is essential. Even if we eat well and engage in activities, if we do not sleep well or enough, we can harm ourselves. Sometimes sleep problems occur first when we tip over our balance, either we have restless nights, or we feel that we cannot sleep enough to rest. Based on scientific research like this we should aim for &lt;strong&gt;7-9 hours per night&lt;/strong&gt; in order to have proper time for regeneration. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hobbies:&lt;/strong&gt; Having time for your hobbies is great for recharging. Sometimes we skip this easily when we have a lot of things to do at work, which for a brief period of time can be an adaptive coping mechanism, but if we lose an activity whose aim was to refill our batteries then we cut out. &lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Mindfulness:&lt;/strong&gt; Being in the present has not been harder than during the last couple of years with our accelerated world. Incorporating mindfulness into our daily lives can help us manage stress. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Practice mindful breathing:&lt;/strong&gt; When you are feeling stressed or overwhelmed, take a few moments to focus on your breath. Close your eyes if possible, and take slow, deep breaths, paying attention to the sensation of the air moving in and out of your body. This simple mindfulness exercise can help calm your nervous system, bring you back to the present moment, and reduce the impact of stress. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Engage in mindful activities:&lt;/strong&gt; Incorporate mindfulness into your daily routine by &lt;strong&gt;engaging in activities with full awareness&lt;/strong&gt;. Whether you are eating, walking, or washing dishes, try to focus on the present moment and fully engage your senses. Notice the sights, sounds, smells, and textures around you without judgment. By bringing mindfulness to everyday activities, you can reduce stress and increase your overall sense of well-being. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Practice self-compassion:&lt;/strong&gt; When you are feeling stressed, it is &lt;strong&gt;easy to be hard on yourself&lt;/strong&gt; or &lt;strong&gt;engage in negative self-talk&lt;/strong&gt;. Instead, practice self-compassion by &lt;strong&gt;treating yourself&lt;/strong&gt; with &lt;strong&gt;kindness&lt;/strong&gt; and &lt;strong&gt;understanding&lt;/strong&gt;. Remind yourself that it's normal to feel stressed from time to time, and that you're doing the best you can in this moment. Offer yourself words of encouragement and support, just as you would to a friend in need. Mindfulness can help you cultivate a greater sense of self-compassion by allowing you to observe your thoughts and emotions with greater clarity and acceptance.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;As we can see, everything comes back to &lt;strong&gt;self-care&lt;/strong&gt;, &lt;strong&gt;knowing our self&lt;/strong&gt; and &lt;strong&gt;boundaries&lt;/strong&gt; and &lt;strong&gt;paying attention to our body and soul&lt;/strong&gt;. By understanding our stress responses and adopting a balance of problem-focused and emotion-focused coping strategies, along with taking care of ourselves and our lifestyle, we can effectively manage stress and &lt;strong&gt;foster resilience&lt;/strong&gt; in our daily lives. &lt;/p&gt;

&lt;p&gt;Some &lt;strong&gt;takeaway questions&lt;/strong&gt; which can help you to reflect on your copings and stress management techniques: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What are my go-to strategies for managing stress? Are they primarily problem-focused or emotion-focused? &lt;/li&gt;
&lt;li&gt;How effective are my current stress management techniques in helping me cope with different stressors? &lt;/li&gt;
&lt;li&gt;If I look at my stress container, what elements are within it? Is it overflowing? Can I take some elements from it? &lt;/li&gt;
&lt;li&gt;Do I tend to prioritize self-care, such as taking breaks, engaging in hobbies, or practising relaxation techniques, during stressful periods? &lt;/li&gt;
&lt;li&gt;How well do I set boundaries between work and personal life? Do I struggle to disconnect from work-related stressors? &lt;/li&gt;
&lt;li&gt;What role does physical activity play in my stress management routine? Am I consistently incorporating exercise into my daily or weekly schedule? &lt;/li&gt;
&lt;li&gt;What adjustments can I make to improve my sleep quality and ensure I get enough rest to support my well-being? &lt;/li&gt;
&lt;li&gt;How mindful am I of my thoughts and emotions during stressful situations? Do I practice mindfulness or other forms of mental relaxation regularly? &lt;/li&gt;
&lt;li&gt;Do I have a support system in place for seeking help or guidance when I feel overwhelmed by stress? &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>stressmanagement</category>
      <category>coping</category>
      <category>protectivefactors</category>
    </item>
    <item>
      <title>Know your patterns</title>
      <dc:creator> Anna Csurgai</dc:creator>
      <pubDate>Wed, 17 Apr 2024 08:52:59 +0000</pubDate>
      <link>https://forem.com/one-beyond/know-your-patterns-11e9</link>
      <guid>https://forem.com/one-beyond/know-your-patterns-11e9</guid>
      <description>&lt;p&gt;We are all different, and we each have our own ways of detecting stress; &lt;strong&gt;stressors&lt;/strong&gt; impact us at varying levels, &lt;strong&gt;influencing our stress levels differently&lt;/strong&gt;. Today’s article is all about &lt;strong&gt;understanding yourself&lt;/strong&gt;, &lt;strong&gt;emphasising the importance of recognising your patterns&lt;/strong&gt;, while keeping in mind that &lt;strong&gt;we are the protagonists&lt;/strong&gt; of &lt;strong&gt;our lives&lt;/strong&gt; and providing some key takeaway thoughts and questions. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Patterns from your family&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Our familial environment imparts patterns, best practices, and guidance for various aspects of our lives. We observe &lt;strong&gt;how our parents react to challenges in their jobs and family lives&lt;/strong&gt;, and these behaviours &lt;strong&gt;shape our own responses&lt;/strong&gt;. This unconscious programming evolves through experiences in kindergarten, elementary, high school, and university. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Patterns from school&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Our &lt;strong&gt;relationship with performance&lt;/strong&gt; is largely defined during our formative years in school. For many, coping mechanisms are first consciously experienced in this setting. We can develop &lt;strong&gt;positive habits&lt;/strong&gt; such as &lt;strong&gt;open communication&lt;/strong&gt; with friends and family about our problems or &lt;strong&gt;taking personal time to recharge&lt;/strong&gt;. However, we can also adopt harmful habits like using maladaptive coping mechanisms such as excessive video consumption, following news obsessively, or turning to substances like smoking, drinking, or drugs to escape stress. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Patterns from your workplace&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Our first workplaces hold a special place in our lives because they &lt;strong&gt;introduce&lt;/strong&gt; us to the &lt;strong&gt;functioning of a workplace&lt;/strong&gt; as we enter the labor market. Naturally, our previous patterns influence the type of workplaces we prefer and feel comfortable in, and we bring our personal coping mechanisms to each new environment. &lt;br&gt;
Furthermore, we not only influence group solutions to problems but also adapt to the coping mechanisms of our peers and the company. We learn how to cope with unexpected situations, how to communicate effectively, what steps to take if initial attempts fail, and how to support one another. &lt;br&gt;
While it is not solely our responsibility to change established practices within a larger community, what we can and must do is reflect on our coping strategies, identify areas for improvement, take action, and speak up when we encounter unhealthy coping patterns. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your place in it&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After considering all the environmental influences we've absorbed since childhood, it's difficult not to conclude that we should just adapt to what we've been given. Well, of course, there are some aspects of our lives when we are not in charge of making decisions and actions. But we are not there anymore. What we inherited is one thing, but &lt;strong&gt;how we process it&lt;/strong&gt; and &lt;strong&gt;how we cope with the incoming stressors&lt;/strong&gt; is something that we can influence, and we can make it better. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Self-knowledge&lt;/strong&gt; and &lt;strong&gt;self-reflection&lt;/strong&gt; are &lt;strong&gt;vital&lt;/strong&gt; for &lt;strong&gt;stress awareness&lt;/strong&gt; and &lt;strong&gt;management&lt;/strong&gt;. By &lt;strong&gt;understanding our own patterns, we can better navigate stressors and develop healthier coping mechanisms&lt;/strong&gt;. To facilitate this process, below are some thought-provoking questions: &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Takeaway questions:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Family Experience:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do you recall stress being managed or expressed within your family while growing up? &lt;/li&gt;
&lt;li&gt;What was your feeling: could your parents communicate their issues with each other? &lt;/li&gt;
&lt;li&gt;What were the primary stressors in your family environment, and do you notice any similarities between those and your current stress triggers? &lt;/li&gt;
&lt;li&gt;Reflect on the coping mechanisms you observed or adopted from your family members when dealing with stress. Are these mechanisms still effective or do they contribute to your stress? &lt;/li&gt;
&lt;li&gt;Are there any recurring patterns or dynamics in your family that you find mirrored in your own stress responses? &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;School Experience:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can you recall specific periods or events during your schooling that significantly increased your stress levels? How did you cope with them then, and how do you cope with similar situations now? &lt;/li&gt;
&lt;li&gt;Reflect on the academic pressures or social dynamics in school that might have contributed to your stress patterns. Do you find yourself experiencing similar pressures in your current life? &lt;/li&gt;
&lt;li&gt;How did teachers or peers influence your stress management strategies during your school years? Are there any habits or beliefs you developed during this time that you still carry with you?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Workplace Experience:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reflect on your earliest job experiences. What were the main stressors you encountered, and how did you initially cope with them? &lt;/li&gt;
&lt;li&gt;How have your stress triggers evolved as you progressed in your career? Are there any recurring themes or patterns in the stressors you face at work? &lt;/li&gt;
&lt;li&gt;Consider the organizational culture and management styles of your past and current workplaces. How have these factors influenced your stress levels and coping mechanisms? &lt;/li&gt;
&lt;li&gt;Have you observed any unhealthy patterns or behaviours in your professional life that contribute to your stress? How do you plan to address or change these patterns moving forward?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;General Self-Reflection:&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What similarities do you notice between the stress triggers and patterns you've identified across different areas of your life (family, school, work)? &lt;/li&gt;
&lt;li&gt;Are there any specific events or experiences that stand out as particularly influential in shaping your current stress responses? &lt;/li&gt;
&lt;li&gt;How do you typically react to stress? Are your reactions primarily emotional, physical, or behavioural? (We have reviewed the reaction types in our first blog of Stress Awareness Month series so you can check &lt;a href="https://dev.to/one-beyond/stress-awareness-33pb"&gt;here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Reflect on the effectiveness of your current stress management strategies. What adjustments or improvements could you make to better address your stress triggers and patterns? &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>stressawareness</category>
      <category>mentalhealth</category>
      <category>wellbeing</category>
      <category>selfawareness</category>
    </item>
    <item>
      <title>Stress Awareness</title>
      <dc:creator> Anna Csurgai</dc:creator>
      <pubDate>Wed, 10 Apr 2024 08:35:35 +0000</pubDate>
      <link>https://forem.com/one-beyond/stress-awareness-33pb</link>
      <guid>https://forem.com/one-beyond/stress-awareness-33pb</guid>
      <description>&lt;p&gt;Stress is part of our everyday life; it is a normal thing to be stressed sometimes. So, someone could ask: then what is the deal about it? Why should we highlight this when it is an essence of our lives? &lt;/p&gt;

&lt;p&gt;Well, it is true that we cannot block ourselves from stress unless we decide to leave our society and enter a monastery, but even there, we would face stress and internal movements. So, the upcoming questions remain: how can we live and cope with it? Can we detect it when we feel stressed? Do we know what are our patterns? Can we manage it? What do we do if we feel stressed when we are not under control? How can we protect ourselves in these highly stressful situations? What kind of protective factors can we make to have balance in our lives? &lt;/p&gt;

&lt;p&gt;April is &lt;strong&gt;International Stress Awareness Month&lt;/strong&gt;, so we aim to cover with &lt;strong&gt;a three-part series of blogs&lt;/strong&gt; the questions of &lt;strong&gt;stress awareness, our patterns&lt;/strong&gt; and &lt;strong&gt;coping strategies&lt;/strong&gt;. As part of our Mental Health First Aider community and with my studies in psychology, I thought that it would be beneficial to have an overview of this topic and make some time for us to reflect on our connection with stress. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stress &amp;amp; stressors&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Stress is how we react when we feel under pressure or threatened. It typically arises &lt;strong&gt;when we find ourselves in circumstances&lt;/strong&gt; that &lt;strong&gt;we perceive as beyond our ability to manage or control&lt;/strong&gt;.  Of course, there are cases when this stress level is negotiable and we think that the situation is under our control, and this eustress has a facilitator mode. However, if &lt;strong&gt;the stressor&lt;/strong&gt; is &lt;strong&gt;too intensive&lt;/strong&gt; or &lt;strong&gt;our capabilities are not enough to control&lt;/strong&gt; or fight with the situation then we can &lt;strong&gt;label&lt;/strong&gt; it as &lt;strong&gt;distress&lt;/strong&gt;. Generally, we can say that long-lasting or intensive stress can have serious impacts on our lives. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stress &amp;amp; Self-awareness&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We could think that it is a natural thing to be aware of being stressed, but it is not that simple. For example: If someone grows up believing stress is normal and emotional instability is common in their family, they're likely to seek out similar situations in their relationships and workplaces. Even if it's not healthy, we often gravitate towards what's familiar because it feels safe. &lt;br&gt;
&lt;strong&gt;Sometimes it is not easy to realize that what we feel&lt;/strong&gt; – whether it's long-lasting or intense stress – is &lt;strong&gt;maladaptive&lt;/strong&gt; or that &lt;strong&gt;we are overwhelmed by it&lt;/strong&gt;. Therefore, it is recommended to take some time regularly to conduct a self-check analysis, where there is an opportunity to observe our current psychological, physical, and behavioural states. We can &lt;strong&gt;divide the symptoms&lt;/strong&gt; into &lt;strong&gt;3 categories&lt;/strong&gt;: &lt;/p&gt;

&lt;p&gt;Common Psychical symptoms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sleep problems&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headache&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fatigue&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Indigestion&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Chest pains and high blood pressure &lt;/li&gt;
&lt;li&gt;Difficulty breathing &lt;/li&gt;
&lt;li&gt;Blood pressure increased &lt;/li&gt;
&lt;li&gt;Sudden weight gain or weight loss &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Feeling sick, dizzy or fainting&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Panic attacks &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Common Physiological symptoms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feeling &lt;strong&gt;anxiety&lt;/strong&gt;, &lt;strong&gt;nervousness&lt;/strong&gt; and &lt;strong&gt;afraid&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Irritability&lt;/strong&gt;, &lt;strong&gt;angry&lt;/strong&gt; or &lt;strong&gt;impatient&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Over-burdened&lt;/strong&gt; or &lt;strong&gt;overwhelmed&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Your mind is a buzzing hive of activity, &lt;strong&gt;unable to calm&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of concertation&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Neglected&lt;/strong&gt; or &lt;strong&gt;lonely&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Depressed&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Mental health problems occur or existing ones getting worse &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Common Behavioural symptoms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Withdrawal from social activities&lt;/strong&gt; or &lt;strong&gt;isolating yourself from others&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Increased use of substances (like alcohol, tobacco, or drugs) &lt;/li&gt;
&lt;li&gt;Changes in eating habits (overeating or undereating) &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Procrastination&lt;/strong&gt; or avoidance of tasks that feel overwhelming &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Difficulty relaxing&lt;/strong&gt; or enjoying leisure activities, hobbies &lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Performance difficulties&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recognising&lt;/strong&gt; these &lt;strong&gt;signs early allows&lt;/strong&gt; you to &lt;strong&gt;take proactive steps&lt;/strong&gt; to &lt;strong&gt;manage stress&lt;/strong&gt; before it escalates and leads to potential stress-related issues or burnout. It's important to remember that &lt;strong&gt;everyone experiences stress differently&lt;/strong&gt;, so being mindful of your own unique signs and symptoms is crucial. Plus, it is also beneficial if you are open to observing and learning your loved ones’ behaviours when it comes to stress. By paying attention to these signals, you can develop strategies to cope with your stress effectively and be supportive of your family and friends. &lt;/p&gt;

&lt;p&gt;Some &lt;strong&gt;takeaway questions&lt;/strong&gt; which can help you to raise your awareness and self-knowledge: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What kind of symptoms do you face when you are stressed? &lt;/li&gt;
&lt;li&gt;What are the stressors that you are highly sensitive to? &lt;/li&gt;
&lt;li&gt;Reflecting on your past experiences, have there been times when you ignored the signs of stress until it became overwhelming? What did you learn from those experiences? &lt;/li&gt;
&lt;li&gt;Reflect on the physical, psychological, and behavioural symptoms of stress listed in the article. Which of these symptoms do you tend to experience most frequently, and how do they manifest in your daily life? &lt;/li&gt;
&lt;li&gt;Imagine a scenario where you feel stressed but are unable to identify the cause immediately. What steps can you take to explore and address the root of your stress? &lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>stressawareness</category>
      <category>mentalhealth</category>
      <category>wellbeing</category>
      <category>symptomsofstress</category>
    </item>
    <item>
      <title>Mentor tools VII - Set up goals</title>
      <dc:creator>Irene Mateo Herrero</dc:creator>
      <pubDate>Fri, 15 Mar 2024 13:43:29 +0000</pubDate>
      <link>https://forem.com/one-beyond/mentor-tools-vii-set-up-goals-22bk</link>
      <guid>https://forem.com/one-beyond/mentor-tools-vii-set-up-goals-22bk</guid>
      <description>&lt;p&gt;Is it time to &lt;strong&gt;help your mentee set up their goals&lt;/strong&gt; for the year and you don't quite know how to do it? &lt;/p&gt;

&lt;p&gt;Or maybe you need a &lt;strong&gt;guide to set up your own goals&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;Setting goals may seem like a simple task, &lt;strong&gt;but how many times have you failed to achieve your goals&lt;/strong&gt;? How many times has a mentee set a goal at the beginning of the year and by the end of the year it was &lt;strong&gt;half done or not even started&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;To increase the chances of achieving your goals, it is essential to &lt;strong&gt;choose them and formulate them well&lt;/strong&gt;. I usually hold a specific meeting (or even two) with my mentees for this purpose. I listen carefully to their ideas but, above all, &lt;strong&gt;I ask a lot of questions to help them clarify and make their own decisions.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;Do you want to know &lt;strong&gt;how I approach the meeting&lt;/strong&gt; in which my mentees set their goals? Read on!&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Ask, ask, ask
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Choosing goals is a very personal decision&lt;/strong&gt;. Maybe it has happened to you that someone has said "&lt;strong&gt;Hey, why don't you do this?&lt;/strong&gt;" and you, even knowing that it was in some sense positive for you, have &lt;strong&gt;not found the motivation&lt;/strong&gt; to do it or have not given it enough priority. &lt;/p&gt;

&lt;p&gt;The reason this happens is that &lt;strong&gt;we each have our own abilities, limitations, motivations, priorities...&lt;/strong&gt; so it is very difficult for someone else to propose something to you that connects and fits with all of this. But there is someone who can hit the nail on the head: &lt;strong&gt;YOU&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;However, &lt;strong&gt;we sometimes do not have very clear ideas&lt;/strong&gt; because we have not stopped enough to know ourselves and discover what moves us, what we like, what our priorities are... this can happen to our mentees and &lt;strong&gt;this is where our work as mentors comes in&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To help your mentee to define their goals, the best thing you can do is to &lt;strong&gt;ask questions&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;These questions will &lt;strong&gt;make them reflect&lt;/strong&gt; and, with the conclusions obtained, they will be able to choose and formulate goals for which &lt;strong&gt;it will be easier to find motivation&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;This doesn't mean that you can't give your opinion or suggestions at some point in the conversation, specially if it is your mentee who asks you about them. But, in my experience, &lt;strong&gt;your questions and your &lt;a href="https://dev.to/one-beyond/mentor-tools-ii-active-listening-2o9b"&gt;&lt;strong&gt;active listening&lt;/strong&gt;&lt;/a&gt; will be more valuable&lt;/strong&gt;, at least in this initial phase of goal setting.&lt;/p&gt;

&lt;p&gt;Furthermore, &lt;strong&gt;think about the goals that your previous mentees have accomplished and which ones have not&lt;/strong&gt;. Have they been the ones they proposed themselves? Or the ones you proposed to them? Perhaps the ones with a mixture of their ideas and your contributions? I invite you to this reflection.&lt;/p&gt;

&lt;p&gt;In any case, if you have always been more about proposing ideas than asking and listening, &lt;strong&gt;I challenge you to change the dynamic. Ask and listen more than you talk.&lt;/strong&gt; At first it will be strange, you will feel that you are too quiet or that you contribute too little. But give yourself time, observe the results, and draw your own conclusions. &lt;/p&gt;

&lt;p&gt;At this point you may be thinking, but &lt;strong&gt;what exactly do I ask my mentee&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;Well, in this section I am going to give you a &lt;strong&gt;list of questions&lt;/strong&gt; you can ask. But first, I will give you some advice.&lt;/p&gt;

&lt;p&gt;The first one is that &lt;strong&gt;you don't have to ask all the questions and not in a specific order&lt;/strong&gt;. You will be the one who, as the conversation flows, will select them with your magical intuition as a mentor and the practice you acquire.&lt;/p&gt;

&lt;p&gt;The second is that before the meeting with your mentee, you &lt;strong&gt;practice reading the questions and answering them yourself to refine any of your goals&lt;/strong&gt;. You will then be able to adapt the questions to the way you speak so that you feel more comfortable. Or you may want to change the order, add or delete some questions... &lt;strong&gt;I encourage you to make this questionnaire your own.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That said, let's get to the &lt;strong&gt;questions list&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Initial questions&lt;/strong&gt;: Are you clear about what goals you want to set?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Yes&lt;/strong&gt;: listen to their ideas and go directly to &lt;strong&gt;Block 1&lt;/strong&gt;. Go through all the following blocks of questions for each one. The idea is to &lt;strong&gt;refine them one by one&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;No&lt;/strong&gt;: ask some of the following &lt;strong&gt;brainstorming questions&lt;/strong&gt; before moving on to the next block:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How do you &lt;strong&gt;see yourself professionally in (1/2/5) years&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;What will you have &lt;strong&gt;learned&lt;/strong&gt; that you don't know now?&lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;hard/soft skills&lt;/strong&gt; will you have that you don't have now?&lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;challenges&lt;/strong&gt; will you have faced?&lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;responsibilities&lt;/strong&gt; will you have?&lt;/li&gt;
&lt;li&gt;What do you need to do to get there?&lt;/li&gt;
&lt;li&gt;Where would you like to start?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From these questions will come ideas for possible goals. Go now to &lt;strong&gt;Block 1&lt;/strong&gt; and talk about each goal independently to get them refined.&lt;/p&gt;


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

&lt;p&gt;&lt;strong&gt;Block 1&lt;/strong&gt;: Alignment with their &lt;strong&gt;motivations&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What do you want to achieve this goal for?&lt;/li&gt;
&lt;li&gt;What will be the &lt;strong&gt;reward&lt;/strong&gt; for you?&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;strong&gt;Block 2&lt;/strong&gt;: alignment with the &lt;strong&gt;needs of the company&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Will you be able to &lt;strong&gt;bring value to the company&lt;/strong&gt; by doing this objective? &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Yes: &lt;strong&gt;Great&lt;/strong&gt;!&lt;/li&gt;
&lt;li&gt;No: 

&lt;ul&gt;
&lt;li&gt;Is there any &lt;strong&gt;way to reformulate&lt;/strong&gt; it so that it brings (more) value?&lt;/li&gt;
&lt;li&gt;Do you want to &lt;strong&gt;keep this goal&lt;/strong&gt; even though it does not seem to bring (enough) value to the company?&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;In case your mentee &lt;strong&gt;wants to keep a goal&lt;/strong&gt; even though it does not bring (enough) value to the company (maybe it does bring value to themself and that is enough for them), I recommend you to warn them that, &lt;strong&gt;the more aligned their goals are with the company's needs, the more likely they will be compensated&lt;/strong&gt;. You can read more about &lt;a href="https://dev.to/one-beyond/mentor-tools-iii-promotable-goals-1e44"&gt;&lt;strong&gt;promotable goals&lt;/strong&gt;&lt;/a&gt; here.&lt;/p&gt;

&lt;p&gt;In case they &lt;strong&gt;don’t want to keep that goal&lt;/strong&gt; you will &lt;strong&gt;discard it&lt;/strong&gt; and &lt;strong&gt;take another idea&lt;/strong&gt; from their list of possible goals. Ideally, &lt;strong&gt;start the questions again&lt;/strong&gt; from the beginning of Block 1 to refine the new goal. This can happen throughout the entire questionnaire and, in fact, it is not a bad thing to discard goals, as it will mean that &lt;strong&gt;you are refining them well&lt;/strong&gt;.&lt;/p&gt;


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

&lt;p&gt;&lt;strong&gt;Block 3&lt;/strong&gt;: &lt;strong&gt;define SMART objective&lt;/strong&gt;. A SMART goal has the following characteristics: it is SPECIFIC, MEASURABLE, AMBITIOUS*, REALISTIC and TIME-BOUND. &lt;/p&gt;

&lt;p&gt;Thanks to these characteristics &lt;strong&gt;the goal has more chances to be fulfilled&lt;/strong&gt;. Therefore, we are going to ask some questions to "transform" it because, surely, the goal as you have set it up to now does not have these characteristics.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Specific&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;What &lt;strong&gt;exactly&lt;/strong&gt; do you want to achieve (e.g. if your proposal is "improve my soft skills", it is about you reflecting on what exactly you want to improve until the objective is specific enough, e.g. "Learn to set boundaries and manage customer expectations assertively").&lt;/li&gt;
&lt;li&gt;What is it for you to... (e.g. if they tell you they want to "write better code" you can ask "What is it for you to write better code?" so that they become more aware of what they want to work on specifically).&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Measurable&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;How will you know that you are &lt;strong&gt;making progress&lt;/strong&gt; on your goal?&lt;/li&gt;
&lt;li&gt;How will you know that you &lt;strong&gt;have achieved it&lt;/strong&gt;?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ambitious&lt;/strong&gt;*:

&lt;ul&gt;
&lt;li&gt;Is it a &lt;strong&gt;challenge&lt;/strong&gt; for you? &lt;/li&gt;
&lt;li&gt;(If not) How could it become a challenge?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Realistic&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;To what extent &lt;strong&gt;is it up to you&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;options for success&lt;/strong&gt; do you see from 0 to 10? &lt;/li&gt;
&lt;li&gt;If the chances of success you see are low:

&lt;ul&gt;
&lt;li&gt;How could you redefine it to &lt;strong&gt;increase the chances of success&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Do you want to keep refining this goal despite the low chances of success?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;resources&lt;/strong&gt; do you need to achieve it (e.g. time, help from others, training, budget...)?&lt;/li&gt;
&lt;li&gt;How can you get the resources you lack?&lt;/li&gt;
&lt;li&gt;What could &lt;strong&gt;prevent you from achieving&lt;/strong&gt; it?&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Time-bound&lt;/strong&gt;:

&lt;ul&gt;
&lt;li&gt;When do you want to &lt;strong&gt;start&lt;/strong&gt; working on it?&lt;/li&gt;
&lt;li&gt;When do you want to have it &lt;strong&gt;completed&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;What &lt;strong&gt;intermediate stages&lt;/strong&gt; might there be?&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;strong&gt;Block 4&lt;/strong&gt;: check &lt;strong&gt;commitment&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What &lt;strong&gt;level of commitment&lt;/strong&gt; do you have to this goal from 0 to 10?&lt;/li&gt;
&lt;li&gt;If your answer is less than 9: 

&lt;ul&gt;
&lt;li&gt;Is there any way to &lt;strong&gt;adapt the goal&lt;/strong&gt; so that your commitment reaches 9? &lt;/li&gt;
&lt;li&gt;Do you want to choose this goal in spite of it?&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;And that’s all from the questioning phase.&lt;/p&gt;

&lt;p&gt;At this point &lt;strong&gt;your mentee will have a good idea about the goals they want to choose&lt;/strong&gt;. You will also have &lt;strong&gt;tested and refined them&lt;/strong&gt; with questions to increase the chances of success.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You already have 90% of the work done!&lt;/strong&gt; You can move on to the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Write down the goals
&lt;/h2&gt;

&lt;p&gt;Now all that's left to do is to &lt;strong&gt;write down these goals&lt;/strong&gt;. It is likely in your company you have a tool or space where these goals can be collected. &lt;/p&gt;

&lt;p&gt;I recommend that you &lt;strong&gt;encourage your mentee to access this space and write them down themself&lt;/strong&gt;. This way you will &lt;strong&gt;foster their autonomy&lt;/strong&gt; and, besides, who better than them to explain what they want to do and how they are going to do it? &lt;/p&gt;

&lt;p&gt;To ensure that the objectives are well written, I suggest you fill in this &lt;strong&gt;template&lt;/strong&gt; for each of them:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Title of the objective&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I want to... (general objective)&lt;/li&gt;
&lt;li&gt;That will have an impact on... (describe personal &amp;amp; company impact)&lt;/li&gt;
&lt;li&gt;For that I am going to... (milestones)&lt;/li&gt;
&lt;li&gt;I am going to need...&lt;/li&gt;
&lt;li&gt;I want to finish it by (deadline)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that’s it! &lt;/p&gt;

&lt;p&gt;I hope you find these tips useful and &lt;strong&gt;see you in the next article&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Note: In some sources, the A from SMART goals can also mean “&lt;strong&gt;attainable&lt;/strong&gt;” or “&lt;strong&gt;achievable&lt;/strong&gt;”.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mentor tools VI: First 1:1</title>
      <dc:creator>Irene Mateo Herrero</dc:creator>
      <pubDate>Tue, 05 Mar 2024 18:10:52 +0000</pubDate>
      <link>https://forem.com/one-beyond/mentor-tools-vi-first-11-5hhh</link>
      <guid>https://forem.com/one-beyond/mentor-tools-vi-first-11-5hhh</guid>
      <description>&lt;p&gt;Is this your &lt;strong&gt;first time mentoring&lt;/strong&gt; and you have your &lt;strong&gt;first one on one coming up&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;Or maybe you've been a mentor before but are just &lt;strong&gt;starting to mentor a new partner&lt;/strong&gt;? &lt;/p&gt;

&lt;p&gt;In any of these cases, you may feel a bit of &lt;strong&gt;concern or uncertainty&lt;/strong&gt;. This is normal, because the first contact with a new mentee is an &lt;strong&gt;important moment&lt;/strong&gt; in the mentoring process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We begin to build the relationship of &lt;strong&gt;trust&lt;/strong&gt; and the &lt;strong&gt;&lt;a href="https://dev.to/one-beyond/mentor-tools-i-safe-space-54n6"&gt;safe space&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We start to know their &lt;strong&gt;motivations and expectations&lt;/strong&gt; regarding their professional growth.&lt;/li&gt;
&lt;li&gt;We begin to define what they will &lt;strong&gt;need from us and/or the company&lt;/strong&gt; to achieve their goals.&lt;/li&gt;
&lt;li&gt;We establish the &lt;strong&gt;basis of the mentoring relationship&lt;/strong&gt; (responsibilities, frequency and duration of the sessions...).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Therefore, I want to give you some &lt;strong&gt;tips&lt;/strong&gt; to face this first 1:1.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before the 1:1
&lt;/h2&gt;

&lt;p&gt;I recommend that before the first 1:1 you &lt;strong&gt;gather information&lt;/strong&gt; from your new mentee:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;their &lt;strong&gt;role&lt;/strong&gt; and &lt;strong&gt;seniority&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;professional background&lt;/strong&gt; (in your company but also previous)&lt;/li&gt;
&lt;li&gt;outstanding &lt;strong&gt;skills&lt;/strong&gt; and &lt;strong&gt;achievements&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;areas for improvement&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;relationship with colleagues and clients&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;project/area&lt;/strong&gt; in which they work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this you can extract from several &lt;strong&gt;sources&lt;/strong&gt;, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;their &lt;strong&gt;manager&lt;/strong&gt;, a &lt;strong&gt;co-worker&lt;/strong&gt;, their &lt;strong&gt;previous mentor&lt;/strong&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;documentation&lt;/strong&gt; about their performance (their latest &lt;strong&gt;Performance Review, Peer Feedback, Manager Assessment&lt;/strong&gt; or any other document with updated information).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This information will be useful for you to  gain &lt;strong&gt;context&lt;/strong&gt; about your mentee. However, along with the objective data you get, such as their role or seniority, you will probably receive more &lt;strong&gt;subjective information&lt;/strong&gt;, such as evaluations about their way of being or their relationships with other colleagues.&lt;/p&gt;

&lt;p&gt;I advise you to &lt;strong&gt;be cautious&lt;/strong&gt; with this information, especially if it is not positive information. It is important to keep in mind that &lt;strong&gt;each of us brings our own subjectivity to our view of others&lt;/strong&gt; and, therefore, you may receive data affected by the &lt;strong&gt;biases&lt;/strong&gt; of the people who gave it to you. So, I recommend that you gather information, but &lt;strong&gt;keep an open mind&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  During the 1:1
&lt;/h2&gt;

&lt;p&gt;The day of your first 1:1 has finally arrived! &lt;/p&gt;

&lt;p&gt;I recommend that you &lt;strong&gt;mute all notifications&lt;/strong&gt; and prepare yourself to give your &lt;strong&gt;&lt;a href="https://dev.to/one-beyond/mentor-tools-ii-active-listening-2o9b"&gt;full attention&lt;/a&gt;&lt;/strong&gt; to what your new mentee is going to tell you.&lt;/p&gt;

&lt;p&gt;Here are some &lt;strong&gt;tips&lt;/strong&gt; on how to approach this first meeting: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Welcome&lt;/strong&gt; them to this space.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Explain the &lt;strong&gt;objectives of the meeting&lt;/strong&gt;. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get to &lt;strong&gt;know each other&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Establish the &lt;strong&gt;basis of the mentoring relationship&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Introduce yourself&lt;/strong&gt;. You will probably tell them about your professional background, but I also recommend that you share some personal and/or less formal information. This will help to generate a &lt;strong&gt;&lt;a href="https://dev.to/one-beyond/mentor-tools-i-safe-space-54n6"&gt;safe space&lt;/a&gt;&lt;/strong&gt; or climate of trust in which your mentee will gradually feel more open to share. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Ask for them&lt;/strong&gt;. Although it is important to make yourself known, &lt;strong&gt;the protagonist of the mentoring sessions is your mentee&lt;/strong&gt;. Therefore, asking and &lt;strong&gt;&lt;a href="https://dev.to/one-beyond/mentor-tools-ii-active-listening-2o9b"&gt;listening&lt;/a&gt;&lt;/strong&gt; is fundamental from day 1. Some &lt;strong&gt;professional questions&lt;/strong&gt; especially relevant to our work as a mentor will be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What &lt;strong&gt;motivates&lt;/strong&gt; you most about the work you do?&lt;/li&gt;
&lt;li&gt;What are the &lt;strong&gt;skills&lt;/strong&gt; you would highlight about yourself?&lt;/li&gt;
&lt;li&gt;What are your &lt;strong&gt;areas of improvement&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;What are your &lt;strong&gt;expectations&lt;/strong&gt; for your &lt;strong&gt;professional growth&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Where would you like to move forward?&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;strong&gt;Establish the basis of the mentoring relationship&lt;/strong&gt;. Now that you know each other a little better, it's time to talk about the mentoring sessions. At this point, I advise you to &lt;strong&gt;ask them if they have any mentoring experience&lt;/strong&gt;, either being a mentor or being mentored and how it went. You can then explain &lt;strong&gt;how you understand the mentoring process and how you usually approach it&lt;/strong&gt;. I usually explain the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Role of mentoring&lt;/strong&gt;: to accompany the mentee to grow professionally. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structure of the sessions&lt;/strong&gt;: I normally cover two main topics:

&lt;ul&gt;
&lt;li&gt;Follow up of &lt;strong&gt;daily work&lt;/strong&gt; (project, client, company...).&lt;/li&gt;
&lt;li&gt;Follow up of &lt;strong&gt;goals&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;strong&gt;Frequency and duration&lt;/strong&gt;: in my case, I establish &lt;strong&gt;1 session per month as a minimum&lt;/strong&gt; in order to be able to follow up on a regular basis. However, I always leave the option to my mentee to choose if they want to have 1:1s more frequently (one session every two weeks, every three weeks...).&lt;/p&gt;

&lt;p&gt;Regarding the duration, you can also agree with your mentee. I usually reserve &lt;strong&gt;between 30 and 45 minutes&lt;/strong&gt; depending on the frequency. Less frequent 1:1s tend to be longer. &lt;/p&gt;


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

&lt;p&gt;&lt;strong&gt;Other matters&lt;/strong&gt;: I always remind my mentee to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Feel free to &lt;strong&gt;ask or express whatever you want&lt;/strong&gt;, this is a safe space.&lt;/li&gt;
&lt;li&gt;Ping me if you need to &lt;strong&gt;talk before the next 1:1&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;You can give me &lt;strong&gt;feedback&lt;/strong&gt; on the sessions at any time. The purpose is that these sessions are useful to you and help you in your growth.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Finally, after explaining all this information to my mentee, I ask them:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do you find what I propose &lt;strong&gt;useful&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Do you think you might &lt;strong&gt;need something I haven't told you&lt;/strong&gt;?&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Listen carefully to their views, discuss it if needed and &lt;strong&gt;you will have completed your first 1:1&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;You can close the meeting by setting the &lt;strong&gt;date of your next meeting&lt;/strong&gt; and &lt;strong&gt;thanking&lt;/strong&gt; them for their time.&lt;/p&gt;

&lt;p&gt;You can also &lt;strong&gt;advance the topic of the next session&lt;/strong&gt; if it will be, for example, the meeting to &lt;strong&gt;&lt;a href="https://dev.to/one-beyond/mentor-tools-iii-promotable-goals-1e44"&gt;define their goals&lt;/a&gt;&lt;/strong&gt;. This way, they can ask you now if they have any questions.&lt;/p&gt;

&lt;p&gt;That’s all, &lt;strong&gt;see you in the next one&lt;/strong&gt;!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Azure Service Bus 101: Introduction to Queues and Messaging</title>
      <dc:creator>Ignacio Ripoli</dc:creator>
      <pubDate>Thu, 18 Jan 2024 23:15:55 +0000</pubDate>
      <link>https://forem.com/one-beyond/azure-service-bus-101-introduction-to-queues-and-messaging-4coj</link>
      <guid>https://forem.com/one-beyond/azure-service-bus-101-introduction-to-queues-and-messaging-4coj</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Few4aky5q8dcjeznr3r1i.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Few4aky5q8dcjeznr3r1i.jpeg" alt="Azure service bus logo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Azure Service Bus acts as a dependable communication system within the world of cloud computing, enabling secure and reliable interactions between various applications and services. &lt;/p&gt;

&lt;p&gt;Compared to other messaging systems, Azure Service Bus offers advanced functionalities. It provides a great framework for different components of an application to communicate effectively and securely. &lt;/p&gt;

&lt;p&gt;Using Azure Service Bus involves setting up communication between applications and services. You can create these pathways, send messages between them, and configure how messages are handled. &lt;/p&gt;

&lt;p&gt;Throughout this discussion, we'll dive into the features and capabilities of the Service Bus and explore how it can be effectively utilized in diverse applications and scenarios. &lt;/p&gt;

&lt;p&gt;You will need an Azure account. I invite you to create your first Azure account by clicking on this &lt;a href="https://datamyte.com/blog/synchronous-vs-asynchronous/" rel="noopener noreferrer"&gt;link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Throughout your reading, you will see how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send messages in a queue,&lt;/li&gt;
&lt;li&gt;Consume messages in a queue,&lt;/li&gt;
&lt;li&gt;Send messages using topics,&lt;/li&gt;
&lt;li&gt;Subscribe to a topic and receive messages,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regarding the code, most of the calls will be non-blocking and therefore asynchronous; a good understanding of async is essential, you can find more info about it &lt;a href="https://datamyte.com/blog/synchronous-vs-asynchronous/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  Azure Service Bus — Overview
&lt;/h2&gt;

&lt;p&gt;Azure Service Bus facilitates the separation of data with a focus on both reliability and security.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Azure Service Bus provides us with the ability to leverage various scenarios:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sending messages in a Queue,&lt;/li&gt;
&lt;li&gt;Decoupling applications for improved reliability and greater scalability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We know that Azure Storage Queue allows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storing over 80GB of messages in a queue,&lt;/li&gt;
&lt;li&gt;Tracking message processing progress,&lt;/li&gt;
&lt;li&gt;Accessing activity logs,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although Azure Service Bus doesn't have these three advantages, it offers compelling functionalities that aren't available at the Azure Service Queue level:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Receiving messages without needing to query the queue,&lt;/li&gt;
&lt;li&gt;A 1-to-N relationship between publishers and subscribers through Topics,&lt;/li&gt;
&lt;li&gt;Implementing workflow coordination and multiplexed transfers that require strict message ordering or message deferral,&lt;/li&gt;
&lt;li&gt;Service Bus ensures FIFO (First In First Out),&lt;/li&gt;
&lt;li&gt;Support for the AMQP protocol and other features,&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;The First In, First Out (FIFO) principle is a method used in queue management, where the first item to enter the queue is the first to be processed or serviced, following a sequential order. This principle ensures that items or elements are processed or dealt with in the same order they were received, without any prioritization or reordering based on urgency or importance. It's a fundamental concept in managing queues and is commonly used in various computing and business scenarios where order preservation is critical.&lt;/em&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you find yourself in any of the mentioned scenarios, Azure Service Bus is your ally.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Azure Service Bus is a fully managed enterprise message broker with message queues and publish-subscribe topics (in a namespace). Service Bus is used to decouple applications and services from each other.&lt;/em&gt; &amp;lt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Azure Service Bus — Queues
&lt;/h2&gt;

&lt;p&gt;The queues will allow us to store the sent messages until the consumer requests them for processing. Below is what a Queue looks like.&lt;/p&gt;

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

&lt;p&gt;In summary, a queue is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A temporary storage warehouse for messages,&lt;/li&gt;
&lt;li&gt;Messages are delivered upon the consumer's request,&lt;/li&gt;
&lt;li&gt;The receiver consumes messages starting with the one that arrived first, following the First In First Out principle.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example of Use&lt;/strong&gt;&lt;br&gt;
We have two services:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first service creates users.&lt;/li&gt;
&lt;li&gt;The second service handles notifications, sending emails and/or push notifications to our users after their creation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our example, it is possible to subscribe our notification service to the 'notification' queue, which receives messages such as 'UserCreated' with the property 'UserId = xxx'. This identifier will be used by the notification service to send a welcome email.&lt;/p&gt;
&lt;h2&gt;
  
  
  Azure Service Bus — Topics
&lt;/h2&gt;

&lt;p&gt;Topics provide the ability to have a provider with multiple observers or consumers, each consumer having its own queue that feeds it.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Example of Use&lt;/strong&gt;&lt;br&gt;
Let's consider the following scenario:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A user creation service&lt;/li&gt;
&lt;li&gt;Several microservices (notification microservice, articles microservice, product microservice, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In our case, upon creating a new user, the service will notify through a topic to different subscribers/microservices about the creation of a new user. This allows other services to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Send the user a confirmation of the account creation,&lt;/li&gt;
&lt;li&gt;Add the user's identifier in the schema of the Article microservice's database to send them new articles,&lt;/li&gt;
&lt;li&gt;Add the user's identifier in the schema of the Product microservice's database to notify them about promotions, new products, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  In practice?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Sign in to Azure Portal:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href="https://portal.azure.com/" rel="noopener noreferrer"&gt;portal.azure.com&lt;/a&gt; and log in to your Azure account.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create a new Service Bus namespace:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on "+ Create a resource."&lt;/li&gt;
&lt;li&gt;Search for "Service Bus" and select it.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ol&gt;
&lt;li&gt;Fill in details for the new namespace (subscription, resource group, name, region, and SKU).&lt;/li&gt;
&lt;li&gt;Click "Review + Create," then "Create" to start deployment.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Review and deploy:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Review configuration details and initiate the deployment process.&lt;/li&gt;
&lt;li&gt;Wait for the deployment to complete.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Access your Service Bus:&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Once deployed, find your Service Bus namespace under "All resources."&lt;/li&gt;
&lt;li&gt;Explore and manage your Service Bus, create queues, topics, or subscriptions as needed.
&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fru7uqpd811kfmdkhrt8t.png" alt="service-bus panel"&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Within your Service Bus namespace, you can create queues, topics, subscriptions, and manage various settings based on your application needs.&lt;br&gt;
Click on "Queues" or "Topics" to create a new queue or topic and set up subscriptions or rules according to your messaging requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating Queues&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ServiceBusClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@azure/service-bus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;createQueue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connectionString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;YOUR_CONNECTION_STRING&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your Service Bus connection string&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queueName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;YOUR_QUEUE_NAME&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your desired queue name&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serviceBusClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ServiceBusClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queueOptions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// Define queue options if needed&lt;/span&gt;
      &lt;span class="c1"&gt;// For example:&lt;/span&gt;
      &lt;span class="c1"&gt;// defaultMessageTimeToLive: 60 // Message time-to-live in seconds&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queueDetails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;serviceBusClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createQueue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queueName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;queueOptions&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Queue "&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;queueDetails&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;queueName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;" created successfully.`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error creating queue:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;serviceBusClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Call the function to create the queue&lt;/span&gt;
&lt;span class="nf"&gt;createQueue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sending a message&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ServiceBusClient&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@azure/service-bus&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;sendMessageToQueue&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;connectionString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;YOUR_CONNECTION_STRING&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your Service Bus connection string&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;queueName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;YOUR_QUEUE_NAME&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your queue name&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;serviceBusClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ServiceBusClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;connectionString&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;serviceBusClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSender&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;queueName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Hello, Azure Service Bus!&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Replace with your message payload&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sendMessages&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Message sent successfully to the queue.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Error sending message:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;serviceBusClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Call the function to send the message&lt;/span&gt;
&lt;span class="nf"&gt;sendMessageToQueue&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This JavaScript code uses the ServiceBusClient class from the @azure/service-bus package to create a sender for the specified queue and sends a message with a simple payload, and the ServiceBusClient package to create a sender for the specified queue. &lt;br&gt;
Adjust the message body or other properties as needed based on your requirements. &lt;/p&gt;

&lt;p&gt;Make sure to handle errors appropriately and ensure that your Azure account has the necessary permissions to send messages to the specified queue in the Service Bus namespace. &lt;/p&gt;

&lt;p&gt;This process sets up a basic Azure Service Bus namespace. From there, you can integrate it into your applications, set up messaging patterns, and utilize the Service Bus functionalities to facilitate communication between different components of your applications or services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Throughout this article, we've covered the creation and receipt of messages within and from a queue. &lt;/p&gt;

&lt;p&gt;This service broadens the spectrum of possibilities significantly. One can envision utilizing queues within Azure Functions to trigger processes upon message receipt. &lt;/p&gt;

&lt;p&gt;I hope this article has allowed you to familiarize yourself with Azure Service Bus, and please leave a comment if you have any questions. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Mentor tools V: Performance Review</title>
      <dc:creator>Irene Mateo Herrero</dc:creator>
      <pubDate>Wed, 17 Jan 2024 16:27:09 +0000</pubDate>
      <link>https://forem.com/one-beyond/mentor-tools-v-performance-review-5d97</link>
      <guid>https://forem.com/one-beyond/mentor-tools-v-performance-review-5d97</guid>
      <description>&lt;p&gt;&lt;strong&gt;Are you in charge of a colleague's Performance Review?&lt;/strong&gt; Is it your first time doing it?&lt;/p&gt;

&lt;p&gt;If so, I can give you a hand with that. From my experience, I know that &lt;strong&gt;sometimes the Performance Review process is not easy&lt;/strong&gt;, especially the first times you do it. You may feel &lt;strong&gt;lost&lt;/strong&gt;, you may not know &lt;strong&gt;where to start&lt;/strong&gt;, or you may even feel a little &lt;strong&gt;nervous&lt;/strong&gt; about the process. Since I've been through that, &lt;strong&gt;I want to give you some tips that have helped me&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;But first it would be good to understand what the purpose of the Performance Review process is, right? Let's get to it!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. What is the Performance Review process?&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Performance Review process is nothing more than &lt;strong&gt;the evaluation of a person's performance at work&lt;/strong&gt;. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are reading this now, &lt;strong&gt;you are probably in the final phase of this process&lt;/strong&gt;, that is, preparing the document and the final meeting in which you are going to communicate to your mentee your evaluation of the whole year. &lt;/p&gt;

&lt;p&gt;But really the Performance Review is an &lt;strong&gt;ongoing, year-long process with some milestones&lt;/strong&gt; that are probably familiar to you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dev.to/one-beyond/mentor-tools-iii-promotable-goals-1e44"&gt;Goal Setting meeting&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://dev.to/one-beyond/mentor-tools-iv-goals-follow-up-lh0"&gt;Goals follow-up meetings&lt;/a&gt;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gap analysis meeting&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you will see, &lt;strong&gt;you probably have actually been doing performance review throughout the year&lt;/strong&gt; if you have been working with your mentee for some time and you’ve had several one on ones where you’ve been:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Giving continuous feedback&lt;/strong&gt; to your mentee on their progress.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Managing their expectations&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Periodically aligning their progress with the company's objectives.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If so, &lt;strong&gt;this last part of the process&lt;/strong&gt; (i.e. filling out the annual Performance Review document and the communication meeting), &lt;strong&gt;will be a mere formality&lt;/strong&gt;. So don't panic, you're doing fine! &lt;/p&gt;

&lt;p&gt;If you haven't done all this exactly, I encourage you to &lt;strong&gt;reflect on your areas of improvement as a mentor&lt;/strong&gt; in this process - we all have something to improve!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. My Tips&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here you’ve got some tips to face this last part of the Performance Review process.&lt;/p&gt;

&lt;p&gt;I’ll divide the tips in &lt;strong&gt;two steps&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Filling-in the Performance Review document&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Communication of the Performance Review&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Fill in the Performance Review document&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To fill out the Performance Review document I recommend that you &lt;strong&gt;follow these steps&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Collect information &amp;amp; documentation&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get feedback from all the people who can provide feedback on your mentee (&lt;strong&gt;peer feedback, client feedback, self assessment&lt;/strong&gt;, etc.).&lt;/li&gt;
&lt;li&gt;Take the &lt;strong&gt;documents describing the skills&lt;/strong&gt; you have to assess for my mentee according to their role and seniority (called &lt;strong&gt;Skills dictionaries&lt;/strong&gt; at our company). &lt;/li&gt;
&lt;li&gt;Review their &lt;strong&gt;Performance Review document from last year&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Take a look at the &lt;strong&gt;Job description&lt;/strong&gt;, i.e. the document where it is specified which skills are attributed to their role and seniority.&lt;/li&gt;
&lt;li&gt;If you still don't have a 360º view of their performance, you can set up a &lt;strong&gt;meeting with whomever you need to get a better perspective&lt;/strong&gt; of their performance, for more objectivity.&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;&lt;strong&gt;Fill-in the Performance Review document&lt;/strong&gt;, keeping in mind that the idea is to: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;highlight achievements&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;point out areas for improvement&lt;/strong&gt;, justifying them with &lt;strong&gt;evidence&lt;/strong&gt; and focusing on proposing &lt;strong&gt;solutions&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;Throughout this process, &lt;strong&gt;try to be as objective as possible&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;And if you need help with anything, &lt;strong&gt;don't hesitate to ping to a fellow mentor with more experience&lt;/strong&gt;, who will surely give you a hand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Communication of the Performance Review&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is a particularly important moment. &lt;/p&gt;

&lt;p&gt;Yes, it may only be a formality if there has been continuous feedback throughout the year, but &lt;strong&gt;it reminds me a bit of getting my end-of-year grades in high school&lt;/strong&gt;. So, in some ways, it can be a difficult conversation to deal with.&lt;/p&gt;

&lt;p&gt;However, I prefer to see it as &lt;strong&gt;a conversation where you can&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Strengthen the trusting relationship&lt;/strong&gt; you already have with your mentee.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Celebrate achievements&lt;/strong&gt; and identify what has made your mentee achieve those achievements in order to repeat it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Detect areas of improvement&lt;/strong&gt; and decide what can be done about it.&lt;/li&gt;
&lt;li&gt;Continue to know better what are the &lt;strong&gt;expectations, motivations... of our mentee&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Align the mentee's ambitions with the company's objectives.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Having said that, the difference I see with my teacher giving grades at school is that this is a &lt;strong&gt;two-way conversation&lt;/strong&gt;. The mentor provides an input, which is the Performance Review document and its evaluations, and from there, &lt;strong&gt;a dialogue is created with the mentee in which they can also contribute their point of view&lt;/strong&gt;. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The value of the Performance Review&lt;/strong&gt; lies not so much in the mentor's notes and comments, but above all in &lt;strong&gt;the dialogue that is generated from them.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To &lt;strong&gt;make this meeting as fruitful as possible&lt;/strong&gt;, here are some tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Write to your mentee to arrange a date and time that suits you both&lt;/strong&gt; and you have enough time to talk. This communication only happens once a year, so make it a &lt;strong&gt;priority&lt;/strong&gt;!&lt;/li&gt;
&lt;li&gt;Consider &lt;strong&gt;sending the Performance Review document in advance&lt;/strong&gt; to your mentee so that they can look at it calmly and come to the meeting with questions, doubts... &lt;/li&gt;
&lt;li&gt;Along with the Performance Review document, this year I have sent a &lt;strong&gt;message&lt;/strong&gt; like this to &lt;strong&gt;convey my mindset regarding this meeting&lt;/strong&gt;, and thus also &lt;strong&gt;generate &lt;a href="https://dev.to/one-beyond/mentor-tools-i-safe-space-54n6"&gt;safe space&lt;/a&gt;&lt;/strong&gt;, as I think that sometimes this moment can be a bit imposing and &lt;strong&gt;I want my mentee to feel comfortable to give their point of view&lt;/strong&gt;:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;Hello [mentee’s name] ! Here is your PR. I hope, above all, that it will be useful to you. Read it calmly and if you have doubts, at the meeting ask me anything you need, feel free.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;I have tried to write a feedback with what I have seen from you this year and with all the information I have received from colleagues, clients and your own self assessment. If you see something that doesn't fit you, feel free to discuss it. For me, the enriching part of the Performance Review meeting is not that I give you the numbers and comments and you read them, but that a fruitful conversation about your professional progress arises from what I have written with more or less success.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Take from the feedback what you can use to improve. In the end, feedback is opinions and there can always be a margin of subjectivity. See you at the meeting!&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Block notifications during meeting time&lt;/strong&gt;. This is the time to activate your &lt;a href="https://dev.to/one-beyond/mentor-tools-ii-active-listening-2o9b"&gt;&lt;strong&gt;active listening&lt;/strong&gt;&lt;/a&gt; at 1000% (and yes, that extra zero is not a typo).&lt;/li&gt;
&lt;li&gt;When the meeting starts, &lt;strong&gt;remind them that this is a &lt;a href="https://dev.to/one-beyond/mentor-tools-i-safe-space-54n6"&gt;safe space&lt;/a&gt;&lt;/strong&gt; for them to discuss what they need to. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you have sent them the Performance Review document in advance, ask them what they thought&lt;/strong&gt;, if they have questions or if they have seen something they want to comment on or disagree with. That's where the discussion can begin. Then, &lt;strong&gt;you can ask them if they want to read the document with you again or if it is not necessary&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;If you haven't sent the Performance Review before the meeting, &lt;strong&gt;ask if they prefer to read it aloud or quietly, or if they prefer you to read it&lt;/strong&gt;. Also make sure that, if you read it, they feel comfortable interrupting you by saying explicitly, &lt;strong&gt;"Feel free to stop me if you want to comment something”&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;THIS IS A VERY IMPORTANT TIP&lt;/strong&gt;: During the meeting, &lt;strong&gt;talk to your mentee as if they were someone you love and want to help, for example, your best friend or a younger sibling&lt;/strong&gt;. Someone you want to care and also help make progress. This will &lt;strong&gt;prevent you from falling into criticism and settling into caring&lt;/strong&gt;, which is crucial when giving feedback &lt;strong&gt;to avoid the other person becoming defensive&lt;/strong&gt; (which is, after all, a normal human reaction to feedback). And when installed in this mood:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Celebrate their accomplishments&lt;/strong&gt;: "I'm very proud of your progress in..."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Point out their areas of improvement with firmness and empathy&lt;/strong&gt;: "I think you could improve in this area by…,  as I have seen that… what do you think?". Remember to &lt;strong&gt;argue with evidence and put the focus on possible solutions&lt;/strong&gt;. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply this caring mindset to everything you communicate&lt;/strong&gt;. It will help you connect with them and strengthen your mentorship relationship.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Encourage them to express their point of view frequently by asking “what do you think about…?” or “How do you see it?”&lt;/strong&gt;. This will fuel the discussion and, again, make the meeting a &lt;a href="https://dev.to/one-beyond/mentor-tools-i-safe-space-54n6"&gt;&lt;strong&gt;safe space&lt;/strong&gt;&lt;/a&gt; from which great insights can emerge.&lt;/li&gt;
&lt;li&gt;If there is a &lt;strong&gt;point on which your mentee disagrees, discuss it without fear&lt;/strong&gt;. &lt;strong&gt;Keep an open mind&lt;/strong&gt;, there may be something you have missed in their performance.&lt;/li&gt;
&lt;li&gt;If at some point in the discussion the conversation gets complicated, in one of my next articles I will give you tips on how to &lt;strong&gt;manage difficult conversations&lt;/strong&gt;. This is unlikely to happen if you have been giving regular feedback, but it is always a possibility. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Close the conversation by thanking&lt;/strong&gt; your mentee for their work during the year and their openness in contributing ideas to this meeting. &lt;/li&gt;
&lt;li&gt;You can also take the opportunity to &lt;strong&gt;ask for feedback&lt;/strong&gt; on the meeting or even on the whole Performance Review process. &lt;/li&gt;
&lt;li&gt;Finally, you can also &lt;strong&gt;let them know the next steps in the Performance Review process&lt;/strong&gt; of your company.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that's all the advice I can give you! I hope these personal tips will help you face these last steps in the Performance Review process. &lt;strong&gt;Good luck and see you in the next one!&lt;/strong&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Finding a performance issue with React Dev Tools</title>
      <dc:creator>Alejandro Sánchez Zaragoza</dc:creator>
      <pubDate>Tue, 02 Jan 2024 15:08:49 +0000</pubDate>
      <link>https://forem.com/one-beyond/find-a-performance-issue-with-react-dev-tools-5l4</link>
      <guid>https://forem.com/one-beyond/find-a-performance-issue-with-react-dev-tools-5l4</guid>
      <description>&lt;p&gt;The most efficient way to identify performance issues in our web application is... just using the web platform itself. Trying to analyse every facet of the platform in search of inefficient renderings can be a time-consuming task, and addressing these less critical issues can consume even more time. Therefore, it is crucial to prioritize tackling real problems that significantly impact performance to ensure our efforts are efficiently utilized. &lt;/p&gt;

&lt;p&gt;These critical performance problems will appear in a natural way during the application's production usage. It's in this context that you may observe certain actions taking more time than expected. These issues may also arise during the development process, and it is in this case when React Dev Tools, integrated into your browser, become invaluable. It can assist you in pinpointing the origin cause of the problem, facilitating an effective resolution process. &lt;/p&gt;

&lt;p&gt;We are going to use the React Developers Tools, and you can download the Chrome extension at &lt;a href="https://chromewebstore.google.com/detail/react-developer-tools/fmkadmapgofadopljbjfkapdkoienihi"&gt;this link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To be able to use the &lt;strong&gt;Profiler&lt;/strong&gt; tool the application needs to be running in production mode, so first we have to run a build command with the --profile flag &lt;br&gt;
&lt;code&gt;npm run build -- --profile&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;After that we can serve the build with &lt;br&gt;
&lt;code&gt;serve -s build&lt;/code&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Using profiler to find a performance issue
&lt;/h2&gt;

&lt;p&gt;Having our application served on production mode we can make use of the Chrome dev tools properly. We can open the Chrome console with cmd+opt+j and go to the "profile" tab&lt;/p&gt;

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

&lt;p&gt;In normal use, when you are ready to start recording the performance behaviour on your platform, you can click on the "Start profiling" button and then start making actions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jmou0rp24g8fw6vmcyl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4jmou0rp24g8fw6vmcyl.png" alt="Start profiling button" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, when clicking on the "Stop profiling" button we´ll see the result of the profiling with the identifier of each element.&lt;/p&gt;

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

&lt;p&gt;And clicking on each, an explanation of what has triggered the re-render of each react element.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95vtplp06dplhn5wc4na.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F95vtplp06dplhn5wc4na.png" alt="Detail in trigger view" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can feel that something is running slow on our platform. If we see the profiler after the recording, we can check that each keypress an input takes 150ms&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kgd21me6zg88t332y6o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7kgd21me6zg88t332y6o.png" alt="React render time" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can check on the performance tab a piece of more detailed information, which lets us know that something is happening on a function call triggered on each keydown.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ri2kpicidhzwmpv27u6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0ri2kpicidhzwmpv27u6.png" alt="Keypress takes too long" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After reviewing the code, we can find that there is an expensive function being called on each render.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wp4p9qyyx6pjjnae4jt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9wp4p9qyyx6pjjnae4jt.png" alt="Code expensive function" width="800" height="160"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We´re passing a direct value as an argument to the &lt;code&gt;useState&lt;/code&gt;, which is used as the initial state during every render. This means that the generateRandomColor function is called on every render, potentially leading to unnecessary computations if the function is not memorized or if it performs expensive operations. &lt;/p&gt;

&lt;p&gt;In this case, using the function as an argument (() =&amp;gt; generateRandomColor()) can be more efficient because it ensures that the initialization is performed only once. &lt;/p&gt;

&lt;p&gt;After changing the line 14 to   &lt;/p&gt;

&lt;p&gt;&lt;code&gt;const [correctAnswer, setCorrectAnswer] = useState(() =&amp;gt; generateRandomColor());&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We are passing a function as an argument to useState, in this case React treats it as a lazy initializer. This means that the function is only executed once, during the initial render, to determine the initial state value. This can be beneficial if the initialization is computationally expensive or involves asynchronous operations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7e6e5ane75upawep10v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw7e6e5ane75upawep10v.png" alt="Checking no cost on profiler tab" width="800" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After applying those changes to the code and running the performance tab, we can see how the expensive function that was running on each keydown is not there anymore.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pushing state changes down to solve performance issues
&lt;/h2&gt;

&lt;p&gt;In another example, after running the profiler we can find that there is a component with the suspicious name of "expensive" being rendered on each keypress&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhnqopjnf5rxaoaiax5j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmhnqopjnf5rxaoaiax5j.png" alt="Expensive component on profiler" width="800" height="271"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After taking a look at the code, we can find that this component is on the app at the same level that some useState hooks, meaning that on each state change, all the react trees of components on this level are going to be re-rendered.&lt;/p&gt;

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

&lt;p&gt;The expensive component is not receiving prop at all, so we can extract all the mutable logic and put it into another component called game.jsx&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wcgq2gq22bl9jtrmd6j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wcgq2gq22bl9jtrmd6j.png" alt="Game component code" width="800" height="1013"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this way, we don´t need to touch the &lt;strong&gt;expensiveComponent.jsx&lt;/strong&gt; component, it may contain heavy logic and it´s not needed to refactor it, maybe it´s not even possible. So, putting the logic in this component, we are pushing down the rerenders on the react tree, separating the problem and the changes of the new &lt;strong&gt;game.jsx&lt;/strong&gt; component will not affect the expensive one.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fess6z8ktfy780tx88xrl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fess6z8ktfy780tx88xrl.png" alt="Two components at same level" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In conclusion, while React Dev Tools offer valuable insights during the development process, particularly in identifying performance bottlenecks, it's important to prioritize issues according to the attention required. By leveraging tools like the Profiler in React Dev Tools, we can detect specific areas of concern and optimize the code according to it. Strategic architectural decisions, such as pushing state changes down the component tree, can easily alleviate unnecessary re-renders and enhance overall application performance.  &lt;/p&gt;

&lt;p&gt;Thanks for reading! I hope you can use these tips to improve the performance of your application through a combination of tooling, thoughtful design, and focused optimizations. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Build Faster: Your Guide to a Quick-Start Project Template</title>
      <dc:creator>Alfonso Domenech</dc:creator>
      <pubDate>Mon, 18 Dec 2023 14:20:47 +0000</pubDate>
      <link>https://forem.com/one-beyond/build-faster-your-guide-to-a-quick-start-project-template-2o0p</link>
      <guid>https://forem.com/one-beyond/build-faster-your-guide-to-a-quick-start-project-template-2o0p</guid>
      <description>&lt;p&gt;Every time I've wanted to embark on a personal project - to learn a new technology or develop an idea - I've found myself redoing configurations for code structure and maintenance, not to mention execution and deployment. It can be frustrating, but I've come to realize that these steps are crucial for success. That's why I'm sharing a minimal template with the most common configurations - the essentials that I believe will help you achieve your goals. We are going to introduce and configure the following technologies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NestJS&lt;/li&gt;
&lt;li&gt;NVM&lt;/li&gt;
&lt;li&gt;Commitlint&lt;/li&gt;
&lt;li&gt;Husky&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;Docker compose&lt;/li&gt;
&lt;li&gt;Github Actions&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you want to take a look at it while you read, you can check out the official &lt;a href="https://github.com/aldorea/nestjs-source-template" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  NestJS &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;NestJS is our backend superhero in the template repo. It's like a magic trick for building solid server-side applications effortlessly in TypeScript or JavaScript. Check out more at &lt;a href="https://docs.nestjs.com/" rel="noopener noreferrer"&gt;NestJS Official Website&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Creating .nvmrc file &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;In this part of the process, the whole team must work with the same version of NodeJS to ensure that all changes made to the application are compatible. This can also be done with Docker, but we will see it later.&lt;/p&gt;

&lt;p&gt;In the .&lt;strong&gt;nvmrc&lt;/strong&gt; file we have to put the version of node we want to use. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

20


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

&lt;/div&gt;

&lt;p&gt;Then we have to install nvm.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configure commitlint &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;If you've worked on projects with a team, you may have noticed that everyone creates different branches and commits changes with random messages. This can make things confusing. That's where commitlint comes in. It helps make sure that commit messages are more consistent and easier to understand. &lt;/p&gt;

&lt;p&gt;💡 Here we have to explain the commit convention and if we want to add our custom commit configuration. Also, the benefits of including commitlint in the projects.&lt;/p&gt;

&lt;p&gt;Now we have to set up commitment in our project following the instructions of the library &lt;a href="https://commitlint.js.org/#/guides-local-setup" rel="noopener noreferrer"&gt;commitlint&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, we must install the library and the convention we want to follow. In our case, we are going to use &lt;a href="https://www.conventionalcommits.org/en/v1.0.0/" rel="noopener noreferrer"&gt;conventional commits&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; @commitlint/cli @commitlint/config-conventional


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

&lt;/div&gt;

&lt;p&gt;Then we have to configure commitlint to use the conventional config. Let´s create our &lt;code&gt;commitlint.config.js&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;extends&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@commitlint/config-conventional&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Set up Husky &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://typicode.github.io/husky/getting-started.html#automatic-recommended" rel="noopener noreferrer"&gt;Husky&lt;/a&gt; is a library which allows developers to execute some commands in the different &lt;a href="https://git-scm.com/docs/githooks" rel="noopener noreferrer"&gt;Git hooks&lt;/a&gt;. Why do we want this? As we said we need to ensure a little bit of homogeneity in our project with husky so we can achieve this. Let´s see how.&lt;br&gt;
So, there's this neat library called husky that developers can use. It helps you run specific commands in various Git hooks(&lt;a href="https://git-scm.com/docs/githooks" rel="noopener noreferrer"&gt;https://git-scm.com/docs/githooks&lt;/a&gt;), which is a fancy way of saying it keeps your project looking consistent. Why is that a good thing? Well, it makes everything easier to understand! Want to know more? Let me break it down.&lt;/p&gt;

&lt;p&gt;First, we need to install husky in our project. For this we are going to follow &lt;a href="https://typicode.github.io/husky/getting-started.html#automatic-recommended" rel="noopener noreferrer"&gt;husky automatic installation&lt;/a&gt; which is recommended.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx husky-init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This command executes the next actions.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the &lt;code&gt;prepare&lt;/code&gt; script to &lt;code&gt;package.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Create a sample &lt;code&gt;pre-commit&lt;/code&gt; hook that you can edit (by default, &lt;code&gt;npm test&lt;/code&gt; will run when you commit).&lt;/li&gt;
&lt;li&gt;Configure Git hooks path.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you want manual installation and customize the husky configuration you can read the corresponding &lt;a href="https://typicode.github.io/husky/getting-started.html#manual" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now we have to configure husky to execute some commands in the git &lt;a href="https://git-scm.com/docs/githooks" rel="noopener noreferrer"&gt;hooks&lt;/a&gt;. We are going to add three that from my point of view are the most important.&lt;/p&gt;

&lt;p&gt;To add a new hook we have to follow the next structure.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx husky add .husky/&lt;span class="o"&gt;{&lt;/span&gt;gitHook&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="s2"&gt;"{command}"&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;This command is going to create different bash files in the &lt;code&gt;.husky&lt;/code&gt; directory. The names of these files are going to be named with the correspondent git hook.&lt;/p&gt;

&lt;p&gt;The first one is the &lt;strong&gt;commit-msg&lt;/strong&gt; hook. Here we are going to ensure that our commit messages follow our commitlint configuration.&lt;/p&gt;

&lt;p&gt;So, let´s add our new hook! Following the command structure mentioned above.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx husky add .husky/commit-msg  &lt;span class="s1"&gt;'npx --no -- commitlint --edit ${1}'&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The second one is the pre-commit hook. With this hook, we are going to lint and format the files we want to add to our commit. This action is executed before committing our changes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx husky add .husky/pre-commit  &lt;span class="s1"&gt;'npm run lint &amp;amp;&amp;amp; npm run format'&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;The last one but not the least, is the &lt;strong&gt;pre-push&lt;/strong&gt; hook. This hook is going to execute our test before pushing our changes.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

npx husky add .husky/pre-push  &lt;span class="s1"&gt;'npm run test'&lt;/span&gt;


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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Docker &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Now we want to create our development environment for our NestJS project. In this part of the article we are going to see how to include Docker and Docker compose.&lt;/p&gt;

&lt;p&gt;First, we need to configure our Docker container creating our &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our Dockerfile employs multi-stage builds, which facilitate the setup of our docker container for both local and development settings. This method offers a range of advantages. It's a two-step process, compile dependencies in one stage and then keep only the essentials in the final image improving our Docker image performance. To learn more about multi-stage builds you can check the &lt;a href="https://docs.docker.com/build/building/multi-stage/" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;

&lt;span class="c"&gt;# BUILD FOR LOCAL DEVELOPMENT&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;As&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;development&lt;/span&gt;

&lt;span class="c"&gt;# Create app directory&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="c"&gt;# Copy application dependency manifests to the container image.&lt;/span&gt;
&lt;span class="c"&gt;# A wildcard is used to ensure copying both package.json AND package-lock.json (when available).&lt;/span&gt;
&lt;span class="c"&gt;# Copying this first prevents re-running npm install on every code change.&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=node:node package*.json ./&lt;/span&gt;

&lt;span class="c"&gt;# Install app dependencies using the `npm ci` command instead of `npm install`&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm ci

&lt;span class="c"&gt;# Bundle app source&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=node:node . .&lt;/span&gt;

&lt;span class="c"&gt;# Use the node user from the image (instead of the root user)&lt;/span&gt;
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; node&lt;/span&gt;

&lt;span class="c"&gt;# BUILD FOR PRODUCTION&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;As&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/src/app&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=node:node package*.json ./&lt;/span&gt;

&lt;span class="c"&gt;# To run `npm run build` we need access to the Nest CLI which is a dev dependency. In the previous development stage we ran `npm ci` which installed all dependencies, so we can copy over the node_modules directory from the development image&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=node:node --from=development /usr/src/app/node_modules ./node_modules&lt;/span&gt;

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=node:node . .&lt;/span&gt;

&lt;span class="c"&gt;# Run the build command which creates the production bundle&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm run build

&lt;span class="c"&gt;# Set NODE_ENV environment variable&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; NODE_ENV production&lt;/span&gt;

&lt;span class="c"&gt;# Remove husky from the production build and install the production dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;npm pkg delete scripts.prepare &lt;span class="se"&gt;\
&lt;/span&gt;    npm ci &lt;span class="nt"&gt;--omit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;dev

&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; node&lt;/span&gt;

&lt;span class="c"&gt;# PRODUCTION&lt;/span&gt;

&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;node:20-alpine&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;As&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;production&lt;/span&gt;

&lt;span class="c"&gt;# Copy the bundled code from the build stage to the production image&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=node:node --from=build /usr/src/app/node_modules ./node_modules&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --chown=node:node --from=build /usr/src/app/dist ./dist&lt;/span&gt;

&lt;span class="c"&gt;# Start the server using the production build&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; [ "node", "dist/main.js" ]&lt;/span&gt;



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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Docker-compose configuration &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Docker-compose is our dev sidekick, making local coding a cakewalk. One config file and that´s it! No more "it works on my machine" drama. Our &lt;code&gt;docker-compose&lt;/code&gt; file is located at the root level of our project.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dockerfile&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="c1"&gt;# Only will build development stage from our dockerfile&lt;/span&gt;
      &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;development&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/usr/src/app&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.env&lt;/span&gt;
    &lt;span class="c1"&gt;# Run a command against the development stage of the image&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run start:dev&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;3000:3000&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now it's a piece of cake to develop our app with the container system we have. It's super easy and hassle-free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Github Action &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Continuous Integration (CI) is a software development practice that allows developers to automatically build, test, and validate their code changes in a centralized and consistent environment. GitHub Actions is a powerful CI/CD (Continuous Integration/Continuous Deployment) platform integrated directly into GitHub repositories, enabling developers to automate their workflows seamlessly. Checkout their &lt;a href="https://docs.github.com/en/actions" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; to learn more!&lt;/p&gt;

&lt;p&gt;In this section, I'll guide you through the process of setting up a basic CI pipeline using GitHub Actions. This pipeline will automatically build and push your docker image to the Docker Hub account when a Pull Request is merged.&lt;/p&gt;

&lt;p&gt;Great! So, to push our Docker images, we need to authenticate our GitHub action. Don't worry, it's quite simple. First, let's add your Dockerhub username and token. After that, we just need to store the credentials in our GitHub repository settings. You can see how to do this in the image below. Let me know if you need any help with this.&lt;/p&gt;

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

&lt;p&gt;Awesome! Let's create our workflow now. We need to place it in the root of your directory at &lt;strong&gt;.github/workflows/build.yml&lt;/strong&gt;. This file will help us set up our CI steps. Don't worry, I'll guide you through the different steps so you can easily follow along!&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;

&lt;span class="c1"&gt;# This workflow is triggered when a pull request is closed (merged or closed without merging) into the main branch.&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;types&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;closed&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;#This defines a job named "build" that runs on the latest version of the Ubuntu environment.&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build Docker image&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="c1"&gt;# This step checks out your Git repository content&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="c1"&gt;# Uses the docker/login-action to log in to Docker Hub using the provided username and token.&lt;/span&gt;
        &lt;span class="c1"&gt;# The credentials are stored as secrets (DOCKERHUB_USERNAME and DOCKERHUB_TOKEN).&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Log in to Docker Hub&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/login-action@v3&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKERHUB_USERNAME }}&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.DOCKERHUB_TOKEN }}&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="c1"&gt;# Extracts the repository name from the GitHub repository full name and sets it as an environment variable (REPO_NAME). &lt;/span&gt;
        &lt;span class="c1"&gt;# This information can be useful for later steps.&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get repository name&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;repo_full_name="$GITHUB_REPOSITORY"&lt;/span&gt;
          &lt;span class="s"&gt;IFS='/' read -ra repo_parts &amp;lt;&amp;lt;&amp;lt; "$repo_full_name"&lt;/span&gt;
          &lt;span class="s"&gt;echo "REPO_NAME=${repo_parts[1]}" &amp;gt;&amp;gt; $GITHUB_ENV&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="c1"&gt;# Uses the docker/metadata-action to extract metadata such as tags and labels for Docker. &lt;/span&gt;
        &lt;span class="c1"&gt;# This metadata can be used for versioning and labelling Docker images.&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Extract metadata (tags, labels) for Docker&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;meta&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/metadata-action@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;images&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;${{ secrets.DOCKERHUB_USERNAME }}/${{env.REPO_NAME}}&lt;/span&gt;
          &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
            &lt;span class="s"&gt;type=sha,format=short &lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="c1"&gt;# Uses the docker/build-push-action to build and push the Docker image. It specifies the context as the current directory (.), the Dockerfile location (./Dockerfile), tags from the metadata, and labels from the metadata. &lt;/span&gt;
        &lt;span class="c1"&gt;# The push: true indicates that the image should be pushed to the Docker Hub registry.&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and push&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/build-push-action@v5&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
          &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./Dockerfile&lt;/span&gt;
          &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.meta.outputs.tags }}&lt;/span&gt;
          &lt;span class="na"&gt;labels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ steps.meta.outputs.labels }}&lt;/span&gt;
          &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;




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

&lt;/div&gt;

&lt;p&gt;Now each time we merge our PRs a GitHub action is going to build a docker image and push it to our registry in DockerHub as you can see in the following images.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7s1rrm5n0flnek36kvp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk7s1rrm5n0flnek36kvp.png" alt="Docker images in our Dockerhub registry"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hope you found it cool and picked up something useful. Stay curious, keep learning, and rock on! Cheers to your next adventure!&lt;/p&gt;

&lt;h3&gt;
  
  
  Bibliography
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/tkssharma/things-you-must-have-in-every-repo-for-javascript-27db"&gt;Things you must have in every Repo for Javascript&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.tomray.dev/nestjs-docker-compose-postgres" rel="noopener noreferrer"&gt;NestJS, Redis and Postgres local development with Docker Compose&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.tomray.dev/nestjs-docker-production" rel="noopener noreferrer"&gt;How to write a NestJS Dockerfile optimized for production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://earthly.dev/blog/cicd-build-github-action-dockerhub/" rel="noopener noreferrer"&gt;Create Automated CI/CD Builds Using GitHub Actions and DockerHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>nestjs</category>
      <category>docker</category>
      <category>githubactions</category>
    </item>
    <item>
      <title>Semantic Search with Elasticsearch on Large Documents</title>
      <dc:creator>Lövei Róbert</dc:creator>
      <pubDate>Wed, 15 Nov 2023 13:51:48 +0000</pubDate>
      <link>https://forem.com/one-beyond/semantic-search-with-elasticsearch-on-large-documents-367j</link>
      <guid>https://forem.com/one-beyond/semantic-search-with-elasticsearch-on-large-documents-367j</guid>
      <description>&lt;p&gt;Semantic search is a technique used by search engines to improve the accuracy of search results by understanding the intent and contextual meaning of the words used in a search query. Traditional search engines primarily rely on keyword matching to retrieve results. However, semantic search goes beyond matching keywords and takes into account the relationship between words, the context of the search, and the user's intent to deliver more relevant results. What if we combine both with a search engine? &lt;/p&gt;

&lt;p&gt;Elasticsearch introduced the dense_vector field type in late 2020, which stores dense vectors of float values. So how does this support semantic search?&lt;br&gt;&lt;br&gt;
In the context of semantic search and natural language processing, vectors are mathematical representations of words or phrases in a high-dimensional space. These representations capture the semantic meaning of words or phrases based on their context and relationships with other words in a given dataset. Vectors are part of a mathematical technique known as word embeddings or word vectors.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aYeVXrd1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2prohbc7m7v221e15079.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aYeVXrd1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2prohbc7m7v221e15079.png" alt="embedding large documents with openai api and elasticsearch" width="800" height="332"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Prepare Documents to Transformation into Embeddings
&lt;/h2&gt;

&lt;p&gt;There are several ways of transforming our documents into embeddings. One is to use an external API, like &lt;a href="https://platform.openai.com/docs/guides/embeddings/what-are-embeddings"&gt;OpenAI’s&lt;/a&gt;, or &lt;a href="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/embeddings?tabs=console"&gt;Microsoft Azure’s&lt;/a&gt; embedding endpoints. Another way is to use our local computer, or an on-premises server with a Hugging Face model, like &lt;a href="https://huggingface.co/BAAI/bge-large-en-v1.5"&gt;bge-large-en&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;Either way, we will face a document size limitation in the transformation step. In the case of OpenAI’s text-embedding-ada-002 model, the limit is 8192 tokens, which is roughly 5000 words. In the case of Hugging Face models, the token size limitation in most cases is 512, which is around 312 words. What can we do to overcome these limits? &lt;/p&gt;

&lt;p&gt;First, we need to slice our documents to make them fit into token limits with the right tool. At One Beyond, we use CharacterTextSplitter class from Python’s langchain library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;text = "..." # your text 
from langchain.text_splitter import CharacterTextSplitter 
text_splitter = CharacterTextSplitter( 
separator = ".", 
chunk_size = 512, 
chunk_overlap = 256 
) 

docs = text_splitter.create_documents([text]) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example our separator is a “.” punctuation sign, which means we split at sentence endings. We allow 512 characters in one chunk, but with 256 characters overlap from the last and next chunks. We need the overlap to keep the context of a specific chunk. If you want to read about other chunking solutions &lt;a href="https://www.pinecone.io/learn/chunking-strategies/"&gt;this is the right article&lt;/a&gt; for you.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Transform a Single Text into Multiple Embeddings
&lt;/h2&gt;

&lt;p&gt;At this step we have our original documents and the chunked versions of them, which fit into the limitations of our selected model.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from sentence_transformers import SentenceTransformer 
model = SentenceTransformer('BAAI/bge-large-en-v1.5') 

text = "..." # your text 
document_chunks = text_splitter.create_documents([text]) 
texts = [doc.page_content for doc in document_chunks] 
texts = [text.replace("\n", ". ") for text in texts] 

embeddings = model.encode(texts) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example we use SentenceTransformer class to load model BGE Large and use it to tokenize our chunks. &lt;/p&gt;

&lt;p&gt;The other options are to use either OpenAI, or Azure AI API to embed them. Here is an example with Azure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import openai 
from dotenv import load_dotenv 

load_dotenv() 

openai.api_key = os.getenv("AZURE_AI_KEY") 
openai.api_base = "https://ob-openai-semantic-search-eastus.openai.azure.com/" 
openai.api_type = 'azure' 
openai.api_version = '2023-05-15' 

your_text = "..." # your text 

document_chunks = text_splitter.create_documents([your_text]) 
texts = [doc.page_content for doc in document_chunks] 
texts = [text.replace("\n", ". ") for text in texts] 
embeddings = [] 
for text in texts: 
    response = openai.Embedding.create(engine="text-embedding-ada-002", input=text) 
    embeddings.append(response.data[0].embedding) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can configure openai python lib to user either OpenAI, or Azure endpoints. &lt;/p&gt;

&lt;h2&gt;
  
  
  3. Create Elasticsearch schema and insert documents
&lt;/h2&gt;

&lt;p&gt;Since we have our original long text and multiple chunks and embeddings associated with it, we need to create parent child relationship between them in our Elasticsearch index. There is an example payload below how you can create such an index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
  "mappings": { 
    "properties": { 
      "id": {"type": "keyword", "store": "true"}, 
      "text": {"type": "text", "store": "true"}, 
      "embedding_bge_large_en_v1_5": { 
        "type": "dense_vector", 
        "dims": 512, 
        "index": True, 
        "similarity": "cosine", 
      }, 
      "vectors": { 
        "type": "join", 
        "relations": { 
          "chunk_embedding": "embedding_bge_large_en_v1_5", 
        }, 
      } 
    } 
  } 
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, we define the document property embedding_bge_large_en_v1_5 as dense_vector with 512 lengths. We define cosine as similarity type. Cosine similarity is a method to determine distance between vectors. If you want to know more about it &lt;a href="https://en.wikipedia.org/wiki/Cosine_similarity"&gt;this is a useful article&lt;/a&gt;. Below is an example of insert document payload into this index.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
  "id": f"{text['id']}_{vector_index}", 
  "embedding_bge_large_en_v1_5": vector, 
  "vectors": { 
    "name": "embedding_bge_large_en_v1_5", 
    "parent": text['id'] 
  }, 
  "routing": 1 
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Search in the index
&lt;/h2&gt;

&lt;p&gt;At this point we have our index populated with data. It is time to run semantic search on it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6TLYDNqD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xo132snwb15qakkf71s2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6TLYDNqD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xo132snwb15qakkf71s2.png" alt="search dense vectors with elasticsearch" width="800" height="310"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As we can see above, we transform our user search into an embedding in similar way to the one I detailed it in Point 2, except that we will have only 1 embedding without chunking this time. &lt;/p&gt;

&lt;p&gt;We compare this embedding with cosine similarity to the chunk embeddings we store in Elasticsearch. This is a built-in feature, so we can do it with a simple query as detailed below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
  "size": 10, 
  "_source": ["text"], 
  "query": { 
  "has_child": { 
    "score_mode": "max", 
    "type": "embedding_bge_large_en_v1_5", 
      "query": { 
        "function_score": { 
          "script_score": { 
            "script": { 
              "source": "(cosineSimilarity(params.vector,'embedding_bge_large_en_v1_5') + 1)", 
              "params": {"vector": query_vector.tolist()}, 
            } 
          } 
        } 
      } 
    } 
  } 
} 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Earlier, we defined cosine as similarity on the child field’s similarity type, so we don’t need to tell Elastic in the query to use it. In the example, query_vector is the search embed passed in as vector to proceed similarity search. The parent document’s score will be the maximum similarity score of its children. &lt;/p&gt;

&lt;h2&gt;
  
  
  5. Example
&lt;/h2&gt;

&lt;p&gt;A good example for all the above is when we have written transcriptions of knowledge sharing sessions or other kind of presentations and we want to build a search bot. Usually presentation or knowledge sharing transcriptions are way longer than embedding limitations with a few hundred words. With the method I explained above you’ll be able to run searches on your knowledge base like “Show presentations about user interface development”. Here is a real example answer from our knowledge sharing bot on our company Slack: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pyQqPRs7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/068o1236mg5oygf124w3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pyQqPRs7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/068o1236mg5oygf124w3.png" alt="semantich search example with elastic search" width="800" height="850"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Semantic search is a powerful information retrieval technique that goes beyond traditional keyword matching to understand the meaning and context of user queries. In the context of searching for UI development presentations, semantic search can enhance the search experience by considering the underlying concepts and relationships between words. &lt;/p&gt;

&lt;p&gt;For instance, this query was focused on UI development, but semantic search algorithms can recognize related terms like "user experience (UX)" even if not explicitly mentioned in the query. This enables the system to retrieve presentations that may be relevant to UX, ensuring a more comprehensive and accurate set of results. In essence, semantic search helps bridge the gap between user intent and search results by intelligently interpreting the meaning behind the words used in the query. &lt;/p&gt;

</description>
      <category>ai</category>
      <category>semanticsearch</category>
      <category>openai</category>
      <category>python</category>
    </item>
    <item>
      <title>Integrate MongoDB database with multiple collections using Mongoose in NestJS and Typescript</title>
      <dc:creator>Elizabeth Morillo</dc:creator>
      <pubDate>Wed, 25 Oct 2023 13:56:12 +0000</pubDate>
      <link>https://forem.com/one-beyond/integrate-mongodb-database-with-multiple-collections-using-mongoose-in-nestjs-and-typescript-egg</link>
      <guid>https://forem.com/one-beyond/integrate-mongodb-database-with-multiple-collections-using-mongoose-in-nestjs-and-typescript-egg</guid>
      <description>&lt;p&gt;In this article we are going to show you a way to integrate multiple &lt;strong&gt;&lt;a href="https://www.mongodb.com/what-is-mongodb" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt;&lt;/strong&gt;(NoSQL database) collections using &lt;strong&gt;&lt;a href="https://mongoosejs.com/" rel="noopener noreferrer"&gt;Mongoose&lt;/a&gt;&lt;/strong&gt; for highly scalable projects into the &lt;a href="https://docs.nestjs.com/" rel="noopener noreferrer"&gt;NestJS&lt;/a&gt; framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are we going to need?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MongoDB database, you can use one locally or use the cloud &lt;a href="https://www.mongodb.com/atlas/database" rel="noopener noreferrer"&gt;MongoDB database&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Have a new project created with Nest CLI, you can check this article for &lt;a href="https://docs.nestjs.com/first-steps" rel="noopener noreferrer"&gt;first steps&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation:
&lt;/h2&gt;

&lt;p&gt;Before starting with our code, it is necessary to install all the dependencies that we need, to do this in our console we run&lt;br&gt;
&lt;code&gt;npm install @nestjs/mongoose mongoose&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Mongoose Schema
&lt;/h2&gt;

&lt;p&gt;Before connecting and configuring our database we are going to create the necessary schemas. Each Schema represents a &lt;strong&gt;MongoDB&lt;/strong&gt; collection that will define our models and each key will define a property in our document that will be associated with a type. &lt;br&gt;
If you want to read more about it, I recommend this official &lt;a href="https://mongoosejs.com/docs/guide.html" rel="noopener noreferrer"&gt;guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the root of our project, we are going to create the following folder structure and inside our Schema folder let’s create a file for each collection we have in our database, in my case I will have only two, it should be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src
├── api 
│   ├── database  
│       └── schemas 
│         └── user.schema.ts 
│         └── dog.schema.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's define our schemas:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// schemas/user.schema.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SchemaFactory&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HydratedDocument&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;UserDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;HydratedDocument&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SchemaFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createForClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// schemas/dog.schema.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SchemaFactory&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HydratedDocument&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;DogDocument&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;HydratedDocument&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Dog&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Prop&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;User&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="nx"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DogSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;SchemaFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createForClass&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This looks spectacular! and we can use decorators to improve our code. The &lt;code&gt;@Prop()&lt;/code&gt; decorator defines &lt;a href="https://mongoosejs.com/docs/schematypes.html#what-is-a-schematype" rel="noopener noreferrer"&gt;schema types&lt;/a&gt; that are automatically inferred by Typescript. &lt;br&gt;
I personally prefer to use decorators since it allows us a better definition, we can send arguments and improve the typing to ensure that we do not have any errors in the future related to the data we send to our database, but if you prefer you can also create your schematics manually, Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;DogSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; 
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;breed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;mongoose&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ObjectId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;User&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;HINT: Remember we don’t need to add an &lt;code&gt;_id&lt;/code&gt; since Mongoose automatically adds an &lt;code&gt;_id&lt;/code&gt; property to your schema.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Connection and Database Module
&lt;/h2&gt;

&lt;p&gt;Once our models have been defined, we can create the connection to our database, inside the folder we created earlier called database, we are going to create a file named &lt;code&gt;database.module.ts&lt;/code&gt; where we will make the connection to our database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Module&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MongooseModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../constants/database&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;MongooseModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRoot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;YOUR_MONGODB_CONNECTION_STRING&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;HINT: It is important to indicate the name of the database to which we want to connect (dbName)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Following best practices, you should create a folder named constants, where we will keep all these literal numeric or string values, known as "magic numbers" and "magic strings", In my case I have only created a database file, here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// ../api/constants/database.ts&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;DATABASE_NAME&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dev_test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is also the possibility of creating our database connection asynchronously and for this Nest provides us with a method called &lt;code&gt;forRootAsync()&lt;/code&gt;, this method also allows us to pass options asynchronously and inject dependencies as a &lt;code&gt;ConfigModule&lt;/code&gt;, for example, this will be the same connection but asynchronously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;MongooseModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forRootAsync&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ConfigModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;useFactory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ConfigService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;configService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;YOUR_MONGODB_CONNECTION_STRING&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;dbName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;database&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DATABASE_NAME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;inject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;ConfigService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DatabaseModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to know more about how to configure and use a &lt;code&gt;ConfigModule&lt;/code&gt; and a &lt;code&gt;ConfigService&lt;/code&gt; using the environment variables, I recommend this &lt;a href="https://dev.to/one-beyond/how-to-configure-and-use-environment-variables-in-nestjs-3cm2"&gt;article&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To be able to use the new connection we need to import the new DatabaseModule to our &lt;code&gt;app.module&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Module&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DogModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./api/dog/dog.module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UserModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./api/user/user.module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DatabaseModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./api/database/database.module&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;DogModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DatabaseModule&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using our collections
&lt;/h2&gt;

&lt;p&gt;Up to this point if we have our app running and listening to all the changes we have been making (&lt;code&gt;npm run start:dev&lt;/code&gt;) we should not have any errors in the console, Excellent! &lt;/p&gt;

&lt;p&gt;Now let's see how to consume our data stored in both collections independently. To begin we are going to create the following folders&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src
├── api 
│   ├── database
│   ├── dog
│       └── dog.module.ts
│       └── dog.service.ts
│   ├── user
│       └── user.module.ts
│       └── user.service.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example I only need two modules, but the idea is that you create how many modules you need according to your collections. &lt;/p&gt;

&lt;p&gt;It’s important in this step that if we have multiple collections, we should always indicate the name of the schema to which we want to refer, the method &lt;code&gt;forFeature()&lt;/code&gt; provided by the MongooseModule allow us to configure the module, the models by including them should be registered in the current scope.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// dog.module.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Module&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DogService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dog.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DogController&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dog.controller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MongooseModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DogSchema&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/api/database/schemas/dog.schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;MongooseModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forFeature&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DogSchema&lt;/span&gt; &lt;span class="p"&gt;}])],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;DogController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;DogService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// user.module.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Module&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UserController&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.controller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;UserService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./user.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MongooseModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/api/database/schemas/user.schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;MongooseModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forFeature&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&lt;/span&gt; &lt;span class="p"&gt;}]),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;UserService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;NOTE: Remember to Add your modules to &lt;code&gt;app.module.ts&lt;/code&gt; in the imports&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we are ready for the queries! &lt;/p&gt;

&lt;p&gt;As you can see, both models are practically the same, the only difference is that they use different collections, having registered our schema allows us to inject using the &lt;code&gt;@InjectModel()&lt;/code&gt; decorator in the service that we want to use&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// dog.service.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Logger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;InjectModel&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/api/database/schemas/dog.schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(@&lt;/span&gt;&lt;span class="nd"&gt;InjectModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;dogModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This action returns all DOGS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dogModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Amazing, isn't it? This will not only allow us to have a more organized project but thinking about the future when refactoring/deleting/adding collections will be much easier. &lt;/p&gt;

&lt;p&gt;Now wait a moment, what would happen if, for example, our dog service also needed to use data from the User’s collection? Would it be possible to add a second collection to the dog module? Yes, it is possible! &lt;/p&gt;

&lt;p&gt;Keep in mind that for these cases it is always better to create fields that make references between the collections, this is an example of how we would inject the user collection into our Dog module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// dog.module.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Module&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DogService&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dog.service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DogController&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dog.controller&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MongooseModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;DogSchema&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/api/database/schemas/dog.schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../database/schemas/user.schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Module&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;MongooseModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forFeature&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;DogSchema&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserSchema&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;]),&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;controllers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;DogController&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;DogService&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// dog.service.ts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Logger&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/common&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;InjectModel&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nestjs/mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mongoose&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Dog&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/api/database/schemas/dog.schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../database/schemas/user.schema&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Injectable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DogService&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;InjectModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;dogModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;InjectModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;findAll&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This action returns all DOGS&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;dogModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;findAllUsers&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This action returns all USERS in dog service&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;userModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Thank you all very much for reading this article and I hope it helps you create amazing applications. Please let me know in the comments what you think about this post or if you have any questions. Thank you so much for reading! &lt;/p&gt;

&lt;p&gt;Thank you all and happy coding! 🖖 &lt;/p&gt;

</description>
      <category>beginners</category>
      <category>javascript</category>
      <category>nestjs</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
