How to Create a Simple REST API With JSON Responses

Learn how to build a simple REST API that returns JSON responses using Node.js and Express. This step-by-step guide walks you through project setup, creating routes, handling different HTTP methods, and testing your endpoints—perfect for beginners diving into API development.

6 minutes ago   •   8 min read

By Savan Kharod
Table of contents

APIs are fundamental tools that allow diverse systems to interact and exchange data reliably. REST APIs, built upon HTTP standards, enable developers to create backend services that are both practical and maintainable. JSON, known for its concise and structured format, has become the preferred choice for data interchange. 

In this post, you'll learn how to build a simple REST API with JSON responses, covering essential steps from project setup to dynamic endpoint creation. This guide is designed to provide you with clear, actionable insights to enhance your development workflow.

What is a REST API?

A REST (Representational State Transfer) API is an architectural style that uses HTTP requests to perform CRUD (Create, Read, Update, Delete) operations on resources. These resources are often represented in JSON format.

Why JSON?

JSON (JavaScript Object Notation) has become the standard response format due to its simplicity, readability, and compatibility with many languages and frameworks. It is lightweight and allows developers to exchange data easily between the server and the client.

💡
Want to go beyond the basics? Treblle gives you real-time API insights, auto-generated docs, and tools to spot issues fast—so you can focus on building, not debugging.

Prerequisites

Before you begin, ensure that you have the following tools and knowledge:

  • Basic Coding Experience: Familiarity with JavaScript (or Python if you prefer a different framework) is recommended to grasp the concepts and code examples.
  • Development Environment Setup:
    • Node.js: Install Node.js to execute the server-side code.
    • (Optional) Python: If you prefer Python, ensure it is installed along with a framework like Flask.
  • Command-Line Interface: Basic competence in using the terminal or command prompt for running commands and managing your project.
  • Code Editor: Use a text editor or an Integrated Development Environment (IDE), such as Visual Studio Code, Sublime Text, or a similar tool.

These prerequisites ensure that you will be ready to quickly set up and run your REST API project without unnecessary delays.

Set Up Your Project

In this section, I will explain how to prepare your project for building a REST API. The steps include creating a project directory, initializing your configuration, and installing the necessary dependencies. Below are detailed instructions for both Node.js with Express and Python with Flask.

For Node.js (Using Express)

Create a Project Directory: Open your terminal and create a new folder for your project. This keeps your API files organized.

1. Initialize the Project with NPM: Use npm init -y to initialize your project with default settings. This command generates a package.json file that manages your project’s metadata and dependencies.

mkdir simple-rest-api
cd simple-rest-api

2. The package.json file is crucial—it keeps track of your project’s configuration, version, and any packages you install.

  1. Install Express: Express is a minimal and flexible Node.js web application framework that simplifies the creation of APIs. Install it using npm:
npm install express
  1.  After installation, Express will appear in your package.json under dependencies, making it easier to manage and deploy your project.

For Python (Using Flask)

  1. Create a Project Directory: Similarly, create a new folder for your Flask project.
mkdir simple-rest-api
cd simple-rest-api
  1. Set Up a Virtual Environment: It’s best practice to isolate project dependencies using a virtual environment. Create and activate one using:
python -m venv venv

On macOS/Linux:

source venv/bin/activate

On Windows:

venv\Scripts\activate
  1. Install Flask: With your virtual environment activated, install Flask using pip:
pip install Flask

Flask is a lightweight web framework ideal for creating REST APIs. Installing it in a virtual environment ensures that your project’s dependencies remain contained and manageable.

Whether you choose Node.js with Express or Python with Flask, the steps to set up your project involve:

  • Creating a dedicated project directory.
  • Initializing the project environment (using npm init for Node.js or a virtual environment for Python).
  • Installing the core framework (Express or Flask) to build your API.

These steps lay the foundation for building and scaling your REST API, ensuring a clean, organized environment as you progress to writing server code and defining endpoints.

Create a Basic Server

To start building your REST API, the next step is to create a simple web server. Below is an example using Node.js with the Express framework. This server listens on a designated port and includes a basic “Hello World” route to confirm that your setup works.

Example Code: Basic Server with Express

Create a file named server.js and include the following code:

// server.js

// Import the Express module
const express = require('express');
// Initialize an Express application
const app = express();
// Add middleware to parse JSON request bodies
app.use(express.json());
// Define the port; it uses the PORT environment variable if set or defaults to 3000
const PORT = process.env.PORT || 3000;

// Create a default route that responds with a simple greeting
app.get('/', (req, res) => {
  res.send('Hello World from your API!');
});

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

Explanation of Key Components

  • Importing Express: The express module is required to leverage Express’s functionality. Initializing app prepares your application to handle HTTP requests.
  • Port Definition: The server listens on a port defined by an environment variable (valid in production) or defaults to port 3000 for development.
  • Hello World Route: The app.get() method sets up a GET request handler at the root URL ("/"). Accessing this route responds with a simple text message confirming that your server is up.
  • Starting the Server: The app.listen() function initiates the server and listens for incoming HTTP requests. Once the server is running, a confirmation message is logged to the console.

This basic server setup provides a solid foundation for adding more complex API endpoints and features as you build your REST API.

Define a Simple API Endpoint

Below is a minimal example showing how to wire up a GET endpoint in Express that returns structured JSON data, using app.get() for routing and res.json() to automatically set the Content-Type header to application/json

This basic pattern establishes a clear convention you can extend across POST, PUT, DELETE, and PATCH routes, ensuring consistency in how your API handles and delivers JSON payloads. 

Example Code: Simple API Endpoints

Add the following code to your existing server.js file to support all primary REST methods with JSON responses:

// Enable JSON body parsing
app.use(express.json());

// GET /api/greeting
app.get('/api/greeting', (req, res) => {
  res.json({ message: 'Hello from your API!' });
});

// POST /api/greeting
app.post('/api/greeting', (req, res) => {
  const { name } = req.body;
  res.json({
    message: `Hello, ${name || 'Guest'}! This greeting was created via POST.`
  });
});

// PUT /api/user/:id
app.put('/api/user/:id', (req, res) => {
  const userId = req.params.id;
  const updates = req.body;
  res.json({
    userId,
    updatedWith: updates,
    message: `User ${userId} has been updated via PUT.`
  });
});

// DELETE /api/user/:id
app.delete('/api/user/:id', (req, res) => {
  const userId = req.params.id;
  res.json({
    userId,
    message: `User ${userId} has been deleted via DELETE.`
  });
});

// PATCH /api/user/:id
app.patch('/api/user/:id', (req, res) => {
  const userId = req.params.id;
  const partial = req.body;
  res.json({
    userId,
    patchedWith: partial,
    message: `User ${userId} has been partially updated via PATCH.`
  });
});

Citations:

  • JSON parsing middleware (app.use(express.json())) enables handling of POST, PUT, and PATCH requests with JSON bodies citeturn2view0
  • res.json() for sending JSON responses citeturn0search0
  • POST handling example sourced from a practical Node.js guide citeturn0search18
  • DELETE route pattern demonstrated by GeeksforGeeks citeturn0search1
  • PATCH implementation reference from a community tutorial citeturn0search2

Add Another Route With Parameters

You can create endpoints that handle dynamic inputs to expand the functionality of your API. In this section, you'll learn how to add a route that accepts parameters, allowing your API to respond with customized data based on user input.

Example Code: Dynamic Route with Parameters

Add the following code to your existing server.js file:

// Define a route with a dynamic parameter for user details
app.get('/api/user/:id', (req, res) => {
  const userId = req.params.id;
  // In a real-world application, you'd fetch user details from a database here.
  res.json({ userId: userId, message: `User with ID ${userId} found.` });
});

Breakdown of the Code

  • Route Definition with a Parameter: The endpoint /api/user/:id uses a colon (:) to define a dynamic segment. Here, id acts as a placeholder that Express extracts from the URL.
  • Accessing the Parameter: The value provided in the URL is accessible via req.params.id. This enables the API to tailor its response according to the user's input.
  • Returning Dynamic JSON: The res.json() method returns a JSON object that includes the extracted parameter. This example sends a message confirming the user ID, mimicking how a real application might return a user's details.

By incorporating dynamic parameters into your routes, you can create more responsive and versatile APIs that cater to varied client requests. This approach lays the groundwork for handling more complex data-fetching operations, such as querying a database for user-specific details.

Test Your API

Verifying that your API endpoints function as expected is a crucial step in the development process. Here are several methods you can use to test your API:

1. Using a Browser

  • Simple Testing: Navigate to your API endpoint URL in a web browser. For example, if your API is running locally on port 3000, enter:
http://localhost:3000/api/greeting

The browser should display the JSON response:

{ "message": "Hello from your API!" }
  • Parameter-Based Testing: You can also test dynamic routes by entering a URL such as:
http://localhost:3000/api/user/1

This should display the JSON response with the dynamic parameter included:

{ "userId": "1", "message": "User with ID 1 found." }

2. Using Command-Line Tools

  • cURL: Use the cURL command to simulate HTTP requests from your terminal. For example:
curl http://localhost:3000/api/greeting
  • This command sends a GET request to the specified endpoint and prints the JSON response in the terminal.
  • HTTPie: HTTPie provides a simple, intuitive way to test your API:
http http://localhost:3000/api/user/1
  • It will display the response in a nicely formatted output.

3. API Testing Tools

There are several API testing tools that you can use to test your APIs. Here are the three best tools with a developer-first approach to try: 

  • Aspen: Aspen is our blazing-fast API testing tool built natively for macOS. It's lightweight, powerful, and designed to make API testing effortless. Built with a developer-first mindset, Aspen allows you to test your APIs without requiring a login.
  • Insomnia: Insomnia is another popular API client that lets you test and organize your API endpoints efficiently.
  • HTTPie: A command-line HTTP client that simplifies making and reading HTTP requests. HTTPie is perfect for developers who favor terminal-based interactions for quick tests and automation.

Verifying Response Structure

  • Expected Format: Double-check that your JSON structure matches your API design. For example, the greeting endpoint should return:
{ "message": "Hello from your API!" }

HTTP Status Codes: Ensure the API returns the correct HTTP status code (e.g., 200 for successful GET requests). Some API testing tools display these status codes, allowing you to confirm that the responses are as expected.

By applying these testing methods, you can confidently verify that your API endpoints return the correct data and handle different types of requests properly.

This step helps ensure a smooth and reliable experience when other applications or clients interact with your API.

Conclusion: 

In this tutorial, I explained how to build a simple REST API using Node.js and Express. I covered how to set up your project, create a basic server with a “Hello World” route, and define static and dynamic endpoints that return JSON responses.

Moving forward, consider enhancing your API with the following improvements:

  • Error Handling: Implement robust error responses to help clients understand and troubleshoot issues.
  • Authentication: Add user verification to secure your endpoints and manage access control.  Learn how to get started with JSON Web Tokens (JWTs) for API authentication.
  • Data Validation: Ensure incoming data is verified and sanitized to prevent issues and maintain data integrity.
  • Additional Features: Explore middleware, logging, and performance optimizations to create a more production-ready API.
  • API Intelligence with Treblle: For a comprehensive view of your API’s performance and reliability, consider integrating Treblle. Treblle provides real-time API intelligence, auto-generated documentation, governance, and error tracking, making it easier to identify issues and optimize your API workflow.

By incorporating these enhancements, you will build a more resilient and scalable system, ready for real-world applications. Continue refining your skills and exploring advanced topics to further enhance your API development expertise.

💡
Ready to take your API from basic to brilliant? Treblle helps you track performance, catch errors, and ship with confidence—all in real time.

Spread the word

Keep reading