Middlewares

Custom middleware

Like any other Effect, Marble.js defines a similar way for defining middlewares. In case of WebSocket protocol it is a function that transforms stream of incoming events 👉 stream of outgoing events.

Lets create a simple logger middleware like we previously did in case of HTTP.

logger.ws-middleware.ts
import { Event } from '@marblejs/core';
import { WsMiddlewareEffect } from '@marblejs/websockets';

export const logger$: WsMiddlewareEffect = event$ =>
  event$.pipe(
    tap(e => console.log(`type: ${e.type}, payload: ${e.payload}`)),
  );
  
// or an equivalent

export const logger$ = (event$: Observable<Event>): Observable<Event> =>
  event$.pipe(
    tap(e => console.log(`type: ${e.type}, payload: ${e.payload}`)),
  );

Similar to any other middleware or effect, we have to register it inside the listener.

webSocket.listener.ts
import { webSocketListener } from '@marblejs/websockets';
import { logger$ } from './logger.ws-middleware';

export const webSocketServer = webSocketListener({
  middlewares: [logger$],
  // ...
});

Middlewares composition

Similar to HTTP routes, you can compose middlewares in two ways:

  • globally (inside webSocketListener configuration object),

  • by composing it directly inside Effect event pipeline.

The use operator availabe in @marblejs/core package allows you to compose multiple types of middlewares - not only HTTP-related. Lets examine how can we compose the @marblejs/middleware-io middleware in event$ pipeline.

Last updated