How to create a REST API with NodeJS



As a MuleSoft architect, having a lightweight, easily deployable non-mule REST API for testing is essential when working with 
Flex Gateway and API management scenarios. Whether we're demonstrating API governance, security policies, or traffic control, a simple Node.js-based API can serve as a reliable backend for our tests. 

In this post, I'll walk you through setting up a minimal Node.js REST API using Express.js, ensuring you can quickly spin up an endpoint for demos, sandbox environments, and integration tests. This API will be designed for ease of use, requiring minimal dependencies while being flexible enough to support real-world API management use cases. 


Prerequisites - Install NodeJS and NPM

On Mac:

To install NodeJS and NPM on Mac, the easiest way to do it is via Homebrew.
For that, Open a Terminal and follow these steps

Install Homebrew (if not installed):

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

Install Node.js and npm:

brew install node

Ve
rify the installation
node -v
npm -v

node js comes with npm bundled but, usually, not with an updated version. To update npm run

npm install npm --global

Ve
rify the updated version of npm

npm -v


On Linux

Here are the steps to install NodeJS and NPM on an Ubuntu Server:

Update the repositories

sudo apt-get update

Add NodeSource repository

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -

Install Node.js:

sudo apt install -y nodejs

Verify installation

node -v
npm -v

After installing Node.js, update
 npm to the latest version:

sudo npm install -g npm@latest

Verify the version:

npm -v

Initialize a Node.js Project

Create a new project directory and initialize a Node.js app:

mkdir hello-nodejs-api
cd hello-nodejs-api
npm init -y


Install Express.js

We’ll use Express.js to build the API. Express.js is a lightweight and fast web framework for Node.js that simplifies building APIs and web applications. It provides easy routing, middleware support, and HTTP request handling.

npm install express


Create the API

Create a file named server.js:

touch server.js

Then, add the following code:

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

const PORT = process.env.PORT || 3000;

// Define the /hello endpoint
app.get("/hello", (req, res) => {
res.json({ message: "Hello World from NodeJS!" });
});

// Start the server
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});


Run the Server and Test the API

Start the server using the command:

node server.js

You should see in your terminal:

Server is running on http://localhost:3000

Now, open a browser and navigate to 
http://localhost:3000 or use Postman or curl

curl http://localhost:3000/hello

We should get a JSON response like this

{ "message": "Hello World from NodeJS!" }


Keep the API Running in the Background

If you close the terminal, the app will stop. In a production environment we should run our API as a system service. For that, we need to create a service file

sudo vi /etc/systemd/system/hello-nodejs.service

Add this content

[Unit]
Description=NodeJS Hello World API
After=network.target

[Service]
User=ubuntu
WorkingDirectory=/home/ubuntu/hello-nodejs-api
ExecStart=/usr/bin/node /home/ubuntu/hello-nodejs-api/server.js
Restart=always

[Install]
WantedBy=multi-user.target

Reload systemd and enable the service

sudo systemctl daemon-reload
sudo systemctl enable hello-nodejs
sudo systemctl start hello-nodejs

Check the status

sudo systemctl status hello-nodejs


Containerize the API

Once we’ve got our NodeJS REST API working, it’s always a great idea to containerize it. For that, let’s use Docker and see how we can create the Docker image for our REST API. 

Create a Dockerfile

Images in Docker are built from Dockerfiles. From the same directory of our REST API, create a file called Dockerfile

touch Dockerfile

Add the following content

# Use official Node.js LTS image
FROM node:18-alpine

# Set working directory
WORKDIR /app

# Copy package.json and package-lock.json first
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy the rest of the application files
COPY . .

# Expose port 3000
EXPOSE 3000

# Start the app
CMD ["node", "server.js"]


Create a .dockerignore File

Exclude unnecessary files:

touch .dockerignore

Add the following content to the file

node_modules
npm-debug.log
Dockerfile
.dockerignore


Build the Docker Image

Now, create the image from our Dockerfile running the following command:

docker build -t hello-nodejs-api .

where 
hello-nodejs-api is the name of the image.


Run the Container

Let’s test our image by running a container from it with the command:

docker run -d -p 3000:3000 hello-nodejs-api

Where:

  • -d: Run the container in detached mode.
  • -p 3000:3000: Map port 3000 of the host to port 3000 of the container.
Now, open http://localhost:3000/hello in your browser or run:

curl http://localhost:3000/hello

You should see again:

{ "message": "Hello World from NodeJS!" }


Tag & Push to Docker Hub

Lastly, let’s make our image available in Docker Hub so that we can download it from any machine. For that, we need to follow these steps:
First, login to our Docker Hub account

docker login -u [YOUR_DOCKERHUB_USERNAME]

Tag the image for Docker Hub

docker tag gon-nodejs-api [YOUR_DOCKERHUB_USERNAME]/hello-nodejs-api

Last step, push the image to Docker Hub:

docker push [YOUR_DOCKERHUB_USERNAME]/hello-nodejs-api

With that we can pull and run this image from any Docker host by running

docker run -p 3000:3000 [YOUR_DOCKERHUB_USERNAME]/hello-nodejs-api

If you find the error "no matching manifest for linux/amd64 in the manifest list entries" that occurs when the Docker image you are trying to pull does not have a build compatible with your system's architecture(e.g., linux/amd64). 

That's probably because the image was built for a different architecture, most likely because the docker host where you build the image has a different architecture from the one you're trying to run the container. It happened to me when I built the image in my Mac and then try to deploy it on a Linux server.

Try rebuilding your image with multi-platform support:

docker buildx build --platform linux/amd64 -t [YOUR_DOCKERHUB_USERNAME]/hello-nodejs-api:latest .
docker push [YOUR_DOCKERHUB_USERNAME]/hello-nodejs-api:latest

Previous Post Next Post