EventStoreClient

An easy-to use API client for connecting ruby applications with https://eventstore.org/

Installation

Add this line to your application's Gemfile:

gem 'event_store_client'

And then execute:

$ bundle

Or install it yourself as:

$ gem install event_store_client

Usage

EventStore engine setup

  1. Download Event Store From https://eventstore.org/downloads/ or docker

docker pull eventstore/eventstore

  1. Run the Event Store server

docker run --name eventstore -it -p 2113:2113 -p 1113:1113 eventstore/eventstore

  1. Set Basic HTTP auth enviornment variables #below are defaults
    • export EVENT_STORE_USER=admin
    • export EVENT_STORE_PASSWORD=changeit

Ref: https://eventstore.org/docs/http-api/security

  1. Login to admin panel http://localhost:2113 and enable Projections for Event-Types

Configure EventStoreClient

Before you start, add this to the initializer or to the top of your script:

EventStoreClient.configure

Create Dummy event and dummy Handler

To test out the behavior, you'll need a sample event and handler to work with:

# Sample Event using dry-struct (recommended)
require 'dry-struct'
class SomethingHappened < Dry::Struct
  attribute :data, EventStoreClient::Types::Strict::Hash
  attribute :metadata, EventStoreClient::Types::Strict::Hash
end

# Sample Event without types check (not recommended)

class SomethingHappened < Dry::Struct
  attr_reader :data, :metadata

  private

  def initialize(data: {}, metadata: {})
    @data = data
    @metadata = 
  end
end

event = SomethingHappened.new(
  data: { user_id: SecureRandom.uuid, title: "Something happened" },
  metadata: {}
)

Now create a handler. It can be anything, which responds to a call method with an event being passed as an argument.

class DummyHandler
  def self.call(event)
    puts "Handled #{event.class.name}"
  end
end

Usage

# initialize the client
client = EventStoreClient::Client.new

Publishing events

client.publish(stream: 'newstream', events: [event])

Reading from a stream

events = client.read('newstream')

**Changing reading direction

events = client.read('newstream', direction: 'backward') #default 'forward'

Subscribing to events

Using automatic pooling

client.subscribe(DummyHandler, to: [SomethingHappened])

# now try to publish several events
10.times { client.publish(stream: 'newstream', events: [event]) }

You can also publish multiple events at once

events = (1..10).map { event }
client.publish(stream: 'newstream', events: events)

# .... wait a little bit ... Your handler should be called for every single event you publish

Stop pooling

client.stop_pooling

Contributing

Do you want to contribute? Welcome!

  1. Fork repository
  2. Create Issue
  3. Create PR ;)

License

The gem is available as open source under the terms of the MIT License.