AFAICT, createServer
function is being kept only for compatibility, because all it does now is to simply call the Server
constructor as is:
In http module:
function createServer(opts, requestListener) {
return new Server(opts, requestListener);
}
Hence, we can simply use:
const { Server } = require('http');
const server = new Server((req, res) => res.end('Hello!'));
In fact, if we examine where Server
is defined by scrolling on top of http:
const {
_connectionListener,
STATUS_CODES,
Server,
ServerResponse
} = require('_http_server');
We understand that Server
is coming from _http_server. Examining how Server
is defined in _http_server
:
function Server(options, requestListener) {
if (!(this instanceof Server)) return new Server(options, requestListener);
if (typeof options === 'function') {
requestListener = options;
options = {};
} else if (options == null || typeof options === 'object') {
options = { ...options };
} else {
throw new ERR_INVALID_ARG_TYPE('options', 'object', options);
}
this[kIncomingMessage] = options.IncomingMessage || IncomingMessage;
this[kServerResponse] = options.ServerResponse || ServerResponse;
const maxHeaderSize = options.maxHeaderSize;
if (maxHeaderSize !== undefined)
validateInteger(maxHeaderSize, 'maxHeaderSize', 0);
this.maxHeaderSize = maxHeaderSize;
const insecureHTTPParser = options.insecureHTTPParser;
if (insecureHTTPParser !== undefined)
validateBoolean(insecureHTTPParser, 'options.insecureHTTPParser');
this.insecureHTTPParser = insecureHTTPParser;
net.Server.call(this, { allowHalfOpen: true });
if (requestListener) {
this.on('request', requestListener);
}
// Similar option to this. Too lazy to write my own docs.
// http://www.squid-cache.org/Doc/config/half_closed_clients/
// https://wiki.squid-cache.org/SquidFaq/InnerWorkings#What_is_a_half-closed_filedescriptor.3F
this.httpAllowHalfOpen = false;
this.on('connection', connectionListener);
this.timeout = 0;
this.keepAliveTimeout = 5000;
this.maxHeadersCount = null;
this.headersTimeout = 60 * 1000; // 60 seconds
this.requestTimeout = 0;
}
We notice the line:
if (!(this instanceof Server)) return new Server(options, requestListener);
at the beginning of the Server
function. This means that we can simply omit the new
keyword when we are calling the Server
constructor. Hence, we can simply use:
require('http').Server((req, res) => res.end('Hello!')).listen(3000, 'localhost');
as a basic server code. Expressed less tersely:
const { Server } = require('http');
const server = Server((req, res) => res.end('Hello!'));
server.listen(3000, 'localhost');
As another note, observe that if the first argument passed to Server
function is a function (which is the case when only a single argument is passed), then Server
treats this as the event handler for the request
event. Or, if two arguments are passed, the second argument is the listener for the request event:
if (requestListener) {
this.on('request', requestListener);
}
If we want to be more explicit, we can create a server as follows:
const { Server } = require('http');
const server = Server();
server.on('request', (req, res) => res.end('Hello!'));
server.listen(3000, 'localhost');