← Back to Tutorials Chapter 12

Advanced Topics

Microservices

Microservices architecture breaks an application into small, independent services that communicate over a network. Node.js is ideal for microservices due to its lightweight nature.

// Service 1: User Service (port 3001)
const express = require('express');
const app = express();
app.get('/api/users/:id', (req, res) => {
  res.json({ id: req.params.id, name: 'Alice' });
});
app.listen(3001);

// Service 2: Order Service (port 3002)
const express = require('express');
const app = express();
app.get('/api/orders', async (req, res) => {
  // Call User Service
  const userRes = await fetch('http://user-service:3001/api/users/1');
  const user = await userRes.json();
  res.json({ user, orders: [{ id: 1, total: 29.99 }] });
});
app.listen(3002);

Communication Patterns

WebAssembly (Wasm)

Node.js can execute WebAssembly modules for near-native performance in compute-heavy tasks.

// Load and run WebAssembly
const fs = require('fs');
const wasmBuffer = fs.readFileSync('module.wasm');

WebAssembly.instantiate(wasmBuffer).then(({ instance }) => {
  const result = instance.exports.add(5, 3);
  console.log('Wasm result:', result); // 8
});

// Write WebAssembly (WAT format)
// (module
//   (func $add (param $a i32) (param $b i32) (result i32)
//     local.get $a
//     local.get $b
//     i32.add)
//   (export "add" (func $add))
// )

HTTP/2

Node.js supports HTTP/2 natively, offering multiplexing, header compression, and server push.

const http2 = require('http2');
const fs = require('fs');

const server = http2.createServer({
  key: fs.readFileSync('server.key'),
  cert: fs.readFileSync('server.cert')
});

server.on('stream', (stream, headers) => {
  stream.respond({
    'content-type': 'text/plain',
    ':status': 200
  });
  stream.end('Hello, HTTP/2!\n');
});

server.listen(3000);

Performance Hooks

Use perf_hooks to measure performance in your Node.js applications.

const { performance, PerformanceObserver } = require('perf_hooks');

// Measure execution time
performance.mark('start');
// ... some operation ...
performance.mark('end');
performance.measure('Operation', 'start', 'end');

const obs = new PerformanceObserver((list) => {
  console.log(list.getEntries());
});
obs.observe({ entryTypes: ['measure'] });

VM Module

The vm module allows running JavaScript code in a sandboxed context.

const vm = require('vm');

const code = 'console.log("Hello from VM!"); return 42;';
const result = vm.runInNewContext(code);
console.log('Result:', result);

// Context with globals
const sandbox = { x: 10, y: 20 };
vm.createContext(sandbox);
vm.runInContext('result = x + y;', sandbox);
console.log(sandbox.result); // 30

TLS/SSL

Secure your Node.js server with TLS.

const https = require('https');
const fs = require('fs');

const options = {
  key: fs.readFileSync('private-key.pem'),
  cert: fs.readFileSync('certificate.pem'),
  ca: fs.readFileSync('ca-certificate.pem')
};

https.createServer(options, (req, res) => {
  res.writeHead(200);
  res.end('Secure connection!\n');
}).listen(443);

Zlib (Compression)

const zlib = require('zlib');
const fs = require('fs');

// Compress file
const gzip = zlib.createGzip();
const readStream = fs.createReadStream('input.txt');
const writeStream = fs.createWriteStream('input.txt.gz');
readStream.pipe(gzip).pipe(writeStream);

// Decompress
const gunzip = zlib.createGunzip();
fs.createReadStream('input.txt.gz')
  .pipe(gunzip)
  .pipe(fs.createWriteStream('output.txt'));

Real-World Examples

Exercise: Research and write a brief proposal for splitting a monolithic Express.js application into microservices. Identify boundaries (e.g., users, orders, products), choose a communication pattern, and outline the API contracts.