Build a Simple REST API Client in Node.js Without Frameworks
Introduction
Building a lightweight REST API client in Node.js can be surprisingly simple without relying on heavy frameworks or third-party libraries. Whether you’re testing APIs, automating data collection, or just experimenting with web services, Node.js provides all the tools you need with its native fetch() support (introduced in Node 18+). In this tutorial, we’ll explore how to create a small but powerful command-line script that performs GET and POST requests to public APIs and processes live JSON responses.
1. Setting Up the Project
Let’s begin by creating a new Node.js project. You’ll need Node.js version 18 or higher since we’ll be using the built-in fetch() API.
mkdir node-rest-client
cd node-rest-client
npm init -y
We now have a minimal project setup. Since we’re avoiding frameworks, we won’t install Express or any other server library. Our focus is on making HTTP requests directly from the CLI.
2. Making a Simple GET Request
To fetch data from a public API, create a file named client.js and use Node’s global fetch() function. For example, we can use the JSONPlaceholder API, a free mock service for testing.
const fetch = global.fetch;
async function getPost(id) {
const url = `https://jsonplaceholder.typicode.com/posts/${id}`;
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
const data = await response.json();
console.log('Fetched post:', data);
} catch (err) {
console.error('Error fetching post:', err.message);
}
}
getPost(1);
This simple function fetches a single post and prints it to the console. The key points here are error handling (using try/catch) and checking response.ok. Even without frameworks, these patterns ensure robust API interactions.
3. Sending a POST Request with JSON Data
Now let’s send data to an API endpoint. With the same JSONPlaceholder API, you can simulate resource creation using a POST request.
async function createPost(postData) {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(postData),
});
const data = await response.json();
console.log('Created post:', data);
} catch (err) {
console.error('Error creating post:', err.message);
}
}
createPost({ title: 'Simple API Client', body: 'Learning Node.js without frameworks', userId: 1 });
This shows how easy it is to send structured data to an API. The fetch() API automatically handles request dispatching and response parsing. You just need to specify headers and convert the payload with JSON.stringify().
4. Processing Live JSON and Integrating CLI Args
Let’s make this script reusable by allowing users to pass input from the command line. We’ll use process.argv to capture command-line arguments.
const args = process.argv.slice(2);
const [command, param] = args;
if (command === 'get') {
getPost(param || 1);
} else if (command === 'create') {
createPost({ title: 'CLI Created Post', body: 'Created via CLI script', userId: 99 });
} else {
console.log('Usage: node client.js get [id] | create');
}
This simple control logic turns our script into a micro CLI tool. Developers can now run node client.js get 5 or node client.js create to interact with the remote API effortlessly.
5. Performance and Optimization Tips
Even though this script is small, a few optimization techniques can make it more resilient and faster:
- Use
Promise.all()when making multiple API requests simultaneously to reduce wait time. - Cache responses for frequently requested endpoints using a simple in-memory map.
- Implement exponential backoff or retries for unstable endpoints.
- Prefer streaming large payloads with
response.bodyandReadableStreamin Node 18+.
async function fetchMultiplePosts(ids) {
const requests = ids.map(id => fetch(`https://jsonplaceholder.typicode.com/posts/${id}`));
const responses = await Promise.all(requests);
const jsonResults = await Promise.all(responses.map(r => r.json()));
console.log('Multiple posts:', jsonResults);
}
fetchMultiplePosts([1, 2, 3]);
Using bulk requests and parallelization, you can turn this simple Node.js script into a high-performance automation tool for testing, data gathering, or monitoring APIs.
Conclusion
With just a few lines of code, you’ve built a versatile REST API client in Node.js. No frameworks, no overhead — just clean, readable JavaScript. This technique is perfect for rapid prototyping, API exploration, and automation workflows. From here, you can extend this tool with features like environment configs, response timing analysis, logging, or authentication for more complex use cases.
Useful links:

