<?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: TC Wang</title>
    <description>The latest articles on DEV Community by TC Wang (@tingchun0113).</description>
    <link>https://dev.to/tingchun0113</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%2F473992%2Fcee91c97-ee62-4d9b-bda5-4fda3a7ec73a.png</url>
      <title>DEV Community: TC Wang</title>
      <link>https://dev.to/tingchun0113</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/tingchun0113"/>
    <language>en</language>
    <item>
      <title>Build an AWS API from Scratch: A Comprehensive Step-by-Step Guide with Sample Code</title>
      <dc:creator>TC Wang</dc:creator>
      <pubDate>Sat, 22 Apr 2023 09:39:37 +0000</pubDate>
      <link>https://dev.to/tingchun0113/build-an-aws-api-from-scratch-a-comprehensive-step-by-step-guide-with-sample-code-2hlb</link>
      <guid>https://dev.to/tingchun0113/build-an-aws-api-from-scratch-a-comprehensive-step-by-step-guide-with-sample-code-2hlb</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;There are many (official) AWS guides out there. I've browsed through some of them, but I'm still missing some details when it comes to using AWS. So, if you're looking for an easy (and thorough) way to build and manage APIs on AWS for your next projects, this article is for you!&lt;/p&gt;

&lt;p&gt;You will learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use some AWS services (such as DynamoDB, Lambda, and API Gateway).&lt;/li&gt;
&lt;li&gt;Access data from a (DynamoDB) database using JavaScript (Node.js).&lt;/li&gt;
&lt;li&gt;Create a RESTful API using the AWS Management Console.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This article is &lt;strong&gt;NOT&lt;/strong&gt; for people who are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AWS experts&lt;/li&gt;
&lt;li&gt;Attempting to build production APIs&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Getting started with AWS services
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Create an AWS account. You can follow the instructions &lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/setting-up.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Navigate to the &lt;a href="https://aws.amazon.com/console/" rel="noopener noreferrer"&gt;AWS Management Console&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Learn the basics:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;DynamoDB&lt;/strong&gt;: a NoSQL database&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lambda&lt;/strong&gt;: a serverless computing platform for running code without managing servers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API Gateway&lt;/strong&gt;: a service for creating (RESTful) APIs to make calls to Lambda&lt;/li&gt;
&lt;li&gt;The relationship between these services is as follows (HTTP API is created by API Gateway):&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fh9rkn54gxsh4ad2ezb8x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fh9rkn54gxsh4ad2ezb8x.png" alt="Services relationship" width="718" height="111"&gt;&lt;/a&gt; &lt;br&gt;
&lt;small&gt;&lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(Optional) "Star" services for easy access. The starred services will then appear.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fag6c0a0pd04epl5778b6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fag6c0a0pd04epl5778b6.png" alt="AWS Management Console" width="640" height="259"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.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%2F2bqdjidol86gmp4beoid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F2bqdjidol86gmp4beoid.png" alt="AWS Management Console" width="704" height="61"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 1: Create a DynamoDB table
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the &lt;a href="https://console.aws.amazon.com/dynamodb/" rel="noopener noreferrer"&gt;DynamoDB&lt;/a&gt; service.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create table&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter the &lt;strong&gt;Table name&lt;/strong&gt; and &lt;strong&gt;Partition key&lt;/strong&gt; (primary key).&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create table&lt;/strong&gt; at the bottom.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Tables&lt;/strong&gt; in the left sidebar to locate the table you created.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fgox1aw3u0k06c1amlw8e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fgox1aw3u0k06c1amlw8e.png" alt="DynamoDB" width="265" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;(Optional) Check the regions in the top right corner if you cannot find a table.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fa5kp2pd3i9mbv1rhc1t6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fa5kp2pd3i9mbv1rhc1t6.png" alt="DynamoDB" width="316" height="375"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click in the created table and click &lt;strong&gt;Explore table items&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;At the bottom, you can use &lt;strong&gt;Actions&lt;/strong&gt; to edit/duplicate/delete items or &lt;strong&gt;Create item&lt;/strong&gt; to add new attributes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fjcc8dy21e0ld1bu039y8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fjcc8dy21e0ld1bu039y8.png" alt="DynamoDB" width="800" height="228"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 2: Create a Lambda function
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a function
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the &lt;a href="https://console.aws.amazon.com/lambda" rel="noopener noreferrer"&gt;Lambda&lt;/a&gt; service.&lt;/li&gt;
&lt;li&gt;Make sure your region is the same as the one where your DynamoDB is created.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create function&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter the &lt;strong&gt;Function name&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select a &lt;strong&gt;Runtime&lt;/strong&gt; (I will use Node.js 18.x in the following steps).&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Change default execution role&lt;/strong&gt;, select &lt;strong&gt;Create a new role from AWS policy templates&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter the &lt;strong&gt;Role name&lt;/strong&gt; and select &lt;strong&gt;Simple microservice permissions&lt;/strong&gt; (to interact with DynamoDB).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Faoiiwyfiww0o4kmsycbk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Faoiiwyfiww0o4kmsycbk.png" alt="Lambda" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Create function&lt;/strong&gt; at the bottom.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Write code in the function
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Under &lt;strong&gt;Code source&lt;/strong&gt;, you can write code in &lt;code&gt;index.mjs&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Import and use AWS and DynamoDB utilities.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import {
  DynamoDBDocumentClient,
  GetCommand,
  PutCommand,
} from '@aws-sdk/lib-dynamodb';

const client = new DynamoDBClient({});
const dynamo = DynamoDBDocumentClient.from(client);

const tableName = 'your-table-name-in-dynamodb'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GetCommand and PutCommand are methods to query and add/update DynamoDB items. More detailed methods can be found in this &lt;a href="https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html" rel="noopener noreferrer"&gt;guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Handle the event.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const handler = async (event) =&amp;gt; {
  // Extract values from the event: 
  // const authToken = event.queryStringParameters?.authToken ?? null;
  // const requestBody = event.body ? JSON.parse(event.body) : null;

  try {
    // Do something
  } catch (error) {
    console.log(error);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Try to query and add/update DynamoDB items.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;try {
    const data = await dynamo.send(
      new GetCommand({
        TableName: tableName,
        Key: { userId }, // Suppose your partition key is userId
      })
    );

    // Your code

    await dynamo.send(
      new PutCommand({
        TableName: tableName,
        Item: {
          userId,
          // Other attributes in the table,
        },
      })
    );

    // Return something
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Put it all together.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import {
  DynamoDBDocumentClient,
  GetCommand,
  PutCommand,
} from '@aws-sdk/lib-dynamodb';

const client = new DynamoDBClient({});
const dynamo = DynamoDBDocumentClient.from(client);

const tableName = 'your-table-name-in-dynamodb'

export const handler = async (event) =&amp;gt; {
  // Extract values from the event: 
  // const authToken = event.queryStringParameters?.authToken ?? null;
  // const requestBody = event.body ? JSON.parse(event.body) : null;

  try {
    const data = await dynamo.send(
      new GetCommand({
        TableName: tableName,
        Key: { userId }, // Suppose your partition key is userId
      })
    );

    // Your code

    await dynamo.send(
      new PutCommand({
        TableName: tableName,
        Item: {
          userId,
          // Other attributes in the table,
        },
      })
    );

    // Return something
  } catch (error) {
    console.log(error);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Add the required &lt;strong&gt;node_modules&lt;/strong&gt; to your function folder. Or, you can create a Lambda layer so that your node modules can be shared between different Lambda functions. Learn more &lt;a href="https://medium.com/@anjanava.biswas/nodejs-runtime-environment-with-aws-lambda-layers-f3914613e20e" rel="noopener noreferrer"&gt;here&lt;/a&gt;. &lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Deploy&lt;/strong&gt; when you are finished writing the code.&lt;/li&gt;
&lt;li&gt;(Optional) You might be wondering what's in an event and want to console.log it. In that case, you can see the console.logged event in &lt;a href="https://console.aws.amazon.com/cloudwatch" rel="noopener noreferrer"&gt;CloudWatch&lt;/a&gt; after creating a RESTful API in API Gateway. In CloudWatch, go to Logs &amp;gt; Log groups &amp;gt; your function &amp;gt; Log streams &amp;gt; Click to open a Log stream:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fu3oogqsxeu2577b5phn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fu3oogqsxeu2577b5phn3.png" alt="CloudWatch" width="800" height="346"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test your functions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Test&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter the &lt;strong&gt;Event name&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Edit the JSON object in &lt;strong&gt;Event JSON&lt;/strong&gt; and click &lt;strong&gt;Save&lt;/strong&gt; at the bottom.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F3fcq7vw2k7atctgvuye3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3fcq7vw2k7atctgvuye3.png" alt="Lambda" width="797" height="749"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Test&lt;/strong&gt; again. The result will appear in the &lt;strong&gt;Execution results&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 3: Create a RESTful API
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Navigate to the &lt;a href="https://console.aws.amazon.com/apigateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt; service.&lt;/li&gt;
&lt;li&gt;Make sure your region is the same as the one where DynamoDB/Lambda is created.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Create API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Locate the REST API and click &lt;strong&gt;Build&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Enter the &lt;strong&gt;API name&lt;/strong&gt; and select &lt;strong&gt;Edge optimized&lt;/strong&gt; in the Endpoint Type field. Leave others as the default and click &lt;strong&gt;Create API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Resources&lt;/strong&gt; in the left sidebar (the "/" is selected).&lt;/li&gt;
&lt;li&gt;(Optional) From &lt;strong&gt;Actions&lt;/strong&gt;, select &lt;strong&gt;Create Resource&lt;/strong&gt;. Enter the &lt;strong&gt;Resource Name&lt;/strong&gt; and &lt;strong&gt;Resource Path&lt;/strong&gt;, then select &lt;strong&gt;Enable API Gateway CORS&lt;/strong&gt;. Click &lt;strong&gt;Create Resource&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fcv979kqnefzeea8cjmtq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fcv979kqnefzeea8cjmtq.png" alt="API Gateway" width="800" height="220"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From &lt;strong&gt;Actions&lt;/strong&gt;, select &lt;strong&gt;Create Method&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select a method (e.g. POST) and select the checkmark.&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;Use Lambda Proxy integration&lt;/strong&gt; checkbox.&lt;/li&gt;
&lt;li&gt;Ensure the &lt;strong&gt;Lambda Region&lt;/strong&gt; is correct and enter the &lt;strong&gt;Lambda Function&lt;/strong&gt; you created.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fq41oo4rkvk63zqqu2hv5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fq41oo4rkvk63zqqu2hv5.png" alt="API Gateway" width="800" height="289"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Save&lt;/strong&gt; and &lt;strong&gt;OK&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Enable CORS&lt;/strong&gt; from &lt;strong&gt;Actions&lt;/strong&gt; for the method you created. Click &lt;strong&gt;Enable CORS and replace existing CORS headers&lt;/strong&gt; and &lt;strong&gt;Yes, replace existing values&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fnc1z43jsobpme5eor13r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fnc1z43jsobpme5eor13r.png" alt="API Gateway" width="800" height="202"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From &lt;strong&gt;Actions&lt;/strong&gt;, select &lt;strong&gt;Deploy API&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;[New Stage]&lt;/strong&gt; in the &lt;strong&gt;Deployment stage&lt;/strong&gt;. Enter the &lt;strong&gt;Stage name&lt;/strong&gt;. Click &lt;strong&gt;Deploy&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Step 4: Test your API
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;In the &lt;a href="https://console.aws.amazon.com/apigateway" rel="noopener noreferrer"&gt;API Gateway&lt;/a&gt; service, click the created API and click &lt;strong&gt;Stages&lt;/strong&gt; in the left sidebar.&lt;/li&gt;
&lt;li&gt;Click on the stage created and you will see the &lt;strong&gt;Invoke URL&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbczunkp8fytva418vsio.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbczunkp8fytva418vsio.png" alt="API Gateway" width="800" height="340"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can then use a tool like Postman to test your API.&lt;/li&gt;
&lt;li&gt;(Optional) Alternatively, you can test your API within API Gateway. Click &lt;strong&gt;Resources&lt;/strong&gt; in the left sidebar, then click the API (method) you created. Click &lt;strong&gt;TEST&lt;/strong&gt; (with a small blue lightning bolt). Enter the parameters and click &lt;strong&gt;Test&lt;/strong&gt; again. &lt;/li&gt;
&lt;li&gt;(Optional) Clean up unnecessary tables, functions, and APIs. See Step 8 of this &lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html" rel="noopener noreferrer"&gt;tutorial&lt;/a&gt; for more details.&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;I used the steps above to build my first API in AWS. AWS provides a robust set of tools that make it easy to build, deploy, and manage APIs. By following this guide and using the sample code provided, you can easily set up your own API using DynamoDB, Lambda, and API Gateway in AWS.&lt;/p&gt;

&lt;p&gt;It's worth noting that this is just the beginning. There are many other AWS features and services that can be used to enhance your APIs, such as AWS Cognito for user authentication and authorization, AWS S3 for object storage, and AWS CloudFront for content delivery. With these tools and services, you can create a robust and scalable API that can handle millions of requests per day.&lt;/p&gt;

&lt;p&gt;I hope this guide has helped you get started building an API in AWS. If you want to see more details about the API I built, you can check out this GitHub &lt;a href="https://github.com/tingchun0113/one-wallet-api" rel="noopener noreferrer"&gt;repository&lt;/a&gt; (each request is a Lambda function).&lt;/p&gt;




&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Build a CRUD API with Lambda and DynamoDB: &lt;a href="https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-dynamo-db.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;How to access a DynamoDB table using the DynamoDB utilities: &lt;a href="https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/dynamodb-example-dynamodb-utilities.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Deploy your serverless function using Amazon API Gateway: &lt;a href="https://aws.amazon.com/getting-started/hands-on/build-web-app-s3-lambda-api-gateway-dynamodb/module-three/" rel="noopener noreferrer"&gt;https://aws.amazon.com/getting-started/hands-on/build-web-app-s3-lambda-api-gateway-dynamodb/module-three/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Want to Connect?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you find this article useful or have any questions, &lt;br&gt;
connect me on &lt;strong&gt;LinkedIn&lt;/strong&gt; (&lt;a href="https://www.linkedin.com/in/tingchunw" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/tingchunw&lt;/a&gt;) for more articles.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>aws</category>
    </item>
    <item>
      <title>How to Perform Form Validation with HTML and JavaScript</title>
      <dc:creator>TC Wang</dc:creator>
      <pubDate>Tue, 14 Sep 2021 14:03:26 +0000</pubDate>
      <link>https://dev.to/tingchun0113/how-to-perform-form-validation-1a54</link>
      <guid>https://dev.to/tingchun0113/how-to-perform-form-validation-1a54</guid>
      <description>&lt;h2&gt;
  
  
  Why form validation is important
&lt;/h2&gt;

&lt;p&gt;Users use web forms to sign up or fulfill online transactions. If you have user input saving to a database, you better make sure the data collected is in the correct format. Someone could crash your website by putting ridiculous values into forms. &lt;/p&gt;

&lt;p&gt;Form validation can also be a security measure. Letting people put whatever they want into forms opens you up to SQL injections. There're way more reasons why form validation is important, but these are the two that I've seen destroy websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  Form validation 101
&lt;/h2&gt;

&lt;p&gt;Performing form validation on the front-end (before submitting data to the server) is called &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Forms/Form_validation" rel="noopener noreferrer"&gt;client-side form validation&lt;/a&gt;. While you can also validate data on the back-end/server-side, I will focus on the client-side.&lt;/p&gt;

&lt;p&gt;There're two types of client-side validation: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Built-in form validation (&lt;code&gt;HTML&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;JavaScript&lt;/code&gt; validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Built-in form validation has better performance than JavaScript but is less customizable. In the following example, I created a &lt;a href="https://tingchun0113.github.io/form-validation/" rel="noopener noreferrer"&gt;form&lt;/a&gt; with empty fields.&lt;br&gt;
&lt;a href="https://media2.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%2F6gvt74j3kfv0qkkebls6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F6gvt74j3kfv0qkkebls6.png" alt="https://tingchun0113.github.io/form-validation/" width="531" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try to type in "Jo" and hit the &lt;strong&gt;Register&lt;/strong&gt; button:&lt;br&gt;
&lt;a href="https://media2.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%2Fxwmdlapyzvf8uelgsmzr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fxwmdlapyzvf8uelgsmzr.png" alt="" width="632" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After fixing it, the border of the input field will turn from red to green:&lt;br&gt;
&lt;a href="https://media2.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%2Flcegvjrgcf9kmuroxotc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Flcegvjrgcf9kmuroxotc.png" alt="Pass" width="630" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can try out other fields as well, but below are the rules I imposed (using built-in form validation): &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Full Name: &lt;em&gt;min&lt;/em&gt; 3 characters; &lt;em&gt;max&lt;/em&gt; 100 characters&lt;/li&gt;
&lt;li&gt;Phone Number: 3 digits-3 digits-4 digits (1111111111 won't pass)&lt;/li&gt;
&lt;li&gt;Email Address: "@" has to be included&lt;/li&gt;
&lt;li&gt;Website URL: "http://" or "https://" has to be included&lt;/li&gt;
&lt;li&gt;Password: 1 uppercase character, 1 lowercase character, and 1 number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Besides, I used JavaScript validation to ensure that "Password" matches "Confirm Password."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2F9b15aqxh6tlpcyzsygz4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F9b15aqxh6tlpcyzsygz4.png" alt="Match passwords" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  Time to see some codes
&lt;/h2&gt;

&lt;p&gt;Built-in form validation (HTML) provides a bunch of attributes to help validate data. Here're some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;* required
* minlength="3"
* maxlength="100"
* pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
* type="email"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Putting them into HTML:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Then, check whether passwords match using JavaScript validation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if "Password" === "Confirm Password", passwords match
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;You can find the full &lt;a href="https://github.com/tingchun0113/form-validation/blob/main/script.js" rel="noopener noreferrer"&gt;JavaScript file&lt;/a&gt; and other project files in this &lt;a href="https://github.com/tingchun0113/form-validation" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Just don't forget that you can (and you should) validate the data on the server side. It's the final line of defense before the database. If you find this article useful or have any questions, connect me on &lt;a href="https://www.linkedin.com/in/tingchunw/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or follow me on &lt;a href="https://tingchun0113.medium.com/" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; for more articles.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to Implement Infinite Scroll with Vanilla JS</title>
      <dc:creator>TC Wang</dc:creator>
      <pubDate>Tue, 24 Aug 2021 14:43:37 +0000</pubDate>
      <link>https://dev.to/tingchun0113/how-to-implement-infinite-scroll-with-vanilla-js-3791</link>
      <guid>https://dev.to/tingchun0113/how-to-implement-infinite-scroll-with-vanilla-js-3791</guid>
      <description>&lt;p&gt;&lt;strong&gt;Infinite scroll&lt;/strong&gt; is often used on social media sites such as Twitter or Pinterest. The feature allows users to load some pictures/contents on a website and then load more once reaching the end of the webpage. &lt;/p&gt;

&lt;p&gt;I used &lt;a href="https://unsplash.com/documentation" rel="noopener noreferrer"&gt;Unsplash API&lt;/a&gt; to get random pictures. This article will focus on how to use JavaScript to make use of some properties to achieve infinite scroll. You can find other project files (HTML or CSS files) in this &lt;a href="https://github.com/tingchun0113/infinite-scroll-unsplash-api" rel="noopener noreferrer"&gt;repo&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Four Properties to Achieve Infinite Scroll
&lt;/h2&gt;

&lt;p&gt;A) &lt;code&gt;window.scrollY&lt;/code&gt;: How far the document has been scrolled from the top&lt;br&gt;
B) &lt;code&gt;window.innerHeight&lt;/code&gt;: The visible part of the window&lt;br&gt;
C) &lt;code&gt;document.body.offsetHeight&lt;/code&gt;: The height of the entire document&lt;br&gt;
D) &lt;code&gt;1000px (or any value)&lt;/code&gt;: The distance from bottom of document&lt;/p&gt;

&lt;p&gt;The diagram below better illustrates these properties:&lt;br&gt;
&lt;a href="https://media2.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%2Fsr2eig6tm023simo3yw9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fsr2eig6tm023simo3yw9.png" alt="JavaScript Web Projects: 20 Projects to Build Your Portfolio" width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;



&lt;p&gt;Looking at the above, we can listen to the scroll event:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;If A (scrollY) + B (innerHeight) &amp;gt;= C (document height) - D (1000px) 
-&amp;gt; load more photos
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Check to see if scrolling near bottom of page; load more photos
window.addEventListener('scroll', () =&amp;gt; {
  if (
    window.scrollY + window.innerHeight &amp;gt;= document.body.offsetHeight - 1000
  ) {
    getPhotos();
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;There're other tools (&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API" rel="noopener noreferrer"&gt;Intersection Observer API&lt;/a&gt;) to implement infinite scroll. If you find this article useful or have any questions, connect me on &lt;a href="https://www.linkedin.com/in/tingchunw/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; or follow me on &lt;a href="https://tingchun0113.medium.com/" rel="noopener noreferrer"&gt;Medium&lt;/a&gt; for more articles.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
