LogoLogo
ChangelogGitHubTwitterGitter
v4.x
v4.x
  • Marble.js
  • Getting started
    • Installation
    • Quick setup
  • HTTP
    • Effects
    • Middlewares
    • Routing
    • Errors
    • Output
    • Context
    • Advanced
      • Logging
      • Validation
      • Server Events
      • Streaming
      • Continuous mode
  • Messaging
    • Core concepts
      • Events
      • Effects
    • Microservices
      • AMQP (RabbitMQ)
      • Redis Pub/Sub
    • CQRS
    • WebSockets
  • Testing
    • HTTP routes testing
  • Other
    • How does it glue together?
    • Migration guides
      • Migration from version 3.x
      • Migration from version 2.x
      • Migration from version 1.x
    • API reference
      • @marblejs/core
        • bindTo
        • bindEagerlyTo
        • createEvent
        • createContextToken
        • operator: matchEvent
        • operator: use
        • operator: act
      • @marblejs/http
        • httpListener
        • r.pipe
        • combineRoutes
        • createServer
      • @marblejs/messaging
        • eventBus
        • messagingClient
        • createMicroservice
        • reply
      • @marblejs/websockets
        • webSocketListener
        • operator: broadcast
        • operator: mapToServer
      • @marblejs/middleware-multipart
      • @marblejs/middleware-cors
      • @marblejs/middleware-io
      • @marblejs/middleware-logger
      • @marblejs/middleware-body
      • @marblejs-contrib/middleware-jwt
        • Token signing
      • @marblejs-contrib/middleware-joi
    • Style Guide
    • FAQ
Powered by GitBook
On this page
  • Installation
  • Importing
  • Type declaration
  • Parameters
  • Usage
  • Validation errors
  • Reporters
  1. Other
  2. API reference

@marblejs/middleware-io

Previous@marblejs/middleware-corsNext@marblejs/middleware-logger

Last updated 4 years ago

A data validation middleware based on awesome library authored by .

Installation

yarn add @marblejs/middleware-io

Requires @marblejs/core to be installed.

Importing

// HTTP
import { requestValidator$ } from '@marblejs/middleware-io';

// Events, eg. WebSockets
import { eventValidator$ } from '@marblejs/middleware-io';

Type declaration

requestValidator$ :: (RequestSchema, ValidatorOptions) -> Observable<HttpRequest> -> Observable<HttpRequest>
eventValidator$ :: (Schema, ValidatorOptions) -> Observable<Event> -> Observable<Event>

Parameters

requestValidator$

parameter

definition

schema

options

<optional> ValidatorOptions

eventValidator$

parameter

definition

schema

options

<optional> ValidatorOptions

ValidatorOptions

parameter

definition

reporter

<optional> Reporter

context

<optional> string

Usage

Let's define a user schema that will be used for I/O validation.

user.schema.ts
export const userSchema = t.type({
  id: t.string,
  firstName: t.string,
  lastName: t.string,
  roles: t.array(t.union([
    t.literal('ADMIN'),
    t.literal('GUEST'),
  ])),
});

export type User = t.TypeOf<typeof userSchema>;
import { use, r } from '@marblejs/core';
import { requestValidator$, t } from '@marblejs/middleware-io';
import { userSchema } from './user.schema.ts';

const effect$ = r.pipe(
  r.matchPath('/'),
  r.matchType('POST'),
  r.useEffect(req$ => req$.pipe(
    requestValidator$({ body: userSchema }),
    // ..
  )));

For more validation use cases and recipes, visit Validation chapter.

You can also reuse the same schema for Events validation if you want.

import { matchEvent, act } from '@marblejs/core';
import { WsEffect } from '@marblejs/websockets';
import { eventValidator$, t } from '@marblejs/middleware-io';
import { userSchema } from './user.schema.ts';

const postUser$: WsEffect = event$ =>
  event$.pipe(
    matchEvent('CREATE_USER'),
    act(eventValidator$(userSchema)),
    act(event => { ... }),
  );

The inferred req.body / event.payload type of provided schema, will be of the following form:

type User = {
  id: string;
  firstName: string;
  lastName: string;
  roles: ('ADMIN' | 'GUEST')[];
};

Please note that each eventValidator$ must be applied inside act operator to prevent closing of the main observable stream.

Validation errors

Lets take a look at the default reported validation error thrown by eventValidator$ . Let's assume that client passed wrong values for firstName and roles fields.

payload.lastName = false;
payload.roles = ['TEST'];

The reported error intercepted via default error effect will look like follows.

{
  type: 'CREATE_USER',
  error: {
    message: 'Validation error',
    data: [
      {
        path: 'lastName',
        expected: 'string',
        got: 'false'
      },
      {
        path: 'roles.0.0',
        got: '"TEST"',
        expected: '"ADMIN"'
      },
      {
        path: 'roles.0.1',
        got: '"TEST"',
        expected: '"GUEST"'
      }
    ]
  }
}

Reporters

interface Reporter<A> {
  report: (validation: Validation<any>) => A
}

In order to use custom reporter you have to pass it with options object as a second argument.

requestValidator$(schema, { reporter: customReporter });

Partial<RequestSchema>(see docs)

Schema (see docs)

You can create custom reporters by conforming to Reporter interface.

io-ts
gcanti
io-ts
io-ts
io-ts