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.
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.
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.
import { use } from '@marblejs/core';
import { WsEffect } from '@marblejs/websockets';
import { eventValidator$, t } from '@marblejs/middleware-io';
const User = t.type({
name: t.string,
age: t.number,
});
export const createUser$: WsEffect = event$ =>
event$.pipe(
matchEvent('CREATE_USER'),
use(eventValidator$(User)),
// ... event.payload: { name: string, age: number }
);
Last updated