Library for handling distributed transactions in the microservices architecture
npm install node-sagasnode-sagas package.node-sagas is a convenient library for managing data consistency in a microservice architecture.Why Sagas?
A distinctive characteristic of the microservice architecture is that in order to ensure loose coupling each service’s
data is private. Unlike in a monolithic application, you no longer have a single database that any module
of the application can update. As a result, one of the key challenges that you will face is maintaining
data consistency across services.
Please read more about saga pattern.
This module is installed via npm::
``shell`
npm i --save node-sagas
This package provides you with main classes for creating sagas.
The first main class is SagaBuilder. `typescript
import { SagaBuilder } from 'node-sagas';
const sagaBuilder = new SagaBuilder
const saga = sagaBuilder
.step('Create order')
.invoke((params: CreateOrderSagaParams) => {
// create order logic
})
.withCompensation((params: CreateOrderSagaParams) => {
// reject order logic
})
.step('Reserve credit')
.invoke((params: CreateOrderSagaParams) => {
// reserve credit
})
.step('Approve order')
.invoke((params: CreateOrderSagaParams) => {
// approve order
})
.build();
const params = new CreateOrderSagaParams();
try {
return await saga.execute(params);
} catch (e) {
if (e instanceof SagaExecutionFailed) {
// Throws, when invocation flow was failed, but compensation has been completed
}
if (e instanceof SagaCompensationFailed) {
// Throws, when compensation flow was failed
}
}
`
A step could be defined using step() method, for each step you can set an action for a positive invoke()
case with method. Also for each step, you can define compensation action with withCompensation() method.
SagaBuilder class use generic class for the handler's params:`typescript
export class CreateOrderSagaParams {
private orderId: number;
private customerId: number;
public getOrderId() {
return this.orderId;
}
public setOrderId(orderId) {
this.orderId = orderId;
}
public getCustomerId() {
return this.customerId;
}
public setCustomerId(customerId) {
this.customerId = customerId;
}
}
```
That class represents scope with params between the steps. Also, an instance of that class will be returned
after the saga success execution.
The article on Medium with a practical example will be prepared soon.
The code in this project is licensed under MIT license.