<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vidit Shah</title>
    <description>The latest articles on DEV Community by Vidit Shah (@proton0210).</description>
    <link>https://dev.to/proton0210</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F724609%2F8841e975-4031-4112-97bc-468f70aa1e0d.jpeg</url>
      <title>DEV Community: Vidit Shah</title>
      <link>https://dev.to/proton0210</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/proton0210"/>
    <language>en</language>
    <item>
      <title>Creating Webhook between Clerk and DynamoDB</title>
      <dc:creator>Vidit Shah</dc:creator>
      <pubDate>Wed, 13 Mar 2024 18:11:48 +0000</pubDate>
      <link>https://dev.to/proton0210/creating-webhook-between-clerk-and-dynamodb-55fi</link>
      <guid>https://dev.to/proton0210/creating-webhook-between-clerk-and-dynamodb-55fi</guid>
      <description>&lt;p&gt;The Whole Motive behind this blog is Auth is hard and a bit of pain to set up in AWS Cognito.With All Due AWS Cognito is a great service but has a learning curve.&lt;/p&gt;

&lt;p&gt;So, lets learn how to integrate all this stack together&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%2Fw1f7b46wxdehbp34zefy.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%2Fw1f7b46wxdehbp34zefy.png" alt="Image description" width="800" height="251"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The common assumption you have a Nextjs Project clerk ready and a Users table in DynamoDB in your specific region&lt;/p&gt;

&lt;p&gt;I have Users Table deployed with Partition key as ClerkID&lt;/p&gt;

&lt;p&gt;So first let's get started with our nextjs Project&lt;/p&gt;

&lt;p&gt;Folder Structure lib-&amp;gt;actions-&amp;gt;user.action.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use server";
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
import { marshall } from "@aws-sdk/util-dynamodb";

export const createUser = async ({
  clerkId,
  name,
  username,
  email,
  picture,
}: {
  clerkId: string;
  name: string;
  username: string;
  email: string;
  picture: string;
}) =&amp;gt; {
  const ddbClient = new DynamoDBClient({
    region: process.env.AWS_REGION as string,
    credentials: {
      accessKeyId: process.env.AWS_ACCESS_KEY_ID as string,
      secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY as string,
    },
  });
  const params = {
    TableName: "Users",
    Item: marshall({
      ClerkID: clerkId,
      Name: name,
      Username: username,
      Email: email,
      Picture: picture,
    }),
  };

  try {
    await ddbClient.send(new PutItemCommand(params));
  } catch (err) {
    throw err;
  }
};

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

&lt;/div&gt;



&lt;p&gt;As you see this code runs on server so lets update our next config too&lt;/p&gt;

&lt;p&gt;next.config.mjs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nextConfig = {
  experimental: {
    mdxRs: true,
    serverComponentsExternalPackages: [
      "@aws-sdk/client-dynamodb",
      "@aws-sdk/util-dynamodb",
    ],
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the API Post route in your app directory&lt;/p&gt;

&lt;p&gt;This all is explained in the Documentation for clerk&lt;/p&gt;

&lt;p&gt;&lt;a href="https://clerk.com/docs/integrations/webhooks/overview?_gl=1*2sp5w1*_gcl_au*Mjk3Mjc1MDIwLjE3MDkwNjYzMzI.*_ga*MTc2OTg3MDQ5OS4xNzA5MDY2MzMy*_ga_1WMF5X234K*MTcxMDM1MTYxNi4xMC4xLjE3MTAzNTE2MzYuMC4wLjA."&gt;Webhook Clerk documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now in our App Directory&lt;br&gt;
app-&amp;gt;api-&amp;gt;webhook-&amp;gt;route.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* eslint-disable camelcase */
import { Webhook } from "svix";
import { headers } from "next/headers";
import { WebhookEvent } from "@clerk/nextjs/server";
import { createUser } from "@/lib/actions/user.action";
import { NextResponse } from "next/server";

export async function POST(req: Request) {
  // You can find this in the Clerk Dashboard -&amp;gt; Webhooks -&amp;gt; choose the webhook
  //
  const WEBHOOK_SECRET = process.env.NEXT_CLERK_WEBHOOK_SECRET;

  if (!WEBHOOK_SECRET) {
    throw new Error(
      "Please add WEBHOOK_SECRET from Clerk Dashboard to .env or .env.local"
    );
  }

  // Get the headers
  const headerPayload = headers();
  const svix_id = headerPayload.get("svix-id");
  const svix_timestamp = headerPayload.get("svix-timestamp");
  const svix_signature = headerPayload.get("svix-signature");

  // If there are no headers, error out
  if (!svix_id || !svix_timestamp || !svix_signature) {
    return new Response("Error occured -- no svix headers", {
      status: 400,
    });
  }

  // Get the body
  const payload = await req.json();
  const body = JSON.stringify(payload);

  // Create a new SVIX instance with your secret.
  const wh = new Webhook(WEBHOOK_SECRET);

  let evt: WebhookEvent;

  // Verify the payload with the headers
  try {
    evt = wh.verify(body, {
      "svix-id": svix_id,
      "svix-timestamp": svix_timestamp,
      "svix-signature": svix_signature,
    }) as WebhookEvent;
  } catch (err) {
    console.error("Error verifying webhook:", err);
    return new Response("Error occured", {
      status: 400,
    });
  }

  const eventType = evt.type;

  console.log({ eventType });
  // write this block by yourself
  try {
    // ... (existing code)

    if (eventType === "user.created") {
      const {
        id,
        email_addresses,
        image_url,
        username,
        first_name,
        last_name,
      } = evt.data;

      try {
        console.log("Creating user...");
        const user = await createUser({
          clerkId: id,
          name: `${first_name}${last_name ? ` ${last_name}` : ""}`,
          username: username!,
          email: email_addresses[0].email_address,
          picture: image_url,
        });
        return NextResponse.json({ message: "OK", user: user });
      } catch (err) {
        console.error("Error creating user:", err);
        return new Response("Error creating user", { status: 500 });
      }
    }

    return new Response("", { status: 201 });
  } catch (err) {
    console.error("Error in API route:", err);
    return new Response("Internal Server Error", { status: 500 });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy your website to Vercel or any other provider add your webhook endpoint of the deployed website to the environment variables here are images to do so&lt;br&gt;
eg : &lt;a href="http://www.example.com/api/webhook"&gt;www.example.com/api/webhook&lt;/a&gt;&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%2Fv7d7r0kcp877vlykogcc.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%2Fv7d7r0kcp877vlykogcc.png" alt="Image description" width="800" height="233"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Make sure you add NEXT_CLERK_WEBHOOK_SECRET in your .env.local&lt;/p&gt;

&lt;p&gt;Here what .env.local should look like when deployed &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%2Fr7l0p5rzzp0xx4pi8gnp.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%2Fr7l0p5rzzp0xx4pi8gnp.png" alt="Image description" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Taddaa you are all set &lt;/p&gt;

</description>
      <category>aws</category>
      <category>nextjs</category>
      <category>clerk</category>
      <category>dynamodb</category>
    </item>
    <item>
      <title>Setting Up Auth using AWS-CDK, Cognito, NextJs 14, and AWS Amplify v6</title>
      <dc:creator>Vidit Shah</dc:creator>
      <pubDate>Wed, 17 Jan 2024 18:59:48 +0000</pubDate>
      <link>https://dev.to/proton0210/setting-up-auth-using-aws-cdk-cognito-nextjs-14-and-aws-amplify-v6-9b3</link>
      <guid>https://dev.to/proton0210/setting-up-auth-using-aws-cdk-cognito-nextjs-14-and-aws-amplify-v6-9b3</guid>
      <description>&lt;p&gt;Welcome to this blog we'll learn how to set up using AmplifyV6&lt;/p&gt;

&lt;p&gt;We'll deploy our backend using aws-cdk&lt;br&gt;
We'll deploy our frontend (Next 14) on aws amplify hosting&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you feel lost with the steps or code do check out the GitHub repo&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Only authenticated users are greeted!&lt;br&gt;
&lt;a href="https://main.d1nzyxtrte9mh5.amplifyapp.com"&gt;Live App&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Complete code for this blog is available here :&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/proton0210/AuthUsingCognitoAmplifyAndCDK"&gt;Github Code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So let's get Started&lt;/p&gt;

&lt;p&gt;Create a parent folder initialize git init and add a .gitignore file&lt;/p&gt;

&lt;p&gt;&lt;code&gt;take auth-cognito&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Add the following in the .gitignore file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;**/node_modules/
**/.env
**/.env.local
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;now let's start building our backend&lt;/p&gt;

&lt;h2&gt;
  
  
  Backend
&lt;/h2&gt;

&lt;p&gt;let's initialize our CDK project backend&lt;/p&gt;

&lt;p&gt;&lt;code&gt;take backend&lt;/code&gt; in your terminal&lt;/p&gt;

&lt;p&gt;&lt;code&gt;cdk init app . --language=typescript&lt;/code&gt; in your terminal&lt;/p&gt;

&lt;p&gt;let's remove the git to avoid conflicts with our monorepo&lt;/p&gt;

&lt;p&gt;&lt;code&gt;rm -rf .git&lt;/code&gt; [works on linux and mac]&lt;/p&gt;

&lt;p&gt;Now run &lt;code&gt;cdk bootstrap&lt;/code&gt; in your terminal&lt;/p&gt;

&lt;p&gt;Now Let's create a handy script to synthesize and deploy our cdk application in &lt;code&gt;package.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;"deploy": "cdk synth &amp;amp;&amp;amp; cdk deploy --all"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;now rename your lib folder to stacks and create &lt;br&gt;
&lt;code&gt;auth.stack.ts&lt;/code&gt; in your stacks folder&lt;/p&gt;

&lt;p&gt;Let's create our user pool and user pool client&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as cdk from "aws-cdk-lib";
import { Construct } from "constructs";
import { aws_cognito as Cognito } from "aws-cdk-lib";
import * as iam from "aws-cdk-lib/aws-iam";

interface authStackProps extends cdk.StackProps {}

export class AuthStack extends cdk.Stack {
  public readonly userPool: Cognito.UserPool;
  public readonly userPoolClient: Cognito.UserPoolClient;

  constructor(scope: Construct, id: string, props?: authStackProps) {
    super(scope, id, props);
    this.userPool = this.createUserPool();
    this.userPoolClient = this.createWebClient();
    this.output();
  }

  createUserPool(props?: authStackProps) {
    const userPool = new Cognito.UserPool(this, "UserPool", {
      userPoolName: "UserPool",
      selfSignUpEnabled: true,
      autoVerify: {
        email: true,
      },
      passwordPolicy: {
        minLength: 8,
        requireLowercase: false,
        requireUppercase: false,
        requireDigits: false,
        requireSymbols: false,
      },
      signInAliases: {
        email: true,
      },
      standardAttributes: {
        email: {
          required: true,
          mutable: true,
        },
      },
      customAttributes: {
        name: new Cognito.StringAttribute({
          minLen: 3,
          maxLen: 20,
        }),
      },
    });
    return userPool;
  }

  createWebClient() {
    const userPoolClient = new Cognito.UserPoolClient(
      this,
      "UserPoolClient",
      {
        userPool: this.userPool,
        authFlows: {
          userPassword: true,
          userSrp: true,
        },
      }
    );
    return userPoolClient;
  }

  output() {
    new cdk.CfnOutput(this, "UserPoolId", {
      value: this.userPool.userPoolId,
    });
    new cdk.CfnOutput(this, "UserPoolClientId", {
      value: this.userPoolClient.userPoolClientId,
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now lets this stack to our bin and deploy&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env node
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { AuthStack } from "../stacks/auth-stack";

const app = new cdk.App();
const authStack = new AuthStack(app, "AuthStack");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;take &lt;code&gt;npm run deploy&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Don't forget to note down the values from the UserPool and UserPool Client
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Frontend
&lt;/h2&gt;

&lt;p&gt;All the code can be found under the frontend folder of repo &lt;br&gt;
&lt;a href="https://github.com/proton0210/AuthUsingCognitoAmplifyAndCDK/tree/main/frontend"&gt;FrontEnd&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's start building our frontend you can clone the repo and run &lt;code&gt;cd frontend &amp;amp;&amp;amp; npm init&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;create .env.local file and add your Userpool and UserpoolClient Values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;NEXT_PUBLIC_USER_POOL_ID=&amp;lt;USER_POOL_ID&amp;gt;
NEXT_PUBLIC_USER_POOL_CLIENT_ID=&amp;lt;USER_POOL_CLIENT_ID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Configuring Amplify on ServerSide&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;create a folder utils and create &lt;code&gt;amplifyServerUtils.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;this file exports &lt;code&gt;runWithAmplifyServerContext&lt;/code&gt; with our config object in it&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { createServerRunner } from "@aws-amplify/adapter-nextjs";
import { ResourcesConfig, AuthConfig } from "@aws-amplify/core";

const config: ResourcesConfig = {
  Auth: {
    Cognito: {
      userPoolId: process.env.NEXT_PUBLIC_USER_POOL_ID as string,
      userPoolClientId: process.env.NEXT_PUBLIC_USER_POOL_CLIENT_ID as string,
      signUpVerificationMethod: "code",
    },
  },
};
export const { runWithAmplifyServerContext } = createServerRunner({
  config,
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's dive into setting up our protected routes in the root of the folder you'll find&lt;br&gt;
&lt;code&gt;middleware.ts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The middleware function takes care of all the request-response and cors&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const config = {
  matcher: ["/"],
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;this line protects our home route&lt;/p&gt;

&lt;p&gt;the authenticated function checks whether the User is authenticated if the user is not authenticated we redirect the user signup, try it yourself&lt;/p&gt;

&lt;p&gt;&lt;code&gt;return NextResponse.redirect(new URL("/signup", request.url));&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now let's work to configure AWS to amplify the Client Side&lt;/p&gt;

&lt;p&gt;if you see the &lt;a href="https://github.com/proton0210/AuthUsingCognitoAmplifyAndCDK/blob/main/frontend/ConfigureAmplifyClientSide.ts"&gt;ConfigureAmplifyClientSide.ts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The steps are pretty much the same but we will be adding into our root layout&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/proton0210/AuthUsingCognitoAmplifyAndCDK/blob/main/frontend/app/layout.tsx"&gt;RootLayout&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hmilOdtx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ceu6mgaxtkz21ebfq13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hmilOdtx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ceu6mgaxtkz21ebfq13.png" alt="Verified user in Cognito" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i9xlm8vg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9g8i8h6gwe9zdj46i51x.png" alt="Success Home page" width="800" height="250"&gt;
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Hosting
&lt;/h2&gt;

&lt;p&gt;Make sure you've uploaded your mono repo on Github&lt;/p&gt;

&lt;p&gt;Go to AWS Amplify and select hosting&lt;br&gt;
Select GitHub and Grant Permission&lt;/p&gt;

&lt;p&gt;have a look at how to work with a mono-repo&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_a4E02Qb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zvotvqaudx6mdox2i7i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_a4E02Qb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1zvotvqaudx6mdox2i7i.png" alt="wokring with Monorepo" width="800" height="616"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now click on advance settings and add your environment Variables&lt;/p&gt;

&lt;p&gt;Make sure you add this custom image value&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_CUSTOM_IMAGE=amplify:al2023
NEXT_PUBLIC_USER_POOL_ID=&amp;lt;YOUR VALUES&amp;gt;
NEXT_PUBLIC_USER_POOL_CLIENT_ID=&amp;lt;YOUR VALUE&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6hy4NgzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o3724dpagplatc6d2hox.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6hy4NgzX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o3724dpagplatc6d2hox.png" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zDFMhcM0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bfhhcjs81qeuljh2zwko.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zDFMhcM0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bfhhcjs81qeuljh2zwko.png" alt="Image description" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And Tadddaa We're done&lt;/p&gt;




&lt;p&gt;If you Like to learn about dynamo DB :&lt;a href="https://www.learndynamoapi.com/"&gt;Click here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you like to learn about cognito :&lt;a href="https://main.d3m5kt17r5818r.amplifyapp.com/"&gt;Click here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Connect on X/Twitter = &lt;a href="https://twitter.com/Vidit_210"&gt;Follow here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cdk</category>
      <category>amplify</category>
      <category>cognito</category>
    </item>
  </channel>
</rss>
