Socket
Socket
Sign inDemoInstall

node-cqrs-framework

Package Overview
Dependencies
51
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    node-cqrs-framework

A CQRS implementation in nodeJS with promises.


Version published
Weekly downloads
33
increased by1000%
Maintainers
1
Install size
4.38 MB
Created
Weekly downloads
 

Readme

Source

node-cqrs-framework

CircleCI CodeFactor Coverage Status

node-cqrs-framework is a node.js framework that helps you to implement microservices and scalability for cqrs architectures over rabbitmq service discovery.

Advantages

  • Think better! Think KISS!
  • Configuration-driven oriented framework.
  • Only one monolithic project in your github.
  • Only one monolithic project to maintain.
  • Start only the services you want with configuration file.
  • Agnostics commands and queries, they just had to be promises.
  • Tests are dissociate from the notion of CQRS.
  • Deploy and scale your microservices like you want.
  • Automatic services discovery! Thanks rabbitmq.

Installation

$ npm i -S node-cqrs-framework

Description

Beware, you need a rabbitmq running in localhost for all those examples.

Server

The server is the main program, he needs to be start at first. Because the project is configuration-driven, you only need those lines of code to start all selected microservices in a row.

Glob patterns

This syntax will load all pomises in this dirpath and attach a 1:1 queue for execute the promise. And attach two 1:N queues (on for success event, and the second for error event).

server.use(path.resolve(__dirname, '../test/data/commands/*.js'))

Simple server

const path = require('path')

const Server = require('node-cqrs-framework').Server
const server = new Server()

// all options from servicebus (see npm)
const options = {
  host: 'localhost',
  port: 5672,
  user: 'guest',
  pass: 'guest',
  timeout: 2000,
  heartbeat: 10
}

server
  .use(path.resolve(__dirname, '../test/data/commands/*.js'))
  .use(path.resolve(__dirname, '../test/data/queries/*.js'))
  .start(options)

server.on('error', error => {
  console.log('server error')
  console.log(error)
})

server.on('ready', () => {
  console.log('server connected')
})
Service

A service is the base element of the CQRS, it's like a microservice or a task. The application result of a service will automaticaly:

  • Send an event on the bus in case of success
  • Send an event on the bus in case of error

You will never have to use this class, Command and Query extend it.

Command
  • "A result" is either a successful application of the command, or an exception.
  • Because it extends Service, success event or error event will be automaticaly send on the bus.

How to create a Command ?

Step 1
You need to create a file who contains "Command" in his name.
path/you/want/BasicNopeCommand.js

Step 2
You need to module.exports a promise.

const Promise = require('bluebird')

const handler = function () {
  return new Promise((resolve, reject) => {
    resolve()
  })
}

module.exports = handler
Query

From the framework point of view a query is the same as a command, but because of queries roles in the CQRS architecture, this time data will be return.

  • "A result" is either data, or an exception
  • Because it extends Service, success event or error event will be automaticaly send on the bus

How to create a Query ?

Step 1
You need to create a file who contains "Query" in his name.
path/you/want/BasicNopeQuery.js

Step 2
You need to module.exports a promise.

const Promise = require('bluebird')

const handler = function () {
  return new Promise((resolve, reject) => {
    resolve({data: true})
  })
}

module.exports = handler
Now it's time to start the server

Classic start:

$ node examples/server.js

But, you can run the server in debug mode.

$ DEBUG=cqrs:* node examples/server.js
Client

It's time to learn how to link all those services and events together, let's me introduce the Client object.

Definitions

A client could be wherever you need it to be, even on another server, or behind a hapiJS/Express server, or why not in another CQRS Server.
You will have three patterns to use the server events bus.

Sender/Receiver pattern

The Send / Receive object pair uses a direct exchange inside of RabbitMQ

Publisher/Subscriber pattern

The Publish / Subscribe object pair uses a fanout exchange inside of RabbitMQ, allowing you to have as many subscribers as you need. Think of pub/sub as an event that gets broadcast to anyone that cares, or no one at all if no one is listening.

Request/Response pattern

The request/response pair uses a "topic" exchange. With a request/response setup, you can send a request for information and respond to it.

Send a Query
  • When the server start and load your handlers, receivers are created in the server.
  • Sender client is a classic fire and forget on the bus. In return you will have only a result who informs you if the command or the query has been executed succesfully or not.

Create a file client-sender.js, and and this code in:

const Client = require('node-cqrs-framework').Client
const client = new Client()

// all options from servicebus (see npm)
const options = {
  host: 'localhost',
  port: 5672,
  user: 'guest',
  pass: 'guest',
  timeout: 2000,
  heartbeat: 10
}

client
  .subscribe('BasicNopeQuery.Success', (result) => {
    console.log('success', result)
    client.close()
  })
  .subscribe('BasicNopeQuery.Error', (result) => {
    console.log('error', result)
    client.close()
  })
  .start(options)

client.on('error', error => {
  console.log('client error')
  console.log(error)
})

client.on('ready', () => {
  console.log('client connected')
  client.send('BasicNopeQuery', {message: 'This is a query'})
})

Nota

  • The pattern BasicNopeQuery.* will receive Error and Success event for one specific Query.
  • The pattern *.Error will receive Errors for all Commands and Queries.
Now it's time to start the client-send

Classic start:

$ node examples/client-sender.js

But, you can run the client in debug mode.

$ DEBUG=cqrs:* node examples/client-sender.js

Result will be:

{ type: 'Query',
  name: 'BasicNopeQuery',
  event: 'BasicNopeQuery.Success',
  params: { message: 'This is a query' },
  exectime: 1004,
  result: { data: true } }
Request a Query
  • When the client start a specific queue is created on the server.
  • The server will have in the data received an automatic header to help him answering the client who called.
  • Events succes or error are also published.

Create a file client-request.js, and and this code in:

const Client = require('node-cqrs-framework').Client
const client = new Client()
client
  .subscribe('BasicNopeQuery.Success', (result) => {
    console.log('success', result)
    client.close()
  })
  .subscribe('BasicNopeQuery.Error', (result) => {
    console.log('error', result)
    client.close()
  })
  .start()

client.on('error', error => {
  console.log('client error')
  console.log(error)
})

client.on('ready', () => {
  console.log('client connected')
  client.request('BasicNopeQuery', {message: 'This is a query'}, (data) => {
    console.log('result', data)
  })
})

Result from the success event will be:

success { type: 'Query',
  name: 'BasicNopeQuery',
  event: 'BasicNopeQuery.Success',
  params:
   { message: 'This is a query',
     __headers:
      { 'x-client-id': 'Client.Response.38057d6b-bd49-4b4b-9727-35146c43789a',
        'x-request-id': 'cb0d0e12-8f8c-4267-a20f-fb05c653aba6' } },
  exectime: 1001,
  result: { data: true } }

Result from the response callback will be:

result { type: 'Query',
  name: 'BasicNopeQuery',
  event: 'BasicNopeQuery.Success',
  params: { message: 'This is a query' },
  exectime: 1001,
  result: { data: true } }

FAQs

Last updated on 01 Dec 2017

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc