This article will discuss sending POST requests from Node.js core libraries. The post requests are wrapped in a promise for easy use by consumers. This technique can be performed with not dependency libraries beyond those provided by core Node.js.

This is a follow up to the article sending GET requests.

Sending JSON

The first part will discuss how to send JSON requests. The example uses a method called authenticate that takes two parameters userId and password.

const http = require('http');

function authenticate(userId, password) {
  return new Promise((resolve, reject) => {
    let data = {
      userId,
      password,
    };
    let dataEncoded = JSON.stringify(data);
    let req = http.request(
      {
        host: 'sample.com',
        path: '/api/user',
        method: 'POST',
        headers: {
          'Content-Length': Buffer.byteLength(dataEncoded),
          'Content-Type': 'application/json',
        },
      },
      res => {
        let buffers = [];
        res.on('error', reject);
        res.on('data', buffer => buffers.push(buffer));
        res.on(
          'end',
          () =>
            res.statusCode === 200
              ? resolve(Buffer.concat(buffers))
              : reject(Buffer.concat(buffers))
        );
      }
    );
    req.write(dataEncoded);
    req.end();
  });
}

This example first constructs a plain old JavaScript object with two properties: userId and password, which is then converted into a JSON string via JSON.stringify. The result of this operation will be used to pass in the content-length header and will be written to the request stream to be sent to the remote server.

The request is constructed and two headers are provided. We use the Buffer.byteLength method to calculate the length of the json data and supply that as content-length. We also specify the content-type header as application/json.

The last step is writing the JSON string to the request stream that is sent to the server. Once this is done, the request can be ended and the server will begin the response.

The response is handled by performing buffer concatenation the same way we did with GET requests. Here each data event is added to an array. Once the end event is called, the buffers are combined via Buffer.concat and the promise is resolved or rejected depending on the status code of the response.

Sending form data

Form data is very similar to JSON data. The only exceptions are how the data is constructed and the content type.

x-www-form-urlencoded

const http = require('http');
const qs = require('querystring');

function authenticate(userId, password) {
  return new Promise((resolve, reject) => {
    let data = {
      userId,
      password,
    };
    let dataEncoded = qs.stringify(data);
    let req = http.request(
      {
        host: 'sample.com',
        path: '/api/user',
        method: 'POST',
        headers: {
          'Content-Length': Buffer.byteLength(dataEncoded),
          'Content-Type': 'application/x-www-form-urlencoded',
        },
      },
      res => {
        let buffers = [];
        res.on('error', reject);
        res.on('data', buffer => buffers.push(buffer));
        res.on(
          'end',
          () =>
            res.statusCode === 200
              ? resolve(Buffer.concat(buffers).toString())
              : reject(Buffer.concat(buffers).toString())
        );
      }
    );
    req.on('error', reject);
    req.write(dataEncoded);
    req.end();
  });
}

As you can see, this is functionally the same. Instead of using JSON.stringify, qs.stringify is used to encode the information.

Hopefully this article has helped shed some light on how you can use Node.js core libraries to perform basic HTTP requests.