Skip to content

Instantly share code, notes, and snippets.

@tatsuyasusukida
Last active May 22, 2022 22:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tatsuyasusukida/da9a3376de13e0d59f16a3c231d3c171 to your computer and use it in GitHub Desktop.
Save tatsuyasusukida/da9a3376de13e0d59f16a3c231d3c171 to your computer and use it in GitHub Desktop.
📤 How to send HTTP requests in Node.js using only the standard library [video version available]

📤 How to send HTTP requests in Node.js using only the standard library [video version available]

Video thumbnail: How to send HTTP requests in Node.js using only the standard library

About this article

This article describes how to send an HTTP request using http, the standard library of Node.js, with methods and headers specified. We will use Express to create a server that sends back information about HTTP requests received to confirm that it works. The related resources of this article are shown below.

Workflow

The workflow is as follows.

  1. Coding preparation
  2. Coding
  3. Operation check

Coding preparation

Run the following commands in the terminal to prepare for coding.

mkdir nodejs-http-request
cd nodejs-http-request
npm init -y
npm install --save express
touch server.js client.js

Coding

server.js

Open server.js in the editor and enter the following content.

click to go to server.js

client.js

Open client.js in the editor and enter the following content.

Click to go to client.js

The key points are shown below.

  1. Create an HTTP request using the http.request function.
  2. Register Promise's resolve for HTTP request's response event.
  3. Register Promise's reject for HTTP request's error event.
  4. Write the HTTP request body using the write method of HTTP request.
  5. Complete HTTP request using the end method of HTTP request.
  6. Register event handlers for the three events: data, end, and error of the HTTP response. For the data event, add the chunk of the HTTP response body fragment to the end of the chunks list.
  7. For the end event, call Promise's resolve function with the chunks list.
  8. For the error event, call Promise's reject function.
  9. Call Buffer.concat function to combine the HTTP response body fragments.

Operation check

Run the following command in a terminal to start the server.

node server.js

Start a new terminal and then run the following command to send an HTTP request.

node client.js

Verify that the execution result matches the following.

{
  "method": "POST",
  "url": "/pathname?query=1",
  "query": {
    "query": "1"
  },
  "headers": {
    "content-type": "text/plain",
    "content-length": "7",
    "x-header": "X-Header",
    "host": "localhost:3000",
    "connection": "close"
  },
  "body": "content"
}

Conclusion

When sending HTTP requests in Node.js, I use node-fetch, which is easy to use because a process that would take about 40 lines with the standard library can be completed in a few lines with fetch. There are many situations where we want to send HTTP requests from Node.js, such as when obtaining OAuth 2.0 access tokens or when conducting API tests. I don't know much about this because I've never done it before, but do people also use HTTP requests for communication between services in a microservice architecture? (And I don't know much about it, but do they use gRPC or something like that?)

I can't imagine what the situation is like, but I hope this article is useful for those who want to send HTTP requests in Node.js without using npm packages such as node-fetch. Thank you for reading!

/node_modules/
/package-lock.json
# Do not ignore package-lock.json other than gist.
const http = require('http')
if (require.main === module) {
main()
}
async function main () {
try {
const res = await new Promise((resolve, reject) => {
try {
const port = process.env.PORT || '3000'
const url = `http://localhost:${port}/pathname?query=1`
const content = "content"
const req = http.request(url, { // <1>
method: 'POST',
headers: {
'Content-Type': 'text/plain',
'Content-Length': '' + content.length,
'X-Header': 'X-Header',
},
})
req.on('response', resolve) // <2>
req.on('error', reject) // <3>
req.write(content) // <4>
req.end() // <5>
} catch (err) {
reject(err)
}
})
const chunks = await new Promise((resolve, reject) => {
try {
const chunks = []
res.on('data', (chunk) => chunks.push(chunk)) // <6>
res.on('end', () => resolve(chunks)) // <7>
res.on('error', reject) // <8>
} catch (err) {
reject(err)
}
})
const buffer = Buffer.concat(chunks) // <9>
const body = JSON.parse(buffer)
console.info(JSON.stringify(body, null, 2))
} catch (err) {
console.error(err)
}
}
{
"name": "nodejs-http-request",
"version": "1.0.0",
"description": "",
"main": "client.js",
"scripts": {
"dev": "node client.js",
"server": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.1"
}
}
const express = require('express')
if (require.main === module) {
main()
}
function main () {
try {
const router = express()
router.use(async (req, res, next) => {
try {
const chunks = await new Promise((resolve, reject) => {
const chunks = []
req.on('data', (chunk) => chunks.push(chunk))
req.on('end', () => resolve(chunks))
req.on('error', reject)
})
const buffer = Buffer.concat(chunks)
res.send({
method: req.method,
url: req.originalUrl,
query: req.query,
headers: req.headers,
body: buffer.toString(),
})
} catch (err) {
next(err)
}
})
const port = parseInt(process.env.PORT || '3000', 10)
router.listen(port, () => {
console.info(`Listening on ${port}`)
})
} catch (err) {
console.error(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment