jaguar_cqrs 2.1.5

  • README.md
  • CHANGELOG.md
  • Installing
  • Versions
  • 50

CQRS/ES

Command Query Responsibility Separation and Event Sourcing library for Dart.

Usage

Define Domain model

class Account implements AggregateModel {
  String id;

  String owner;

  double amount;

  Account({this.id, this.owner, this.amount});
}

Define commands

abstract class ForAccount {
  final String forAggregate = "account";
}

class CreateAccountCmd extends Command with ForAccount {
  final String modelId;

  final String owner;

  CreateAccountCmd({@required this.owner, @required this.modelId});
}

class DepositCmd extends Command with ForAccount {
  final String modelId;

  final double amount;

  DepositCmd({@required this.amount, @required this.modelId});
}

class WithdrawCmd extends Command with ForAccount {
  final String modelId;

  final double amount;

  WithdrawCmd({@required this.amount, @required this.modelId});
}

Define events

class AccountCreatedEvent implements Event {
  String get forAggregate => "account";

  final String id;

  final String owner;

  AccountCreatedEvent({@required this.id, @required this.owner});

  String toString() => "Created account ($id) for $owner.";
}

class DepositPerformedEvent implements Event {
  String get forAggregate => "account";

  final String id;

  final double amount;

  DepositPerformedEvent({@required this.id, @required this.amount});

  String toString() => "Deposited $amount\$ into account $id.";
}

class WithdrawalPerformedEvent implements Event {
  String get forAggregate => "account";

  final String id;

  final double amount;

  WithdrawalPerformedEvent({@required this.id, @required this.amount});

  String toString() => "Withdrew $amount\$ from account $id.";
}

Define aggregate

class AccountAggregate extends Aggregate<Account> {
  final String name = 'account';

  @override
  Account initializeModel() => Account();

  @override
  Future<void> apply(Account model, DomainEvent event) async {
    if (event is AccountCreatedEvent) {
      model.id = event.id;
      model.owner = event.owner;
      model.amount = 0.0;
    } else if (event is DepositPerformedEvent) {
      model.amount += event.amount;
    } else if (event is WithdrawalPerformedEvent) {
      model.amount -= event.amount;
    } else {
      throw Exception("Unknown event!");
    }
  }

  @override
  Future<void> handleCommand(
      Command cmd, Account model, CommandOutput out) async {
    if (cmd is CreateAccountCmd) {
      if (model.id != null) {
        out.setError("Model with id ${cmd.modelId} already exists!");
        return;
      }
      out.addEvent(AccountCreatedEvent(id: cmd.modelId, owner: cmd.owner));
    } else if (cmd is DepositCmd) {
      out.addEvent(DepositPerformedEvent(id: cmd.modelId, amount: cmd.amount));
    } else if (cmd is WithdrawCmd) {
      if (model.amount < cmd.amount) {
        out.setError("Not enough balance!");
        return;
      }
      out.addEvent(
          WithdrawalPerformedEvent(id: cmd.modelId, amount: cmd.amount));
      return;
    } else {
      throw UnsupportedError(cmd.runtimeType.toString());
    }
  }
}

Glue them all together

main() async {
  final cqrs = Cqrs()
    ..registerAggregate(AccountAggregate())
    ..registerRepository(InMemoryRepository<Account>(forAggregate: "account"));

  cqrs.events.listen(print);

  await cqrs.submitCommand(CreateAccountCmd(owner: "Teja", modelId: "1"));
  await cqrs.submitCommand(DepositCmd(modelId: "1", amount: 200.0));
  await cqrs.submitCommand(DepositCmd(modelId: "1", amount: 200.0));
  await cqrs.submitCommand(WithdrawCmd(modelId: "1", amount: 300.0));
  await cqrs.submitCommand(DepositCmd(modelId: "1", amount: 400.0));
}

Outputs.

Created account (1) for Teja. Deposited 200.0$ into account 1. Deposited 200.0$ into account 1. Withdrew 300.0$ from account 1. Deposited 400.0$ into account 1.

2.1.5

  • Command results
  • Event stream

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  jaguar_cqrs: ^2.1.5

2. Install it

You can install packages from the command line:

with pub:


$ pub get

with Flutter:


$ flutter packages get

Alternatively, your editor might support pub get or flutter packages get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:jaguar_cqrs/jaguar_cqrs.dart';
  
Version Uploaded Documentation Archive
2.1.5 Oct 3, 2018 Go to the documentation of jaguar_cqrs 2.1.5 Download jaguar_cqrs 2.1.5 archive
2.1.4 Oct 2, 2018 Go to the documentation of jaguar_cqrs 2.1.4 Download jaguar_cqrs 2.1.4 archive
2.1.2 Oct 2, 2018 Go to the documentation of jaguar_cqrs 2.1.2 Download jaguar_cqrs 2.1.2 archive
2.1.0 Oct 2, 2018 Go to the documentation of jaguar_cqrs 2.1.0 Download jaguar_cqrs 2.1.0 archive
Popularity:
Describes how popular the package is relative to other packages. [more]
0
Health:
Code health derived from static analysis. [more]
100
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
100
Overall:
Weighted score of the above. [more]
50
Learn more about scoring.

We analyzed this package on Dec 5, 2018, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.1.0
  • pana: 0.12.7

Platforms

Detected platforms: Flutter, web, other

No platform restriction found in primary library package:jaguar_cqrs/jaguar_cqrs.dart.

Maintenance suggestions

Maintain an example.

None of the files in your example/ directory matches a known example patterns. Common file name patterns include: main.dart, example.dart or you could also use jaguar_cqrs.dart. Packages with multiple examples should use example/readme.md.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.0.0 <3.0.0
meta ^1.1.6 1.1.6
Dev dependencies
test ^1.3.0