Build Your First REST API with Node.js

REST APIs are the backbone of modern web and mobile applications. If you’re learning backend development, building a REST API using Node.js is one of the best places to start.

In this guide, you’ll learn how to build your first REST API in Node.js using Express.js, with simple examples you can run locally.


Prerequisites

Before starting, make sure you have:

  • Basic JavaScript knowledge
  • Node.js installed
  • A code editor (VS Code recommended)

Check Node.js installation:

node -v
npm -v


What Is a REST API?

A REST API allows applications to communicate with each other using HTTP methods:

  • GET – Fetch data
  • POST – Create data
  • PUT – Update data
  • DELETE – Remove data

REST APIs usually return data in JSON format.


Step 1: Create a New Node.js Project

Create a folder and initialize your project:

mkdir my-first-api
cd my-first-api
npm init -y

This creates a package.json file.


Step 2: Install Required Packages

We’ll use Express.js, a popular Node.js framework.

npm install express

Optional (for auto restart):

npm install nodemon --save-dev


Step 3: Create the Server File

Create a file named index.js:

const express = require('express');
const app = express();

app.use(express.json());

const PORT = 3000;

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Run the server:

node index.js

Visit 👉 http://localhost:3000


Step 4: Create Your First API Route

Add a GET API:

app.get('/', (req, res) => {
  res.json({ message: 'Welcome to my first REST API!' });
});

Now open the browser:

http://localhost:3000/

You’ll see JSON output


Step 5: Create a GET API (Fetch Data)

Let’s return a list of users:

app.get('/users', (req, res) => {
  const users = [
    { id: 1, name: 'John' },
    { id: 2, name: 'Sara' }
  ];
  res.json(users);
});

URL:

GET /users


Step 6: Create a POST API (Add Data)

app.post('/users', (req, res) => {
  const user = req.body;
  res.status(201).json({
    message: 'User created',
    user
  });
});

Test using Postman or Thunder Client:

POST /users
{
  "name": "Alex"
}


Step 7: Create PUT API (Update Data)

app.put('/users/:id', (req, res) => {
  res.json({
    message: `User ${req.params.id} updated`
  });
});


Step 8: Create DELETE API

app.delete('/users/:id', (req, res) => {
  res.json({
    message: `User ${req.params.id} deleted`
  });
});


Step 9: Test Your API

You can test APIs using:

  • Postman
  • Thunder Client (VS Code extension)
  • curl command

Suggested Project Structure (Beginner)

my-first-api
│
|--- index.js
|--- package.json
|--- node_modules

As your app grows, you can separate routes, controllers, and services.

Best Practices for Node.js REST APIs

  • Use environment variables
  • Validate input
  • Use async/await
  • Add logging

Frequently Asked Questions

Is Node.js good for REST APIs?

Yes, Node.js is widely used…

Which framework is best for Node.js REST API?

Express.js is the most popular…

Can beginners learn REST API in Node.js?

Absolutely…

Send Email with Attachment File from Lambda (Nodejs)

You can create a lambda (nodejs) with the following code (written in typescript) to send an email to a user with a file attachment.

In the below example, we are first getting the content from S3 bucket, then creating a csv and sending it to a user (SES verified user).

import {
    S3Client,
    GetObjectCommand
  } from "@aws-sdk/client-s3";
  import { SESClient, SendRawEmailCommand } from "@aws-sdk/client-ses";
  import { Readable } from "stream";
  const s3Client = new S3Client({ region: "ap-southeast-2" });
  const sesClient = new SESClient({ region: "ap-southeast-2" });


  export const sendEmail = async () => {
    const senderEmail = process.env.SENDER_EMAIL_ADDRESS;
    const recipientEmail: any = process.env.RECIEVER_EMAIL_ADRESS;
    const subject = "SUBJECT here";
    const bodyText =
      "Hello,\r\n\nPlease see the attached csv file \n\nThanks";
  
    const getObjectCommand = new GetObjectCommand({
      Bucket: process.env.BUCKET,
      Key: process.env.BUCKET_KEY,
    });
  
    const attachmentData = await s3Client.send(getObjectCommand);
    const attachmentBuffer = await streamToBuffer(
      attachmentData.Body as Readable
    );
  
    const attachmentBase64 = attachmentBuffer.toString("base64");
  
    const emailData =
      `From: ${senderEmail}\r\n` +
      `To: ${recipientEmail}\r\n` +
      `Subject: ${subject}\r\n` +
      `MIME-Version: 1.0\r\n` +
      `Content-Type: multipart/mixed; boundary="boundary"\r\n\r\n` +
      `--boundary\r\n` +
      `Content-Type: text/plain; charset=utf-8\r\n` +
      `${bodyText}\r\n\r\n` +
      `--boundary\r\n` +
      `Content-Type: application/octet-stream\r\n` +
      `Content-Disposition: attachment; filename="file.csv"\r\n` +
      `Content-Transfer-Encoding: base64\r\n\r\n` +
      `${attachmentBase64}\r\n\r\n` +
      `--boundary--`;
  
    const sendRawEmailCommand = new SendRawEmailCommand({
      RawMessage: {
        Data: Buffer.from(emailData),
      },
      Source: senderEmail,
      Destinations: [recipientEmail],
    });
  
    const result = await sesClient.send(sendRawEmailCommand);
    return result.MessageId;
  }

  async function streamToBuffer(stream: Readable): Promise<Buffer> {
    return new Promise((resolve, reject) => {
      const chunks: Uint8Array[] = [];
      stream.on("data", (chunk) => chunks.push(chunk));
      stream.on("end", () => resolve(Buffer.concat(chunks)));
      stream.on("error", reject);
    });
  }

Convert PHP script to JavaScript

Convert PHP script to JavaScript

  • Add the “base-reality/php-to-javascript”: “>=0.0.3” to your project’s composer.json file:

    “require”:{ “base-reality/php-to-javascript”: “0.1.16” }

    Or the latest tagged version. The dev master should only be used for development, not production.\
  • Include the Composer SPL autoload file in your project: require_once(‘../vendor/autoload.php’);

    Call the converter:
 $phpToJavascript = new PHPToJavascript\PHPToJavascript();
   $phpToJavascript->addFromFile($inputFilename); $jsOutput =
   $phpToJavascript->toJavascript();

$jsOutput will now contain an auto-generated Javascript version of the PHP source file.

Interested in Cryptocurrency. Register and start investing here

Earn a side income by affiliate marketing. Learn here how to do it.

Join now – Affiliate Program

Countdown timer in Javascript

Code to create a timer till a specific datetime.

Below is the code to create a timer till a specific datetime.

For this sample, the deadline is 5/16/2021 11:26:00

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script language="javascript">

     function getTimeRemaining(endtime) {
      var d = new Date();
      var t = endtime.getTime() - d.getTime(); 

      var seconds = Math.floor((t / 1000) % 60);
      var minutes = Math.floor((t / 1000 / 60) % 60);
      var hours = Math.floor((t / (1000 * 60 * 60)) % 24);
      var days = Math.floor(t / (1000 * 60 * 60 * 24));
      return {
        'total': t,
        'days': days,
        'hours': hours,
        'minutes': minutes,
        'seconds': seconds
      };
     }

   function initializeCountdown(id, endtime) {
    var clock = document.getElementById(id); 
    var daysSpan = clock.querySelector('.days');
    var hoursSpan = clock.querySelector('.hours');
    var minutesSpan = clock.querySelector('.minutes');
    var secondsSpan = clock.querySelector('.seconds');

   function updateTimer() {
        var t = getTimeRemaining(endtime);
       
        daysSpan.innerHTML = t.days;
        hoursSpan.innerHTML = ('0' + t.hours).slice(-2);
        minutesSpan.innerHTML = ('0' + t.minutes).slice(-2);
        secondsSpan.innerHTML = ('0' + t.seconds).slice(-2);

        if (t.total <= 0) {
            clearInterval(timeinterval);
        }
     }
     updateTimer();

     var timeinterval = setInterval(updateTimer, 1000);
    }

    window.onload = function () {
     var deadline = new Date("5/16/2021 11:26:00"); // The datetime of the 
     deadline
     initializeCountdown('clockdiv', deadline);
  }
</script>
</head>

<body>
<form id="form1" runat="server">
   
<div id="clockdiv">
  <div style="float:left;">
    <span class="days"></span>
    <div>Days</div>
  </div>
  <div style="float:left;">
    <span class="hours"></span>
    <div>Hours</div>
  </div>
  <div style="float:left;">
    <span class="minutes"></span>
    <div>Minutes</div>
  </div>
  <div style="float:left;">
    <span class="seconds"></span>
    <div>Seconds</div>
  </div>
</div>
</form>
</body>
</html>

Output –

Interested in Cryptocurrency. Register and start investing here

Earn a side income by affiliate marketing. Learn here how to do it.

ECMAScript 2018 (ES9)

ES9 provides syntactic support for asynchronous iteration – synchronous iterators and asynchronous iterables, which is just like regular iterators, except that they have a next() method that returns in Promise.

The feature set of ES9 has been set by TC39 committee. Checkout the new release process here. It is basically a 5 stage process starting with Stage 0.

Stage 0: Strawman (draft proposal after brainstorming)

Stage 1: Proposal (Make the case for the solution and identify the potential challenges)

Stage 2: Draft (Describe the syntax and semantics)

Stage 3: Candidate (Indicates that further work require users feedback)

Stage 4: Finished (The edition is ready to be included in the formal ECMAScript standard)

So, whats new in ES9 –

1. Asynchronous Iteration –

Finally!!! Its there !!!

We can use await on loops.

ES9 provides syntactic support for asynchronous iteration – synchronous iterators and asynchronous iterables, which is just like regular iterators, except that they have a next() method that returns in Promise. Have a look at the detailed proposal here

for await (const l of readLines(path)) { console.log(l); }

     

2. Promise.prototype.finally –

Execution of callback functions become easy with Promise. A Promise chain can either succeed or fell into a catch exception block. Sometimes, we want to run the code regardless of the output.

With ES9, we can use finally() block that allows to add the final logic at one place regardless of the outcome.

Have a look at the detailed proposal here

function doSomething() { 
method1() 
.then(method2)
.catch(er) { console.log(er); })
.finally(() =>{ // final logic here }); } 

     

3. Regex Changes –

In total, there were 4 RegExp changes –

  • s (dotAll) flag for regular expressions –

    ES9 introduces the use of s flag which match any character, including line terminators. Have a look the the detailed proposal here

 /hello.es9/s.test('hello\nes9');// true 
  • RegExp named capture groups –

    Another great feature we are getting with ES9 as it improves readability and maintainability. Detailed proposal can be viewed here

 
const pattern = /(?\d{4})-(?\d{2})-(?\d{2})/u; 
const result = pattern.exec('2018-06-25'); 
// → result.groups.year === '2018' 
// → result.groups.month === '06' 
// → result.groups.day === '25' 
  • RegExp Look behind Assertions –

Assertions are regular expressions that either are true or false based on the match found. ECMAScript currently have lookahead assertions that do this in forward direction. ES9 comes with an extension to lookbehind, both positive and negative. Detailed proposal can be viewed here

Positive lookbehind make sure that the pattern is always preceded by another pattern:

 
const pattern = /(?=\$)\d+/u; 
const result = pattern.exec('$45'); 
// result[0] === '45' 

Negative lookbehind make sure that the pattern is not preceded by another pattern:


const pattern = /(?lt;!\$)\d+/u;
const result = pattern.exec('$45');
// → result[0] === '45'

  • RegExp Unicode Property Escapes

This feature enables us to access the Unicode character properties natively in ECMAScript regular expressions as before the developers have to depend on other libraries which adds up to the run time dependency cost. Detailed proposal can be viewed here


/\p{Script=Greek}/u.test('μ') // prints true

4. Rest/Spread Properties –

The three-dot operator (…) was introduced with ECMA2015 and has been used for array literals. ES2018 introduces rest/spread feature for object destructuring as well as arrays. Detailed proposal can be viewed here


const values = {a: 5, b: 6, c: 7, d: 8};
const {a, ...n} = values;
console.log(a); // prints 5
console.log(n); // prints {b: 6, c: 7, d: 8}

This was all about ES9.

Let’s see what they will come up with the next version.