Course contentsShow
← Node.js
Lesson 433 of 1,9805. Streams and BackpressureFree lesson

Stream Interceptor Patterns

Create middleware-like wrappers for streams to add cross-cutting concerns like logging or authentication.

In this lesson, you will learn how to build "interceptor" wrappers around streams to inject cross-cutting logic like logging or authentication without cluttering your main data processing pipeline.

The Interceptor Concept

When you are building complex streaming pipelines, you often find yourself repeating the same boilerplate tasks: verifying a user’s token before processing, logging every chunk that passes through, or monitoring for specific metadata. Instead of baking this into your business logic, you can use the Interceptor Pattern.

By wrapping a stream in a PassThrough or a custom Transform stream, you create a "gatekeeper." This gatekeeper sits in your pipeline, inspects the data, performs an action (like checking an authorization header), and then decides whether to forward the chunk or trigger an error.

Implementing an Interceptor

Think of a PassThrough stream as a transparent pipe. If we provide it with transform logic, we can tap into the flow:

const { PassThrough } = require('stream');

function createLoggingInterceptor(label) {
  return new PassThrough({
    transform(chunk, encoding, callback) {
      console.log(`[${label}] Intercepted chunk of size: ${chunk.length}`);
      // Simply pass the data through unchanged
      callback(null, chunk);
    }
  });
}

// Usage: Injecting the interceptor into a pipeline
const logStream = createLoggingInterceptor('File-Processor');
inputStream.pipe(logStream).pipe(outputStream);

Why Use This?

  1. Decoupling: Your transformation logic remains focused on data, while your interceptor handles operational concerns.
  2. Reusability: You can write a single AuthInterceptor and pipe it into any stream that requires security, keeping your codebase DRY.
  3. Transparency: Because these interceptors are just streams, they respect backpressure automatically. If the interceptor is busy logging to a slow database, it will signal the upstream source to pause, preventing memory overflow.

By treating these "add-on" features as discrete stream objects, you turn your pipeline into a modular series of plug-and-play components.

Key Takeaway: The Stream Interceptor Pattern uses lightweight Transform or PassThrough streams to encapsulate cross-cutting concerns, ensuring your data logic remains clean, testable, and compliant with backpressure requirements.