StrongLoop makes it easy to develop APIs in Node, plus get DevOps capabilities like monitoring, debugging and clustering.

change-into-a-truck Welcome to part one of a three part series that aims to help you get a jumpstart on new and breaking API changes in the upcoming Node.js v0.12 release. In part one, we’ve pulled out the non-breaking API changes, while in part two we separate out breaking APIs. In part three, Ben Noordhuis will detail breaking C++ API changes on StrongLoop Blog.

Because v0.12 is not out yet, this post is largely based on differences between v0.10 documentation and v0.11. Click on an API below to jump to the appropriate section in the post below to learn more.

Process

Event: process.beforeExit

New in v0.12

This event is emitted when node empties it’s event loop and has nothing else to schedule. Normally, node exits when there is no work scheduled, but a listener for beforeExit can make asynchronous calls, and cause node to continue.

beforeExit is not emitted for conditions causing explicit termination, such as process.exit() or uncaught exceptions, and should not be used as an alternative to the exit event unless the intention is to schedule more work.

process.exitCode

New in v0.12

A number which will be the process exit code, when the process either exits gracefully, or is exited via process.exit() without specifying a code.

Specifying a code to process.exit(code) will override any previous setting of process.exitCode.

Util

util.debuglog(section)

New in v0.12

This is used to create a function which conditionally writes to stderr based on the existence of a NODE_DEBUG environment variable. If the section name appears in that environment variable, then the returned function will be similar to console.error(). If not, then the returned function is a no-op.

For example:

var debuglog = util.debuglog('foo');

var bar = 123;
debuglog('hello from foo [%d]', bar);

If this program is run with NODE_DEBUG=foo in the environment, then it will output something like:

FOO 3245: hello from foo [123]

where 3245 is the process id. If it is not run with that environment variable set, then it will not print anything.

You may separate multiple NODE_DEBUG environment variables with a comma. For example, NODE_DEBUG=fs,net,tls.

Custom inspect() function on Objects

New in v0.12

Objects also may define their own inspect(depth) function which util.inspect() will invoke and use the result of when inspecting the object:

var util = require('util');

var obj = { name: 'nate' };
obj.inspect = function(depth) {
  return '{' + this.name + '}';
};

util.inspect(obj);
  // "{nate}"

You may also return another Object entirely, and the returned String will be formatted according to the returned Object. This is similar to how JSON.stringify() works:

var obj = { foo: 'this will not show up in the inspect() output' };

obj.inspect = function(depth) {
  return { bar: 'baz' };
};

util.inspect(obj);
  // "{ bar: 'baz' }"

EventEmitter

EventEmitter.defaultMaxListeners

New in v0.12

emitter.setMaxListeners(n) sets the maximum on a per-instance basis. This class property lets you set it for all EventEmitter instances, current and future, effective immediately. Use with care.

Note that emitter.setMaxListeners(n) still has precedence over EventEmitter.defaultMaxListeners.

Buffer

Class Method: Buffer.compare(buf1, buf2)

New in v0.12

The same as buf1.compare(buf2). Useful for sorting an Array of Buffers:

var arr = [Buffer('1234'), Buffer('0123')];
arr.sort(Buffer.compare);

buf.compare(otherBuffer)

New in v0.12

Returns a number indicating whether this comes before or after or is the same as the otherBuffer in sort order.

buf.toArrayBuffer()

New in v0.12

Creates a new ArrayBuffer with the copied memory of the buffer instance.

Stream

writable.cork()

New in v0.12

Forces buffering of all writes.

Buffered data will be flushed either at .uncork() or at .end() call.

writable.uncork()

New in v0.12

Flush all data, buffered since .cork() call.

writable._writev(chunks, callback)

New in v0.12

  • chunksArray The chunks to be written. Each chunk has following format: { chunk: ..., encoding: ... }.
  • callbackFunction Call this function (optionally with an error argument) when you are done processing the supplied chunks.

Note: This function MUST NOT be called directly. It may be implemented by child classes, and called by the internal Writable class methods only.

This function is completely optional to implement. In most cases it is unnecessary. If implemented, it will be called with all the chunks that are buffered in the write queue.

Crypto

crypto.setEngine(engine, [flags])

New in v0.12

Load and set engine for some/all OpenSSL functions (selected by flags).

  • engine could be either an id or a path to the to the engine’s shared library.

  • flags is optional and has ENGINE_METHOD_ALL value by default. It could take one of or mix of following flags (defined in constants module):
    • ENGINE_METHOD_RSA
    • ENGINE_METHOD_DSA
    • ENGINE_METHOD_DH
    • ENGINE_METHOD_RAND
    • ENGINE_METHOD_ECDH
    • ENGINE_METHOD_ECDSA
    • ENGINE_METHOD_CIPHERS
    • ENGINE_METHOD_DIGESTS
    • ENGINE_METHOD_STORE
    • ENGINE_METHOD_PKEY_METH
    • ENGINE_METHOD_PKEY_ASN1_METH
    • ENGINE_METHOD_ALL
    • ENGINE_METHOD_NONE

cipher.getAuthTag()

New in v0.12

For authenticated encryption modes (currently supported: GCM), this method returns a Buffer that represents the authentication tag that has been computed from the given data. Should be called after encryption has been completed using the final method!

cipher.setAAD(buffer)

New in v0.12

For authenticated encryption modes (currently supported: GCM), this method sets the value used for the additional authenticated data (AAD) input parameter.

decipher.setAuthTag(buffer)

New in v0.12

For authenticated encryption modes (currently supported: GCM), this method must be used to pass in the received authentication tag. If no tag is provided or if the ciphertext has been tampered with, final will throw, thus indicating that the ciphertext should be discarded due to failed authentication.

decipher.setAAD(buffer)

New in v0.12

For authenticated encryption modes (currently supported: GCM), this method sets the value used for the additional authenticated data (AAD) input parameter.

crypto.createDiffieHellman(prime_length, [generator])

New in v0.12

Creates a Diffie-Hellman key exchange object and generates a prime of prime_length bits and using an optional specific numeric generator. If no generator is specified, then 2 is used.

crypto.createDiffieHellman(prime, [prime_encoding], [generator], [generator_encoding])

New in v0.12

Creates a Diffie-Hellman key exchange object using the supplied prime and an optional specific generator. generator can be a number, string, or Buffer. If no generator is specified, then 2 is used. prime_encoding and generator_encoding can be 'binary', 'hex', or 'base64'. If no prime_encoding is specified, then a Buffer is expected for prime. If no generator_encoding is specified, then a Buffer is expected for generator.

diffieHellman.verifyError

New in v0.12

A bit field containing any warnings and/or errors as a result of a check performed during initialization. The following values are valid for this property (defined in constants module):

  • DH_CHECK_P_NOT_SAFE_PRIME
  • DH_CHECK_P_NOT_PRIME
  • DH_UNABLE_TO_CHECK_GENERATOR
  • DH_NOT_SUITABLE_GENERATOR

crypto.pbkdf2(password, salt, iterations, keylen, [digest], callback)

New in v0.12

Asynchronous PBKDF2 function. Applies the selected HMAC digest function (default: SHA1) to derive a key of the requested length from the password, salt and number of iterations. The callback gets two arguments: (err, derivedKey).

Example:

crypto.pbkdf2('secret', 'salt', 4096, 512, 'sha256', function(err, key) {
  if (err)
    throw err;
  console.log(key.toString('hex'));  // 'c5e478d...1469e50'
});

You can get a list of supported digest functions with crypto.getHashes().

crypto.pbkdf2Sync(password, salt, iterations, keylen, [digest])

New in v0.12

Synchronous PBKDF2 function. Returns derivedKey or throws error.

Certificate.verifySpkac(spkac)

New in v0.12

Returns true of false based on the validity of the SPKAC.

Certificate.exportChallenge(spkac)

New in v0.12

Exports the encoded public key from the supplied SPKAC.

Certificate.exportPublicKey(spkac)

New in v0.12

Exports the encoded challenge associated with the SPKAC.

TLS

Perfect Forward Secrecy

New in v0.12

The term “Forward Secrecy” or “Perfect Forward Secrecy” describes a feature of key-agreement (i.e. key-exchange) methods. Practically it means that even if the private key of a (your) server is compromised, communication can only be decrypted by eavesdroppers if they manage to obtain the key-pair specifically generated for each session.

This is achieved by randomly generating a key pair for key-agreement on every handshake (in contrary to the same key for all sessions). Methods implementing this technique, thus offering Perfect Forward Secrecy, are called “ephemeral”.

Currently two methods are commonly used to achieve Perfect Forward Secrecy (note the character “E” appended to the traditional abbreviations):

  • DHE – An ephemeral version of the Diffie Hellman key-agreement protocol.
  • ECDHE – An ephemeral version of the Elliptic Curve Diffie Hellman key-agreement protocol.

Ephemeral methods may have some performance drawbacks, because key generation is expensive.

Class: tls.TLSSocket

New in v0.12

This is a wrapped version of net.Socket that does transparent encryption of written data and all required TLS negotiation. Replaces tls.CleartextStream in v0.10.

This instance implements a duplex Stream interfaces. It has all the common stream methods and events.

NOTE: If this class is of interest to you, be sure to review the new docs carefully as there are new methods and properties.

Here’s the list of changes:

new tls.TLSSocket(socket, options)

New in v0.12

Construct a new TLSSocket object from existing TCP socket.

  • socket is an instance of net.Socket.
  • optionsObject that might contain following properties:
    • secureContext – An optional TLS context object from tls.createSecureContext( ... )
    • isServer – If true – TLS socket will be instantiated in server-mode
    • server – An optional net.Server instance
    • requestCert – Optional, see tls.createSecurePair
    • rejectUnauthorized – Optional, see tls.createSecurePair
    • NPNProtocols – Optional, see tls.createServer
    • SNICallback – Optional, see tls.createServer
    • session – Optional, a Buffer instance, containing TLS session
    • requestOCSP – Optional, if true – OCSP status request extension would be added to client hello, and OCSPResponse event will be emitted on socket before establishing secure communication

tls.createSecurePair(…)

New in v0.12

Deprecated. Use tls.TLSSocket instead.

Class: CryptoStream

New in v0.12

Deprecated. Use tls.TLSSocket instead.

Class: tls.CleartextStream

New in v0.12

This is a somewhat strange case. The class is completely replaced by the tls.TLSSocket in the new docs without a deprecation notice.

Event: ‘OCSPRequest’

New in v0.12

function (certificate, issuer, callback) { }

Emitted when the client sends a certificate status request. You could parse server’s current certificate to obtain OCSP url and certificate id, and after obtaining OCSP response invoke callback(null, resp), where resp is a Buffer instance. Both certificate and issuer are a Buffer DER-representations of the primary and issuer’s certificates. They could be used to obtain OCSP certificate id and OCSP endpoint url.

Alternatively, callback(null, null) could be called, meaning that there is no OCSP response.

Calling callback(err) will result in a socket.destroy(err) call.

Typical flow:

  1. Client connects to server and sends OCSPRequest to it (via status info extension in ClientHello.)
  2. Server receives request and invokes OCSPRequest event listener if present
  3. Server grabs OCSP url from either certificate or issuer and performs an OCSP request to the CA
  4. Server receives OCSPResponse from CA and sends it back to client via callback argument
  5. Client validates the response and either destroys socket or performs a handshake.

NOTE: issuer could be null, if certficiate is self-signed or if issuer is not in the root certificates list. (You could provide an issuer via ca option.)

NOTE: adding this event listener will have an effect only on connections established after addition of event listener.

NOTE: you may want to use some npm module like asn1.js to parse the certificates.

File System

fs.write(fd, buffer, offset, length[, position], callback)

New in v0.12

position argument is now optional. You shouldn’t have to make any changes.

fs.write(fd, data[, position[, encoding]], callback)

New in v0.12

Write data to the file specified by fd. If data is not a Buffer instance then the value will be coerced to a String.

Unlike when writing Buffer, the entire string must be written. No substring may be specified. This is because the byte offset of the resulting data may not be the same as the string offset.

fs.writeSync(fd, buffer, offset, length[, position])

New in v0.12

Synchronous versions of fs.write(). Returns the number of bytes written.

fs.writeSync(fd, data[, position[, encoding]])

New in v0.12

Synchronous versions of fs.write(). Returns the number of bytes written.

Path

path.isAbsolute(path)

New in v0.12

Determines whether path is an absolute path. An absolute path will always resolve to the same location, regardless of the working directory.

Posix examples:

path.isAbsolute('/foo/bar') // true
path.isAbsolute('/baz/..')  // true
path.isAbsolute('qux/')     // false
path.isAbsolute('.')        // false

Windows examples:

path.isAbsolute('//server')  // true
path.isAbsolute('C:/foo/..') // true
path.isAbsolute('barbaz')  // false
path.isAbsolute('.')         // false

Net

Event: ‘lookup’

New in v0.12

Emitted after resolving the hostname but before connecting. Not applicable to UNIX sockets.

  • errError The error object. See dns.lookup().
  • addressString The IP address.
  • familyString The address type. See dns.lookup().

UDP / Datagram Sockets

dgram.createSocket(options, [callback])

New in v0.12

dgram.createSocket() now has overloaded signature with options.

  • type – Not clear from the docs, I submitted #8019.
  • reuseAddrBoolean Required. false by default. When truesocket.bind() will reuse address, even if the other process has already bound a socket on it.

DNS

All functions taking domain argument now take hostname instead (which means argument was basically renamed).

dns.resolveSoa(hostname, callback)

New in v0.12

The same as dns.resolve(), but only for start of authority record queries (SOA record).

callback(err, addresses) with the following structure:

{
  nsname: 'ns.example.com',
  hostmaster: 'root.example.com',
  serial: 2013101809,
  refresh: 10000,
  retry: 2400,
  expire: 604800,
  minttl: 3600
}

dns.getServers()

New in v0.12

Returns an array of IP addresses as strings that are currently being used for resolution.

dns.setServers(servers)

New in v0.12

Given an array of IP addresses as strings, set them as the servers to use for resolving.

If you specify a port with the address it will be stripped, as the underlying library doesn’t support that.

This will throw if you pass invalid input.

HTTP

http.METHODS

New in v0.12

A list of the HTTP methods that are supported by the parser.

response.statusMessage

New in v0.12

When using implicit headers (not calling response.writeHead() explicitly), this property controls the status message that will be sent to the client when the headers get flushed. If this is left as undefined then the standard message for the status code will be used.

Example:

response.statusMessage = 'Not found';

After response header was sent to the client, this property indicates the status message which was sent out.

new Agent([options])

New in v0.12

  • optionsObject Set of configurable options to set on the agent. Can have the following fields:
    • keepAliveBoolean Keep sockets around in a pool to be used by other requests in the future. Default is false
    • keepAliveMsecsInteger When using HTTP KeepAlive, how often to send TCP KeepAlive packets over sockets being kept alive. Default is 1000. Only relevant if keepAlive is set to true.
    • maxSocketsNumber Maximum number of sockets to allow per host. Default is Infinity.
    • maxFreeSocketsNumber Maximum number of sockets to leave open in a free state. Only relevant if keepAlive is set to true. Default is 256.

The default http.globalAgent that is used by http.request has all of these values set to their respective defaults.

To configure any of them, you must create your own Agent object.

var http = require('http');
var keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);

agent.maxFreeSockets

New in v0.12

By default set to 256. For Agents supporting HTTP KeepAlive, this sets the maximum number of sockets that will be left open in the free state.

agent.freeSockets

New in v0.12

An object which contains arrays of sockets currently awaiting use by the Agent when HTTP KeepAlive is used. Do not modify.

agent.requests

New in v0.12

An object which contains queues of requests that have not yet been assigned to sockets. Do not modify.

agent.destroy()

New in v0.12

Destroy any sockets that are currently in use by the agent.

It is usually not necessary to do this. However, if you are using an agent with KeepAlive enabled, then it is best to explicitly shut down the agent when you know that it will no longer be used. Otherwise, sockets may hang open for quite a long time before the server terminates them.

request.flush()

New in v0.12

Flush the request headers.

For effiency reasons, node.js normally buffers the request headers until you call request.end() or write the first chunk of request data. It then tries hard to pack the request headers and data into a single TCP packet.

That’s usually what you want (it saves a TCP round-trip) but not when the first data isn’t sent until possibly much later. request.flush() lets you bypass the optimization and kickstart the request.

message.rawHeaders

New in v0.12

The raw request/response headers list exactly as they were received.

Note that the keys and values are in the same list. It is not a list of tuples. So, the even-numbered offsets are key values, and the odd-numbered offsets are the associated values.

Header names are not lowercased, and duplicates are not merged.

console.log(request.rawHeaders);

[ 'user-agent',
  'this is invalid because there can be only one',
  'User-Agent',
  'curl/7.22.0',
  'Host',
  '127.0.0.1:8000',
  'ACCEPT',
  '*/*' ]

message.rawTrailers

New in v0.12

The raw request/response trailer keys and values exactly as they were received. Only populated at the end event.

message.statusMessage

New in v0.12

Only valid for response obtained from http.ClientRequest.

The HTTP response status message (reason phrase), e.g. OK or Internal Server Error.

HTTPS

server.setTimeout(msecs, callback)

New in v0.12

See http.Server#setTimeout().

server.timeout

New in v0.12

See http.Server#timeout.

REPL

Event: ‘reset’

New in v0.12

function (context) {}

Emitted when the REPL’s context is reset. This happens when you type .clear. If you start the repl with { useGlobal: true } then this event will never be emitted.

Example of listening for reset:

// Extend the initial repl context.
r = repl.start({ options ... });
someExtension.extend(r.context);

// When a new context is created extend it as well.
r.on('reset', function (context) {
  console.log('repl has a new context');
  someExtension.extend(context);
});

Child Process

child_process.spawnSync(command, [args], [options])

New in v0.12

  • commandString The command to run
  • argsArray List of string arguments
  • optionsObject
    • cwdString Current working directory of the child process
    • inputString|Buffer The value which will be passed as stdin to the spawned process
    • supplying – this value will override stdio[0]
    • stdioArray Child’s stdio configuration.
    • envObject Environment key-value pairs
    • uidNumber Sets the user identity of the process. (See setuid(2).)
    • gidNumber Sets the group identity of the process. (See setgid(2).)
    • timeoutNumber In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignalString The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBufferNumber
    • encodingString The encoding used for all stdio inputs and outputs. (Default: 'buffer')
    • returnObject
    • pidNumber Pid of the child process
    • outputArray Array of results from stdio output
    • stdoutBuffer|String The contents of output[1]
    • stderrBuffer|String The contents of output[2]
    • statusNumber The exit code of the child process
    • signalString The signal used to kill the child process
    • errorError The error object if the child process failed or timedout

spawnSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won’t return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn’t exit, your process will wait until the child process has exited.

child_process.execFileSync(command, [args], [options])

New in v0.12

  • commandString The command to run
  • argsArray List of string arguments
  • optionsObject
    • cwdString Current working directory of the child process
    • inputString|Buffer The value which will be passed as stdin to the spawned process
    • supplying – this value will override stdio[0]
    • stdioArray Child’s stdio configuration. (Default: ‘pipe’)
    • stderrby default will be output to the parent process’ stderr unless stdio is specified
    • envObject Environment key-value pairs
    • uidNumber Sets the user identity of the process. (See setuid(2).)
    • gidNumber Sets the group identity of the process. (See setgid(2).)
    • timeoutNumber In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignalString The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBufferNumber
    • encodingString The encoding used for all stdio inputs and outputs. (Default: 'buffer')
  • return: Buffer|String The stdout from the command

execFileSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won’t return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn’t exit, your process will wait until the child process has exited.

If the process times out, or has a non-zero exit code, this method will throw. The Error object will contain the entire result from child_process.spawnSync.

child_process.execSync(command, [options])

New in v0.12

  • commandString The command to run
  • optionsObject
    • cwdString Current working directory of the child process
    • inputString|Buffer The value which will be passed as stdin to the spawned process
    • supplyingthis value will override stdio[0]
    • stdioArray Child’s stdio configuration. (Default: 'pipe')
    • stderrby default will be output to the parent process’ stderr unless stdio is specified
    • envObject Environment key-value pairs
    • uidNumber Sets the user identity of the process. (See setuid(2).)
    • gidNumber Sets the group identity of the process. (See setgid(2).)
    • timeoutNumber In milliseconds the maximum amount of time the process is allowed to run. (Default: undefined)
    • killSignalString The signal value to be used when the spawned process will be killed. (Default: 'SIGTERM')
    • maxBufferNumber
    • encodingString The encoding used for all stdio inputs and outputs. (Default: 'buffer')
  • return: Buffer|String The stdout from the command

execSync will not return until the child process has fully closed. When a timeout has been encountered and killSignal is sent, the method won’t return until the process has completely exited. That is to say, if the process handles the SIGTERM signal and doesn’t exit, your process will wait until the child process has exited.

If the process times out, or has a non-zero exit code, this method will throw. The Error object will contain the entire result from child_process.spawnSync.

ZLIB

zlib.flush([kind], callback)

New in v0.12

  • kind defaults to zlib.Z_FULL_FLUSH.

Flush pending data. Don’t call this frivolously, premature flushes negatively impact the effectiveness of the compression algorithm.

zlib.params(level, strategy, callback)

New in v0.12

Dynamically update the compression level and compression strategy. Only applicable to deflate algorithm.

Options

New in v0.12

All convenience methods now take optional options argument.

  • flush (default: zlib.Z_NO_FLUSH)
  • chunkSize (default: 16*1024)
  • windowBits
  • level (compression only)
  • memLevel (compression only)
  • strategy (compression only)
  • dictionary (deflate/inflate only, empty dictionary by default)

See the description of deflateInit2 and inflateInit2 at http://zlib.net/manual.html#Advanced for more information on these.

Cluster

cluster.schedulingPolicy

New in v0.12

The scheduling policy, either cluster.SCHED_RR for round-robin or cluster.SCHED_NONE to leave it to the operating system. This is a global setting and effectively frozen once you spawn the first worker or call cluster.setupMaster(), whatever comes first.

SCHED_RR is the default on all operating systems except Windows. Windows will change to SCHED_RR once libuv is able to effectively distribute IOCP handles without incurring a large performance hit.

cluster.schedulingPolicy can also be set through the NODE_CLUSTER_SCHED_POLICY environment variable. Valid values are rr and none.

Smalloc

Smalloc is a new experimental core module for manipulating array data.