What can we help you with?

If you are interested in finding out more about how we can help your organization, please provide your details and project requirements. We'll get back to you soon.

NodeJS 10.0 – Getting even better

NodeJS

NodeJS community has recently released the newest version of Node, which is 10.0. This version will become a Long-Term-Support line in October 2018 and LTS line will be supported till 2021. This version of NodeJS development is given a codename of Dubnium. NodeJS developers have been eagerly waiting for the LTS release due to improved support for HTTP/2 module, effective error handling, filesystem module with promises and many more. In this article, we will see the major updates of this release.

Improved Native HTTP/2 module

With HTTP, loading a web page is intensive because it supports only one request/TCP connection. HTTP/2 was initially introduced in NodeJs v8.4 (LTS) to provide higher performance than HTTP. Http2 has been redeveloped to allow the browser to multiplex requests, minimize protocol overhead, and add support for request prioritization and server push. Though there have been many new features added, it does not modify the application semantics of HTTP keeping status codes, header fields, URIs all remain in place. That means no need to change existing applications.

Request response multiplexing:

If the client wants to make multiple requests in parallel then he needs to create multiple TCP connections and only one response can be delivered at a time. This results in inefficient use of TCP connection.

HTTP/2 on the other hand, allows the client and the server to divide HTTP message into independent frames, interleave them and again reassemble them on another end thus removes the limitation of one response at a time. This helps to make the application faster and simpler by eliminating the need for multiple connections.

Stream prioritization:

With HTTP/2, the message can be divided into streams and to achieve prioritization it allows the stream to have dependency and weight associated with that stream.

  • Each stream can have a weight assigned between 1 and 256.
  • Each stream may have the dependency on another stream.
  • Based on the given instruction and making effective use of CPU allocation, bandwidth etc. it ensures the optimal delivery of high priority response to the client.

Server push:

HTTP2 facilitates server to send multiple responses to a single client request. The server can push an additional resource to the client without the client need to request each one. Server push is initiated via the PUSH_PROMISE frame. The client can have full control of the use of server push.

Creating client/server using HTTP2

http2.createServer or http2.createSecureServer methods can be used to create server using http2. However, Https is necessary otherwise the browser will not be able to connect.

const http2 = require('http2');
const server = http2.createServer();
 
server.on( 'stream', (stream, headers) => {
  stream.respond({'content-type': 'text/html', ':status': 200});
  stream.end('<h1>Hello HTTP2</h1>');
});
server.listen(3000);

Some of the functions have been added in v10.0 are as follows –

  • http2session.connecting
  • Event: wantTrailers
  • http2stream.sendTrailers
  • request.aborted

Below, illustrates the client side example of HTTP2.

const http2 = require('http2');
const fs = require('fs');
const client = http2.connect('https://localhost:8443', {
  ca: fs.readFileSync('localhost-cert.pem')
});
client.on('error', (err) => console.error(err));
 
const req = client.request({ ':path': '/' });
 
req.on('response', (headers, flags) => {
  for (const name in headers) {
    console.log(`${name}: ${headers[name]}`);
  }
});

N-API

NodeJS has module ecosystem including JavaScript and native add-on modules. Native modules are developed in C/C++ with dependency on V8 and NAN APIs resulting lack of API stability, requiring modules to be upgraded or recompile for the major release of NodeJs. Earlier Node.JS API was in experimental mode and it has become stable with the next major release. Stable N-API is independent of V8 and it is maintained as a part of NodeJS. In other words, it allows modules to run against newer versions of Node without the need to recompile.

N-API supports following datatypes.
napi_status
Below are some of the supported status codes indicating success or failure.

typedef enum {
    napi_ok,
    napi_invalid_arg,
    napi_object_expected,
    napi_string_expected,
    napi_name_expected,
    napi_array_expected,
    napi_generic_failure,
    napi_pending_exception,
    napi_cancelled,
 
}
napi_status;
  • napi_env
  • napi_handle_scope
  • napi_escapable_handle_scope
  • napi_get_last_error_info
  • napi_callback
  • napi_fatal_error

Ease of error handling

At present, Node API throws error messages and this makes error management challenging because the code has to check for error message string for a known value to identify what error was thrown. If there is any change in error message by API it may break the code and developer has to wait for the solution until the next major release.

NodeJs team has been working to add error codes thrown by the NodeJS API. This will help to manage error handling effectively as one will not need to compare error messages. Below are some of the new error codes available in the upcoming major release.

ERR_AMBIGUOUS_ARGUMENT, ERR_ASSERTION, ERR_BUFFER_TOO_LARGE,
ERR_CANNOT_WATCH_SIGINT

FS available with promises

before v8 developer had to manually use promise to fs.writeFile function.

return new Promise((resolve, reject) => {
    fs.writeFile('/path/to/file', data, error => {
        if (error) reject(error);
        resolve("file created successfully with handcrafted Promise!");
    });
});

With the latest node version, fs itself returns promise. Take a look at below code snippet.

const fsp = require("fs.promises");
var path = require( "path" );
var project_dir_path = path.resolve( "." );
 
try {
  var return_promise =  fsp.writeFile(project_dir_path+"/tmp/test.txt",'Hello world with Node.js v10 fs.promises!');
 
  console.log("return_promise",return_promise);
 
} catch (error){
    console.error(error);
}

You would observe that return_promise is a type of promise with the warning saying “The fs.promises API is experimental”.

With the new fs Promises API, new class FileHandle has been introduced. The instance of FileHandle will automatically close the file descriptor and will throw a process warning. It does not need to call filehandle.close() method explicitly means there are fewer chances of memory leaks.

Trace Events

With the upcoming LTS version, 10.X of NodeJs it will be easier to quickly diagnose any emerging issue and developer can monitor how the code is performing. Tracing can be enabled using the trace event module and with command line arguments. i.e. –trace-event-categories. Below categories can be monitored using the trace_event module.

  • node.fs.sync – It captures trace data for file system sync method.
  • node.perf – To capture data for Performance API.
  • node.promises.rejections – Tracking the number of unhandled Promise rejection and handled after rejection.

Below is the example to enable trace event using ‘trace_event’ module.

const trace_events = require('trace_events');
const tracing = trace_events.createTracing({ categories: ['node.fs.sync'] }); // comma seperated values for categories.
tracing.enable();  // Enable trace event capture
 
// trace your stuff
 
tracing.disable();  // Disable trace event capture

To summarize, as mentioned above improvement on HTTP2, availability of promises in the file system are much-required improvements. In addition to these, there are many other improvements like Cryptographic support will be available with the upcoming version which offers the advanced level of security it making node applications more secure and smoother in development.