Middleware Composition

Purpose

Middleware Composition addresses the challenge of extending the core SWR data fetching hook with additional functionality in a modular and reusable manner. Rather than embedding features directly into the core hook, this subtopic provides a utility to layer multiple middleware functions, allowing developers to compose complex behaviors (e.g., logging, caching strategies, subscription handling) seamlessly on top of the base SWR hook. This promotes clean separation of concerns, easier maintenance, and flexible customization of hook behavior without modifying core logic.

Functionality

At its core, Middleware Composition enables wrapping the original useSWR hook with one or more middleware functions that can intercept and enhance the hook’s inputs, outputs, or internal lifecycle.

This pattern supports recursive or nested middleware composition, enabling complex feature layering while maintaining a simple interface for consumers.

Key Code Interaction

The withMiddleware function is the centerpiece:

export const withMiddleware = (
  useSWR: SWRHook,
  middleware: Middleware
): SWRHook => {
  return <Data = any, Error = any>(...args) => {
    const [key, fn, config] = normalize(args)
    const uses = (config.use || []).concat(middleware)
    return useSWR<Data, Error>(key, fn, { ...config, use: uses })
  }
}

Integration

Middleware Composition is the foundational utility that enables the broader Middleware Architecture within the project. By providing a consistent way to layer middleware, it allows all other middleware features—such as preloading, devtools integration, subscription management, and immutable data handling—to plug into the core SWR hook transparently.

This mechanism empowers developers to create custom middleware or combine existing ones, fostering an extensible and scalable data fetching ecosystem.

Diagram

sequenceDiagram
  participant Component as React Component
  participant ComposedHook as Composed SWR Hook
  participant MiddlewareChain as Middleware Stack
  participant CoreHook as Core useSWR Hook

  Component->>ComposedHook: Call with args (key, fetcher, config)
  ComposedHook->>ComposedHook: Normalize args
  ComposedHook->>MiddlewareChain: Append new middleware to config.use
  ComposedHook->>CoreHook: Invoke useSWR with updated config
  CoreHook->>MiddlewareChain: Execute middleware chain during hook lifecycle
  MiddlewareChain->>CoreHook: Enhance fetch/data behavior
  CoreHook-->>ComposedHook: Return SWR state and utilities
  ComposedHook-->>Component: Provide SWR data and methods

This sequence illustrates how a React component calls a SWR hook wrapped with middleware composition, which normalizes inputs, extends middleware, and delegates to the core hook. The middleware chain then augments the hook’s behavior before returning stateful data to the component.