DEV Community

Cover image for DevOps Stage 1 - Number Classification API
Precious Ogundipe
Precious Ogundipe

Posted on • Edited on

DevOps Stage 1 - Number Classification API

Introduction

In this, tutorial I will walk you through how I built a Number Classification API. This API allows users to input a number and get details about the number. I'll cover both the frontend and backend parts of the project, explaining how each piece of the system works and how they interact.

Technical Architecture

Architecture

Step 1: Creating the Frontend for Input

The first thing I did was create the frontend UI to input the number. The frontend is essential because users need an interface to interact with the API. I used HTML and JavaScript to build a simple form where users can enter numbers.

You can check out my frontend code here

Step 2: Hosted My Frontend on GitHub Pages

For this project, I wanted a seamless user experience by allowing users to input a number and see the results from the API. This is where GitHub Pages came into play. GitHub Pages is a free service that allows you to host static websites directly from a GitHub repository. Here's how I used it for the frontend part of my API.

Steps for hosting on GitHub Pages:

  1. Create a GitHub repository for the frontend files.
  2. Push the HTML, CSS, and JavaScript files to the repository.
  3. Enable GitHub Pages under the repository settings.
  4. Choose the branch (main) and the root directory for serving the files.
  5. GitHub will provide a URL to access the hosted frontend.

Step 3: Setting Up the Backend with AWS Lambda

Once the frontend was ready, I moved on to the backend. For the backend, the first thing I did was to create a Lambda function called numberapi, which uses node.js version 22 as runtime which would be used to process the request from the frontend. The Lambda function accepts the number, performs calculations, and returns the results.

lambda image
here is my lambda function code;

// Utility function: Check if a number is prime
function isPrime(num) {
  if (num < 2) return false;
  for (let i = 2; i <= Math.sqrt(num); i++) {
      if (num % i === 0) return false;
  }
  return true;
}

// Utility function: Check if a number is perfect
function isPerfect(num) {
  if (num < 1) return false;
  let sum = 0;
  for (let i = 1; i <= num / 2; i++) {
      if (num % i === 0) sum += i;
  }
  return sum === num;
}

// Utility function: Check if a number is an Armstrong number
function isArmstrong(num) {
  const digits = num.toString().split('').map(Number);
  const power = digits.length;
  const sum = digits.reduce((acc, digit) => acc + Math.pow(digit, power), 0);
  return sum === num;
}

// Utility function: Calculate the sum of digits
function digitSum(num) {
  // Handle negative numbers by using the absolute value
  num = Math.abs(num);
  return num.toString().split('').reduce((acc, digit) => acc + Number(digit), 0);
}

// AWS Lambda handler function
export const handler = async (event) => {
  const query = event.queryStringParameters || {};
  const numberParam = query.number;
  const parsedNumber = parseInt(numberParam, 10);

  const headers = {
      "Content-Type": "application/json",
      "Access-Control-Allow-Origin": "*"
  };

  // Validate input: if not a valid integer, return 400 with error JSON
  if (isNaN(parsedNumber)) {
      return {
          statusCode: 400,
          headers,
          body: JSON.stringify({ number: numberParam, error: true })
      };
  }

  const prime = isPrime(parsedNumber);
  const perfect = isPerfect(parsedNumber);
  const armstrong = isArmstrong(parsedNumber);
  const parity = (parsedNumber % 2 === 0) ? "even" : "odd";

  let properties = [];
  if (prime) {
      properties.push("prime");
  }
  if (perfect) {
      properties.push("perfect");
  }
  if (armstrong) {
      properties.push("armstrong");
  }

  // Add parity (odd/even)
  properties.push(parity);

  const sum = digitSum(parsedNumber);

  let fun_fact = "";
  try {
      const response = await fetch(`http://numbersapi.com/${parsedNumber}/math`);
      fun_fact = await response.text();
  } catch (error) {
      fun_fact = "Fun fact unavailable at this time.";
  }

  const result = {
      number: parsedNumber,
      is_prime: prime,
      is_perfect: perfect,
      properties: properties,
      digit_sum: sum,
      fun_fact: fun_fact
  };

  return {
      statusCode: 200,
      headers,
      body: JSON.stringify(result)
  };
};
Enter fullscreen mode Exit fullscreen mode

Step 4: Deploying the Lambda Function with API Gateway

After creating the Lambda function, the next step was to set up an API Gateway to allow communication between the frontend and the Lambda function.

  • Create a REST API in API Gateway.
  • Add a GET endpoint (/classify-number) that triggers the Lambda function when called.
  • Set up CORS so that the frontend can make requests to the API.

API gateway

endpoint

cors

  • If you go back to your lambda function you'll see that API GATEWAY has been added automatically

lambdawithapi

You can check the API app here

Top comments (2)

Collapse
 
toluxfash profile image
Tolulope Fasoro

๐Ÿ‘๐Ÿ‘

Collapse
 
adeoluwa profile image
Kiishi_joseph

Thank you for this!