Skip to content

CQRS/Event Sourcingのためのイベントストア機能をSwiftで提供する

License

Notifications You must be signed in to change notification settings

lemo-nade-room/event-store-adaptor-swift

Repository files navigation

event-store-adapter-swift

License Testing Status

このライブラリは、DynamoDBなどのデータストアを利用し、CQRS/Event Sourcingのためのイベントストア機能をSwiftで提供するためのライブラリです。
Rust版のEvent Store Adapter (event-store-adapter-rs)を参考に実装されています。

使い方

EventStoreを使えば、Event Sourcing対応リポジトリを簡単に実装できます。

import EventStoreAdaptor

struct UserAccountRepository<EventStore: EventStoreAdaptor.EventStore>
where
    EventStore.Aggregate == UserAccount,
    EventStore.Event == UserAccount.Event,
    EventStore.AggregateId == UserAccount.Id
{
    var eventStore: EventStore
    
    func storeEvent(event: UserAccount.Event, version: Int) async throws {
        try await eventStore.persistEvent(event: event, version: version)
    }
    
    func storeEventAndSnapshot(event: UserAccount.Event, snapshot: UserAccount) async throws {
        try await eventStore.persistEventAndSnapshot(event: event, aggregate: snapshot)
    }
    
    func findById(id: UserAccount.Id) async throws -> UserAccount? {
        guard let snapshot = try await eventStore.getLatestSnapshotById(aggregateId: id) else {
            return nil
        }
        let events = eventStore.getEventsByIdSinceSequenceNumber(
            aggregateId: id,
            sequenceNumber: snapshot.sequenceNumber + 1
        )
        return UserAccount.replay(events, snapshot)
    }
}

以下はリポジトリの使用例です。

let eventStore = EventStoreForDynamoDB<UserAccount, UserAccount.Event>(
    client: try await DynamoDBClient(),
    journalTableName: journalTableName,
    journalAidIndexName: journalAidIndexName,
    snapshotTableName: snapshotTableName,
    snapshotAidIndexName: snapshotAidIndexName,
    shardCount: 64
)

let repository = UserAccountRepository(eventStore: eventStore)

guard var userAccount = try await repository.findById(id: userAccountId) else {
    fatalError()
}

let userAccountEvent = try userAccount.rename(name: "foo")

// Store the new event without a snapshot
try await repository.storeEvent(event: userAccountEvent, version: userAccount.version)

// Store the new event with a snapshot
// try await repository.storeEventAndSnapshot(event: userAccountEvent, snapshot: userAccount)

テーブル仕様

docs/DATABASE_SCHEMA.ja.mdを参照してください。

About

CQRS/Event Sourcingのためのイベントストア機能をSwiftで提供する

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages