在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
开源软件名称:mishudark/eventhus开源软件地址:https://github.com/mishudark/eventhus开源编程语言:Go 100.0%开源软件介绍:EventhusCQRS/ES toolkit for Go. CQRS stands for Command Query Responsibility Segregation. It's a pattern that I first heard described by Greg Young. At its heart is the notion that you can use a different model to update information than the model you use to read information. The mainstream approach people use for interacting with an information system is to treat it as a CRUD datastore. By this I mean that we have mental model of some record structure where we can create new records, read records, update existing records, and delete records when we're done with them. In the simplest case, our interactions are all about storing and retrieving these records. Event Sourcing ensures that every change to the state of an application is captured in an event object, and that these event objects are themselves stored in the sequence they were applied for the same lifetime as the application state itself. Examplesbank account shows a full example with UsageThere are 3 basic units of work: CommandA command describes an action that should be performed; it's always named in the imperative tense such as Let’s start with some code: import "github.com/mishudark/eventhus"
// PerformDeposit to an account
type PerformDeposit struct {
eventhus.BaseCommand
Amount int
} At the beginning, we create the You can also define custom fields, in this case EventAn event is the notification that something happened in the past. You can view an event as the representation of the reaction to a command after being executed. All events should be represented as verbs in the past tense such as We create the // DepositPerformed event
type DepositPerformed struct {
Amount int
} AggregateThe aggregate is a logical boundary for things that can change in a business transaction of a given context. In the Eventhus context, it simplifies the process the commands and produce events. Show me the code! import "github.com/mishudark/eventhus"
//Account of bank
type Account struct {
eventhus.BaseAggregate
Owner string
Balance int
} We create the Additionally Now that we have our // HandleCommand create events and validate based on such command
func (a *Account) HandleCommand(command eventhus.Command) error {
event := eventhus.Event{
AggregateID: a.ID,
AggregateType: "Account",
}
switch c := command.(type) {
case CreateAccount:
event.AggregateID = c.AggregateID
event.Data = &AccountCreated{c.Owner}
case PerformDeposit:
event.Data = &DepositPerformed{
c.Amount,
}
}
a.BaseAggregate.ApplyChangeHelper(a, event, true)
return nil
} First, we create an Finally, the event should be applied to our aggregate; we use the helper Note: The last step in the aggregate journey is to apply the // ApplyChange to account
func (a *Account) ApplyChange(event eventhus.Event) {
switch e := event.Data.(type) {
case *AccountCreated:
a.Owner = e.Owner
a.ID = event.AggregateID
case *DepositPerformed:
a.Balance += e.Amount
}
} Also, we use a switch-case format to determine the type of the Note: The aggregate is never saved in its current state. Instead, it is stored as a series of Saving the events, publishing them, and recreating an aggregate from Config
Event StoreCurrently, it has support for We create an import "github.com/mishudark/eventhus/config"
...
config.Mongo("localhost", 27017, "bank") // event store Event Publisher
We create an import "github.com/mishudark/eventhus/config"
...
config.Nats("nats://ruser:T0pS3cr3t@localhost:4222", false) // event bus Wire it all togetherNow that we have all the pieces, we can register our import (
"github.com/mishudark/eventhus"
"github.com/mishudark/eventhus/commandhandler/basic"
"github.com/mishudark/eventhus/config"
"github.com/mishudark/eventhus/examples/bank"
)
func getConfig() (eventhus.CommandBus, error) {
// register events
reg := eventhus.NewEventRegister()
reg.Set(bank.AccountCreated{})
reg.Set(bank.DepositPerformed{})
reg.Set(bank.WithdrawalPerformed{})
// wire all parts together
return config.NewClient(
config.Mongo("localhost", 27017, "bank"), // event store
config.Nats("nats://ruser:T0pS3cr3t@localhost:4222", false), // event bus
config.AsyncCommandBus(30), // command bus
config.WireCommands(
&bank.Account{}, // aggregate
basic.NewCommandHandler, // command handler
"bank", // event store bucket
"account", // event store subset
bank.CreateAccount{}, // command
bank.PerformDeposit{}, // command
bank.PerformWithdrawal{}, // command
),
)
} Now you are ready to process commands: uuid, _ := utils.UUID()
// 1) Create an account
var account bank.CreateAccount
account.AggregateID = uuid
account.Owner = "mishudark"
commandBus.HandleCommand(account) First, we generate a new Event consumerYou should listen to your {
"id": "0000XSNJG0SB2WDBTATBYEC51P",
"aggregate_id": "0000XSNJG0N0ZVS3YXM4D7ZZ9Z",
"aggregate_type": "Account",
"version": 1,
"type": "AccountCreated",
"data": {
"owner": "mishudark"
}
} Prior Art |
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论