The usual web-server term for this is "virtual hosts". It has been present in every HTTP server since probably 1996, so based on that alone I would suggest that existing solutions are a good enough choice and you shouldn't be trying to literally reinvent the wheel just for the sake of avoiding Apache (especially if you have zero experience in this area).
With virtual hosts as they are implemented in major web servers, the path to the host files is configured per-domain rather than globally per-server. There are no "redirects" as the server looks in a different location from the very beginning.
For example, Apache or Nginx (very nearly the same layout) might be configured like this:
# The global setting is only used for requests that didn't match any VHost. DocumentRoot /var/www/default # Normally you would have <VirtualHost> blocks for every recognized domain # (one for HTTP on *:80 and of course an identical one for HTTPS on *:443). <VirtualHost *:80> ServerName gamestudio.example.com DocumentRoot /var/www/gamestudio </VirtualHost> <VirtualHost *:80> ServerName workbench.example.com DocumentRoot /var/www/workbench </VirtualHost>
If you have Nginx, the same is done using multiple server { ... } blocks. With Caddy, the domain name is literally the main "parameter" within the configuration file:
gamestudio.example.com { root * /var/www/gamestudio } workbench.example.com { root * /var/www/workbench }
Now if you do want to implement it manually in Node regardless – I actually have no idea how one normally creates web servers in Node to begin with, but the web browser specifies the requested domain name in the Host: header. So upon receiving an HTTP request, you would look at its Host header to determine the host/domain name, and instead of a single fixed "path to the host files" you'd have a Map of domains and their respective paths.
For example, (this is the first thing I've written in Node ever):
var http = require('http'); var fs = require('fs'); http.createServer(function (req, res) { console.log(req.headers); let host = req.headers["host"]; if (host == "workbench.example.com") { res.writeHead(200, {'Content-Type': 'text/html'}); res.end(fs.readFileSync('/var/www/workbench/index.html')); } else if (host == "gamestudio.example.com") { res.writeHead(200, {'Content-Type': 'text/html'}); res.end(fs.readFileSync('/var/www/gamestudio/index.html')); } else { res.writeHead(400, {'Content-Type': 'text/plain'}); res.end('Unrecognized vhost'); } }).listen(8080);
That said, however, even with webapp backends it is more common to let some external HTTP proxy handle this. Instead of having one big backend process to handle five webapps, one would have e.g. Nginx/Traefik/Haproxy/etc. acting as a proxy to five separate backends – each handling only its own domain.