Benefits of Event Sourcing in Financial Application


What is Event Sourcing

Event sourcing is a practice of keeping record of every change during the lifecycle of an application. In traditional approaches, usually the current state of the application is preserved. But the information of how we reached that state over time is lost. We lose information while updating data models.

Event sourcing ensures that all changes are captured in the forms of event object and stores them sequentially. Events are stored in append only mode and they are never to be modified.
Event sourcing is not a new concept. There are real world examples of practicing event sourcing:
An accountant keeps track of all transactions. He never erases or modifies previous records. He always creates a new entry, even to fix the previous mistake.
A doctor keeps record of patient’s medical history by adding new entry at the end of the journal


Why Event Sourcing is beneficial in financial application

Never lose information

No risk of losing important business information, as it store every changes in application state as event. It’s the biggest advantage of event sourcing based application. It is vitally important to keep track of every bit of financial data. And storing information is not that costly nowadays. We might never know in advance, which information will be useful in future.

Auditing is simple

Auditing is a vital part of any financial system. As all immutable events are appended sequentially in the event store, it is a readily available audit log of all past changes in the system or financial data

Event replay and Temporal queries

Travelling to a past state of a application is possible. Starting with initial application state and replaying all the events to a particular time, we can determine application state at any point of time. Also in case of failure, reconstruction of application state is possible by replaying the events.

Debuggability

By replaying, rewinding or stopping the actual events in a test environment, it’s possible to reproduce what went wrong in a certain situation. This form of debuggability is useful before deployment in production.

Scalability

Event sourcing is often coupled with CQRS, an approach to separate read or query functionality from the write or command functionality. As reads and writes separated, each can be scalable with different magnitude with their separate optimization.

Security

As events are never modified and added in the event store on append-only mode, data tampering will be hard and traceable. We can take the advantage of using WORM storage (Write Once Read Many), for storing events to ensure better security.

Domain Driven Design

Unlike CRUD operations, events are more relatable with business domain. Thus application architecture can be designed in a more Domain Driven approach. It is less likely to get carried away with technicality from the business domain

Analytics

Keeping all business information allows us to estimate how things co-relate over time. This data allows us to draw various conclusions from past data, project estimates, analize customer behaviour etc.

Yml or Yaml for DevOps

As software engineers, we are always learning new tech stacks as we process our careers. Everyone who works on any short of software farm all came across a term called DevOps.

As the name suggests, it’s consists of two terms Dev equal Development Ops equals Operations. So DevOps means Development Operations. As a different career choice/position in some software farms still as a developer, it may help a lot if we know some shot of DevOps terms and tools which we can use to help others if anyone needs help or fast peace our development/testing time.

In this post, we’ll not post about any complicated tech stacks which may be used by our DevOps colleagues like Docker, Kubernetes, Ansible, Prometheus, etc. But we’ll learn to use a common language called data-serialization language. These languages are human-readable so that anyone can understand what’s going on in that particular DevOps tools when we first saw them in our projects.

Prerequisites: None

What is YAML?

YAML (a recursive acronym for "YAML Ain’t Markup Language") is a human-readable data-serialization language.

It is quite popular in the DevOps tools which we will talk about in our later posts. One of the main reasons why YAML popularity has increased so much over the past few years is that it is super human-readable and intuitive which makes it a great tool for writing configuration files for all those recent DevOps tools like I mentioned above.

As we try to learn YAML, we came across its competitors in this field which is XML and JSON. We’ll show you examples of the three so that you can understand why YAML so popular among these three.

YAML XML JSON
yml syntax xml syntax json syntax

Note: YAML is a superset of JSON, So any valid JSON syntax will be a valid YAML code.

So as YAML uses line separation and spaces with indentation instead of tags with angle brackets in XML and curly bracket in JSON. It’s a lot more easy to understand by others than XML or JSON.

In this post, we will learn just enough syntax of YAML so that when anyone saw any configuration files from now on, he/she can easily understand what it means.

Now let’s talk about the basic use cases of YAML in DevOps tools. We use YAML(YML) used in docker-compose, Kubernetes, Prometheus, Ansible, etc configuration files.

Basic Syntax

As YAML uses simple key-value pair with proper space and indentation to format as we have shown in the above YAML picture.

Writing a comment

# this is a comment in yaml(yml)

Placing a # sign in front of a sentence is considered comment in YAML.

Strings

"valid string 1"
'valid string 2'
valid string 3

In YAML, strings can be written with double quotes or single quotes or without any quotes.

Note: If a string has any special character like \n or \t then it must be written inside quotes otherwise YAML can’t understand it.

'This string must be inside \n quotes'

Key-Value pair

image: consul:latest
container_name: consul_dev
ports: 8500

Writing anything in YAML must be followed like the above key-value pair except comments.

Objects

consul:
    image: consul:latest
    container_name: consul_dev
    ports: 8500

To write objects in YAML, we just need to indent them within another key, check the example above. image, container_name, port becomes an object with consul as its key.

Note: Indentation must be the same without proper indentation YAML can’t understand what it meant so it will throw an error when executing the YAML file. It’ll be best if we use a YAML validator when writing YAML.

Validate YAML, this online tool can be used to validate YAML.

Lists

ports: 
    - 8500
    - 9500
# OR
ports: [8500, 9500]

If we want to create a list of ports, we can just add a dash (-) in front of the port value which will make it a list item. Another way of writing a list item is more readable than the first one. so use whatever suits you better.

Booleans

app:
    auth: true # false
# OR
app:
    auth: yes # no
# OR
app:
    auth: on # off

The above three ways are defined to express boolean values.

This is the basic syntax anyone needs to understand any configuration file written in YAML.

Let’s look at a practical example using a simple docker-compose file and we use YAML

version: '3.7'

services:
  db:
    image: mysql:8.0.21
    container_name: mysql
    ports:
      - 3309:3306
    volumes:
      - ./db:/var/lib/mysql:rw
    environment:
      - MYSQL_USER=d2d_user
      - MYSQL_PASSWORD=12345678
      - MYSQL_DATABASE=d2d_db
      - MYSQL_ROOT_PASSWORD=12345678
    tty: true

At we start to write a docker-compose file we start with version:3.7 key-pair as it’s required for docker-compose to understand which version of YAML we are using to write docker-compose so that it can parse the YAML file

Then we create a services key-pair so that we can define our services when we run docker-compose up to start application needed services.

Within the services key. we create a db service and a YAML object as its value. we used a MySQL image and defined mysql as docker container name. : sign used to define image tags.

Other info’s like volumes to persist data in a local folder or environment to define environment variable and tty: true for docker run -t which are specific to docker so that it can start db containers.

If you like you can read the same article in my Personal blog

In conclusion, we can say, Understanding YAML can help a lot if we starting our career as a DevOps Engineer or a software engineer to understand other configuration files used by the DevOps team.

জাভাস্ক্রিপ্টে Primitive এবং Reference টাইপ কি?

আজকে আমরা আলোচনা করতে যাচ্ছি Primitive এবং Reference টাইপ ডাটার মাঝে কি পার্থক্য এবং এই ডাটা টাইপগুলো কিভাবে কাজ করে। Primitive এবং Reference টাইপকে pass by value এবং pass by reference ও বলা হয়ে থাকে। একজন জাভাস্ক্রিপ্ট প্রোগ্রামার হিসাবে এই ডাটা টাইপগুলো সম্পর্কে পরিষ্কার জ্ঞান রাখা আবশ্যক।

জাভাস্ক্রিপ্টে দুই টাইপের ডাটা টাইপ আছে।

  1. primitive ডাটা টাইপ এবং
  2. non-primitive বা reference ডাটা টাইপ

জাভাস্ক্রিপ্টে Strings, Numbers, Boolean, Null, undefined এই ডাটা টাইপগুলো প্রিমিটিভ ডাটা টাইপ হিসাবে পরিচিত এবং Arrays, Objects, Function নন-প্রিমিটিভ বা রেফারেন্স ডাটা টাইপ হিসাবে পরিচিত। এদের মাঝে মৌলিক পার্থক্য হচ্ছে যে প্রিমিটিভ ডাটা immutable বা অপরিবর্তনীয় এবং নন-প্রিমিটিভ ডাটা mutable বা পরিবর্তনীয়।

প্রিমিটিভ ডাটা টাইপ

প্রমিটিভ ডাটা immutable বা অপরিবর্তনীয় ডাটা টাইপ হিসাবে পরিচিত। কারণ এই ডাটা একবার তৈরি হয়ে গেলে এটি পরিবর্তন করার কোন পথ নেই। তাহলে চলেন আপনাদের প্রমাণ করে দেখাই।

    let str1 = "Hi there, I am a string!";
    console.log(str1[1]); // "i"

    str1[1] = "e";
    console.log(str1); // "Hi there, I am a string!"

উপরের কোডটা রান করলে জাভাস্ক্রিপ্টের কারিশমা দেখতে পারবেন। সব কিছু মাথার উপর দিয়ে গেল? আচ্ছা, চলেন ব্যাপারটা ব্যাখ্যা করি। আপনি হাজার বার চাইলেও স্ট্রিং এর ভ্যালু পরিবর্তন করতে পারবেন না। কারণ স্ট্রিং একটি immutable বা অপরিবর্তনীয় ডাটা। একটি কথা মনে রাখবেন যদি স্ট্রিংকে কোন ভেরিয়েবলে অ্যাসাইন করে ফেলেন এবং অ্যাসাইন করার পর স্ট্রিংকে মডিফাই করতে চান, তাহলে আপনি একটি নতুন স্ট্রিং পাবেন। যেমন- .toUpperCase(), .slice(), .trim() ইত্যাদি।

    let str1 = "Hi there, I am a string!";
    let newStr = str1.toUpperCase();

    console.log(newStr); // HI THERE, I AM A STRING!
    console.log(str1); Hi there, I am a string!

প্রিমিটিভ ডাটা টাইপগুলো একে অপরের সাথে তাদের ভ্যালু দ্বারা তুলনা করে।

    let str1 = "Hi there, I am a string!";
    let str2 = "Hi there, I am a string!";

    console.log(str1 == str2); // true

    let num1 = 7;
    let num2 = 7;

    console.log(num1 == num2); // true

প্রিমিটিভ টাইপগুলো সব সময় তাদের ভ্যালু পাস করে। যখন আমরা কোন প্রিমিটিভ ডাটা টাইপকে অন্য কোন ভেরিয়েবলে অ্যাসাইন করি, তখন তার ভ্যালু কপি হয়ে নতুন ভেরিয়েবলে অ্যাসাইন হয়।

    let num1 = 7;
    let num2 = num1;

    console.log(num1); // 7
    console.log(num2); // 7

    num2 = 8;

    console.log(num1); // 7
    console.log(num2); // 8

নন-প্রিমিটিভ ডাটা টাইপ

নন-প্রিমিটিভ ডাটা mutable বা পরিবর্তনীয়। কারণ একটি নন-প্রিমিটিভ ডাটা তৈরি হয়ে যাওয়ার পরেও তার ভ্যালু পরিবর্তন হতে পারে। আমরা যখন কোন নন-প্রিমিটিভ ডাটা তৈরি করি, তখন সেই ডাটার জন্যে মেমোরিতে একটা অ্যাড্রেস তৈরি হয় এবং সেই অ্যাড্রেসটাকে মনে রেখে কোন এক জায়গায় ভ্যালুগুলোকে স্ট্রোর করে রাখে। তারপর আমাদের যখন দরকার পরে তখন সে ঐ অ্যাড্রেসকে কল করে এবং আমাদের ডাটা প্রদান করে। এটা বুঝতে হলে আপনাকে স্ট্যাক এবং হীপ মেমোরি সম্পর্কে জানতে হবে। তবে আমি যতটুকু বললাম এখন এতটুকু মনে রাখলেই হবে।

    let arr1 = ["JavaScript", "React", "Redux", "React-Redux"];
    let arr2 = arr1;

    console.log(arr1); // ["JavaScript", "React", "Redux", "React-Redux"]
    console.log(arr2); // ["JavaScript", "React", "Redux", "React-Redux"]

    arr2[3] = "Redux-Toolkit";
    console.log(arr1); // ["JavaScript", "React", "Redux", "Redux-Toolkit"]
    console.log(arr2); // ["JavaScript", "React", "Redux", "Redux-Toolkit"]

নন-প্রিমিটিভ বা রেফারেন্স ডাটাগুলো সব সময় তাদের রেফারেন্স পাস করে। যখন আমরা কোন রেফারেন্স ডাটাকে অন্য কোন ভেরিয়েবলে অ্যাসাইন করি, তখন তার রেফারেন্স কপি হয়। মানে arr1 কে যখন আমরা arr2 তে অ্যাসাইন করি তখন তার রেফারেন্স বা অ্যাড্রেসটাকে কপি করে বা মনে রাখে তার ভ্যালুকে না। তাই দুইটা ভেরিয়েবলের অ্যাড্রেস একই থাকে। তাই যখন আমরা কোন একটি ভেরিয়েবলের ভ্যালু পরিবর্তন করি, তখন দুইটা ভেরিয়েবলেরই ভ্যালু পরিবর্তন হয়ে যায়।

    let obj1 = {
    name: 'JavaScript'
    };
    let obj2 = obj1;

    console.log(`${obj1.name}`); // JavaScript
    console.log(`${obj2.name}`); // JavaScript

    obj2.name = "React";

    console.log(`${obj1.name}`); // React
    console.log(`${obj2.name}`); // React

আশা করি, উপরের কোডে কি হচ্ছে সেটা এখন খুব ভাল ভাবেই বুঝতে পারছেন। একটি কথা নন-প্রিমিটিভ ডাটা তাদের রেফারেন্স দ্বারা তুলনা করে।

    let obj1 = {
    name: 'JavaScript'
    };

    let obj2 = {
    name: 'React'
    };

    console.log(obj1 === obj2); // false

এখানে দুইটা অবজেক্টের একই ভ্যালু কিন্তু যখন আমরা দুইটা অবজেক্টকে একে-অপরের সাথে তুলনা করছি, তখন তারা false রিটার্ন করছে। কারণ তাদের ভ্যালু একই হলেও তাদের অ্যাড্রেস এক না।

    let obj1 = {
    name: 'JavaScript'
    };

    let obj2 = obj1;

    console.log(obj1 === obj2); // true

এখানে কি হচ্ছে সেটা কি বলতে হবে? বিষয়টা একদম পানির মত পরিষ্কার।

এই হচ্ছে প্রিমিটিভ এবং নন-প্রিমিটিভ ডাটা টাইপের মাঝে পার্থক্য। যদি ভাল লেগে থাকে তাহলে মুক্ত জ্ঞান সবার মাঝে ছড়িয়ে দিন। সবাইকে জানতে এবং শিখতে সাহায্য করুন। দেখা হবে পরবর্তী কোন লেখায়। ততদিন হ্যাপি কোডিং

লেখকের ব্যক্তিগত যেতে এখানে ক্লিক করুন।

জাভাস্ক্রিপ্টে কলব্যাক ও হাইয়ার অর্ডার ফাংশন

কলব্যাক ব্যাপারটি আমাদের জীবনের সাথে ব্যাপকভাবে জড়িয়ে আছে। যদি “সে” কলব্যাক না করে আপনি হয়তো “অ” হয়ে যান! ইয়ে মানে বলতে চাচ্ছিলাম যে অভিমানী নয়তো অস্থির হয়ে যান 😉 আর যদি আপনার লাইফে “সে” না থাকে তবে তো কোন কথাই নেই। আমার মত বিন্দাস 😂। যাইহোক, আপনি “অ” হোন আর না হোন, “সে” কলব্যাক করুক আর না করুক আজকে আমরা কলব্যাক নিয়ে আলোচনা করবই। চলুন তাহলে শুরু থেকেই শুরু করি…

জাভাস্ক্রিপ্টে ফাংশন হচ্ছে একটি ফার্স্ট-ক্লাস অবজেক্ট। এই কারণে, ফাংশন ভেরিয়েবলের মাঝে এসাইন হতে পারে, অন্য একটি ফাংশনকে আর্গুমেন্ট হিসাবে নিতে পারে, ফাংশনের ভিতরেও কাজ করতে পারে এবং ফাংশন দ্বারা রিটার্নও হতে পারে।

কলব্যাক ফাংশন কি?

সহজ কথায়, কলব্যাক ফাংশন হচ্ছে এমন একটি ফাংশন যেটি অন্য একটি ফাংশনে আর্গুমেন্ট হিসাবে পাস করা ফাংশন, যেটি কোন কাজ সম্পন্ন করার জন্যে আউটার ফাংশনের ভিতরে ইনভোক হয়।

হাইয়ার অর্ডার ফাংশন কি?

যে ফাংশনে অন্য কোন ফাংশনকে আর্গুমেন্ট হিসাবে পাস করা হয় বা কোন ফাংশন অন্য কোন ফাংশনকে রিটার্ন করে তাকে হাইয়ার অর্ডার ফাংশন বলা হয়। বাংলায় এটাকে ঊচ্চমার্গীয় ফাংশন হিসেবে ভেবে নিতে পারেন। ঊচ্চমার্গীয় কথাবার্তা মাথার উপর দিয়ে গেলেও ঊচ্চমার্গীয় ফাংশন মাথার নিচ দিয়েই যাবে ইনশাআল্লাহ্‌, নিশ্চিত থাকুন।

আমাদের এমন একটি ফাংশন আছে যেটি আর্গুমেন্ট হিশাবে একটি অ্যারে নিবে এবং সেটি কে মডিফাই করে একটি নতুন অ্যারে নিটার্ন করবে। এক্ষেত্রে, আমাদের ফাংশনটিকে যে অ্যারে দেওয়া হবে তার সাথে দুই যোগ করে নতুন একটি অ্যারে নিটার্ন করবে।

function modifyBy2(arr) {
    let output = [];

    for(let i = 0; i < arr.length; i++) {
        output.push(arr[i] + 2);
    }

    return output;
}

const newArr = modifyBy2([1,2,3,4,5,6]);
console.log(newArr); // [3, 4, 5, 6, 7, 8]

এখন আমাদের আরেকটি ফাংশন আছে যেটি আর্গুমেন্ট হিশাবে একটি অ্যারে নিবে এবং যে অ্যারে দেওয়া হবে তার সাথে দুই গুণ করে নতুন একটি অ্যারে নিটার্ন করবে।

function multifyBy2(arr) {
    let output = [];

    for(let i = 0; i < arr.length; i++) {
        output.push(arr[i] * 2);
    }

    return output;
}

const newArr = modifyBy2([1,2,3,4,5,6]);
console.log(newArr); // [2, 4, 6, 8, 10, 12]

এখন যদি আমরা বিয়োগ বা ভাগ করতে চাই? তাহলে আমাদেরকে আরও দুটি ফাংশন লিখতে হবে তাই না? ব্যাপারটা তাহলে কি ভাল কিছু হচ্ছে? কোড রিপিটেশন হয়ে যাচ্ছে। একটি বিষয় লক্ষ্য করেন আমাদের লেখা দুটি ফাংশনেই শুধু অপারেশনগুলা ছাড়া একই কোড লিখেছি। আমরা যদি এমন কিছু করতে পারি যে আমাদের ফাংশনে যোগ, বিয়োগ যে কাজই করুক না কেন সেটি আমরা বলে দিবো, তাহলে কেমন হয়? এখন আমরা সে কাজটাই করবো। তার জন্যে আমাদেরকে আমাদের ফাংশনের সাথে আরেকটি আর্গুমেন্ট পাস করতে হবে। যেটি আসলে আমাদের অপারেশনটা হ্যান্ডল করবে।

function modifyArray(arr, fn) {
    let output = [];

    for(let i = 0; i < arr.length; i++) {
        output.push(fn(arr[i]));
    }

    return output;
}

function modifyBy2(elem) {
    return elem + 2;
}

const newArr = modifyArray([1,2,3,4,5,6], modifyBy2);
console.log(newArr); // [3, 4, 5, 6, 7, 8]

উপরের কোডে লক্ষ্য করুন, আমরা modifyArray নামে একটি ফাংশন ডিফাইন করেছি যেটি দুটি আর্গুমেন্টস নিচ্ছে। একটি অ্যারে এবং অন্যটি একটি ফাংশন। সে ফাংশনে আমরা বলে দিচ্ছি তার কাজ কি হবে। সে তার কাজ সম্পন্ন করে output অ্যারেতে তার ভ্যালুটা পুশ করে দিচ্ছে এবং modifyArray ফাংশনটি কাজ সম্পন্ন করে একটি নতুন অ্যারে রিটার্ন করতেছে। এখন যদি আমরা বিয়োগ, গুণ বা ভাগ করতে চাই সেটিও খুব সহজেই করতে পারবো এই ফাংশন দিয়ে। আমাদেরকে নতুন করে কোন লজিক লেখা লাগবে না শুধু আমরা একটি নতুন ফাংশন দিয়ে দিবো এবং সেখানে বলে দিবো তাকে কি করতে হবে। তাহলে চলেন দেখি আমাদের কাজ করতে পারি কিনা।

function modifyArray(arr, callback) {
    let output = [];

    for(let i = 0; i < arr.length; i++) {
        output.push(callback(arr[i]));
    }

    return output;
}

function addBy2(elem) {
    return elem + 2;
}

function multifyBy2(elem) {
    return elem * 2;
}

const additionArr = modifyArray([1,2,3,4,5,6], addBy2);
const multiArr = modifyArray([1,2,3,4,5,6], multifyBy2);

console.log(additionArr); // [3, 4, 5, 6, 7, 8]
console.log(multiArr); // [2, 4, 6, 8, 10, 12]

modifyArray ফাংশনটিতে আর্গুমেন্ট হিসাবে যে ফাংশনটিকে পাস করতেছি ওই ফাংশনটিই হচ্ছে একটি কলব্যাক ফাংশন এবং modifyArray ফানশনটি হচ্ছে একটি হাইয়ার অর্ডার ফাংশন

বিঃ দ্রঃ এই হচ্ছে কলব্যাক এবং ঊচ্চমার্গীয় ফাংশনের কাজ কারবার। এইবার কি কলব্যাক এবং ঊচ্চমার্গীয় ফাংশন মাথার নিচ দিয়ে যাচ্ছে?? এরপরও যদি ৬০০+ ওয়র্ডের একটা লেখা পড়ে মাথার উপর দিয়ে যায় তাহলে কমেন্ট বক্সে কমেন্ট করে উড়াই দিবেন, আমি ধরে নিবো।

এখানে ক্লিক করে লেখকের ব্যক্তিগত ব্লগেও পড়তে পারবেন