npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

asyncapi-sub-middleware

v1.0.3

Published

Create routes and validation for an express-like async server

Downloads

2

Readme

asyncapi-sub-middleware

Create routes and validation for an express-like async server

Summary

This module will automatically adds parameters, headers and message validators to your express-like async application (see kafka-express or rabbitmq-express) from an AsyncAPI definition file. It will also mount your own middlewares if asked.
Freely inspired by swagger-tools

Usage

const rabbitserver = require('rabbitmq-express');
const asyncApi = require('asyncapi-sub-middleware');

const app = rabbitserver();

const doc = fs.readFileSync('./lib/myAsyncAPIFile.yaml', 'utf8');

await asyncApi(app, doc, { stubMiddleware: true });

app.listen(options);

This will validate and parse your AsyncAPI file (myAsyncAPIFile.yaml), then create a route for each channel with a publish operation defined in that file. The validation and parsing of the file is done by @asyncapi/parser.
This route will validate the parameters of the route and the headers and body of the message with the parameter, headers and payload schemas defined in the file and add them to the api property of the request object. The validation itself is done by ajv.
It will then add a "stub" middleware on each route.

Documentation

asyncapi-sub-middleware

The module exports a function that takes your express-like application, an AsyncAPI document and options.

require('asyncapi-sub-middleware')(application, document, options)

application

Any application using middlewares can be used, i.e. there should be a .use(route, [middlewares]) function available.
The request object fed into the middlewares should have a params and a body property to validate against the schema.
The application is responsible for the connection to the actual async server (rabbitmq, kafka, etc...)

document

The AsyncAPI file. It accepts 3 formats:

string (reading directly from the file)

const document = fs.readFileSync('./lib/myAsyncAPIFile.yaml', 'utf8');

JSON (the file converted to a JSON object)

const yaml = require('js-yaml');
const document = yaml.load(fs.readFileSync('./lib/myAsyncAPIFile.yam', 'utf8'));

AsyncAPIDocument (the file parsed through @asyncapi/parser)

const { parse } = require('@asyncapi/parser');
const document = await parse(fs.readFileSync('./lib/myAsyncAPIFile.yam', 'utf8'));

options

An optional object. All properties are optional too.

// these are the default values
const {
  tag = '',
  requireController = true,
  controllers = '',
  stubMiddleware = false,
} = options;

If tag is set, only the tagged publish operations will be mounted.
If requireController is set to false, only the 2 validation middlewares will be mounted and all controller's related infos will be ignored.
controllers should be the path to a directory/file defining the controller middlewares for each publish operations.
If stubMiddleware is set to true, a stub middleware will be mounted on each route if a controller middleware is not defined.

ValidationError

The module exports the error class that is thrown in case of a validation error.

const { ValidationError } = require('asyncapi-sub-middleware');
if (err instanceof ValidationError) // That's our error.

Controller Middleware

To be able to automatically mount your controller middlewares you need to provide a combination of information.

First, in the options object requireController should be set to true (it is the default.)

Second, you need to provide the path to one or more files containing your middlewares. For that we use the controllers property of the options object and an optional extension in the AsyncAPI file on the publish operation:

x-operation-controller

Third, you need to define the operationId of the publish operation as the name of a function on the file defined by the combination of the controllers and the x-operation-controller.

example

The options object:

const options = {
  tag = 'myApp',
  requireController = true,
  controllers = 'src/api',
  stubMiddleware = false,
};

The AsyncAPI file:

channels:
  topic.{id}.key:
    parameters:
      id:
        $ref: '#/components/parameters/myid'
    publish:
      tags:
        - name: myApp
      operationId: nameOfMyMiddleware
      x-operation-controller: 'topic/myControllerFile'
      message:
        $ref: '#/components/messages/mymessage'

In this example you should have a "required-able" file on the path defined by the combination of controllers and the x-operation-controller, i.e. src/api/topic/myControllerFile.js.
This file should export a function by the name of the operationId, i.e nameOfMyMiddleware

The controller file for this operation (src/api/topic/myControllerFile.js):

module.exports = {
  nameOfMyMiddleware: (req, res, next) => {
    const { api: { params, headers, body } } = req;
    //do something
  }
}

OR

module.exports = {
  nameOfMyMiddleware: () => {
    return [
      (req, res, next) => {
        const { api: { params, headers, body } } = req;
        //do something
      },
      (err, req, res, next) => {
        //do something in case of an error
      }
    ]
  }
}