Node.js Native HTTP Request: Get & Post
In this article, we’ll explore how to perform GET and POST requests using Node.js’s native http
module, with practical examples leveraging the JSONPlaceholder API, a free online REST API for testing and prototyping.
Why It Matters
Using Node.js’s native http
module for HTTP requests is valuable because:
- No external dependencies: Keeps your project lightweight.
- Educational value: Deepens understanding of how HTTP requests work under the hood.
- Control: Fine-grained control over request options and handling.
While higher-level libraries simplify common tasks, knowing how to use the core modules ensures you understand the fundamentals and can troubleshoot issues effectively.
Core Concepts
The http
Module
Node.js’s http
module provides methods to create HTTP clients and servers. For client-side requests, it offers the http.request()
method, which allows you to craft detailed requests, including method, headers, and payloads.
Key Components
- Request options: Host, port, path, method, headers.
- Request object: Writable stream to send data.
- Response object: Readable stream to receive data.
Code Walkthrough
Let’s walk through examples of GET and POST requests with detailed inline comments.
1. Performing a GET Request
We’ll fetch a list of posts from JSONPlaceholder.
const http = require('http');
// Define the options for the GET request
const options = {
hostname: 'jsonplaceholder.typicode.com', // API host
port: 80, // Default HTTP port
path: '/posts', // API endpoint
method: 'GET', // HTTP method
headers: {
'Content-Type': 'application/json' // Expect JSON response
}
};
// Make the GET request
const req = http.request(options, (res) => {
let data = '';
// Concatenate chunks of data as they arrive
res.on('data', (chunk) => {
data += chunk;
});
// When the response ends, parse and log the data
res.on('end', () => {
try {
const posts = JSON.parse(data);
console.log('Fetched posts:', posts);
} catch (error) {
console.error('Error parsing JSON:', error);
}
});
});
// Handle request errors
req.on('error', (error) => {
console.error('Request error:', error);
});
// End the request (for GET, no body is sent)
req.end();
Note: For HTTPS requests, you’d use the https
module instead.
2. Performing a POST Request
Suppose we want to create a new post.
const http = require('http');
// Data to send in the POST request
const postData = JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
});
// Define request options
const options = {
hostname: 'jsonplaceholder.typicode.com',
port: 80,
path: '/posts',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(postData) // Required for POST
}
};
// Make the POST request
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
try {
const responsePost = JSON.parse(data);
console.log('Response from POST:', responsePost);
} catch (error) {
console.error('Error parsing response JSON:', error);
}
});
});
req.on('error', (error) => {
console.error('Request error:', error);
});
// Write data to request body
req.write(postData);
// End request
req.end();
Common Mistakes
- Forgetting to call
req.end()
: The request won’t be sent without ending the request. - Incorrect headers or
Content-Length
: Omitting or mismatching headers can cause server errors. - Using the wrong module for HTTPS: For secure requests, use
https
instead ofhttp
. - Not handling asynchronous responses properly: Always listen to
'data'
and'end'
events to process responses. - Assuming JSON response without parsing: Always parse the response data to utilize it effectively.
Best Practices
- Use Promises or async/await: Encapsulate requests in functions returning Promises for cleaner asynchronous code.
- Handle errors gracefully: Always listen for
'error'
events. - Use
https
module for secure endpoints: JSONPlaceholder can be accessed via HTTPS (https://jsonplaceholder.typicode.com
). - Set appropriate headers: Especially
Content-Type
andContent-Length
for POST/PUT requests. - Abstract repetitive code: Create reusable functions for GET and POST requests.
Here’s a quick example of wrapping GET requests in a Promise:
const http = require('http');
function httpGet(hostname, path) {
return new Promise((resolve, reject) => {
const options = {
hostname,
port: 80,
path,
method: 'GET',
headers: { 'Accept': 'application/json' }
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => (data += chunk));
res.on('end', () => {
try {
resolve(JSON.parse(data));
} catch (err) {
reject(err);
}
});
});
req.on('error', reject);
req.end();
});
}
// Usage
httpGet('jsonplaceholder.typicode.com', '/posts')
.then(posts => console.log(posts))
.catch(error => console.error(error));
Final Thoughts
While third-party libraries like Axios or node-fetch
simplify HTTP requests, mastering Node.js’s native http
module provides you with a solid understanding of HTTP communication and greater control over your requests. With examples above, you can now confidently perform GET and POST requests in your Node.js applications, whether you’re building APIs, integrating services, or learning the fundamentals.
Remember: Always handle errors, set proper headers, and close your requests properly to ensure robust and reliable network communication.
References
- Node.js
http
module documentation - MDN Web Docs on HTTP
- JSONPlaceholder API
- Using Promises with Node.js HTTP requests
Happy coding!