Releases: RailsEventStore/rails_event_store
v0.30.0
RailsEventStore
-
Change: Introduce new read API with fluent interface [#184]
Was:
client = Rails.configuration.event_store client.read_all_streams_forward(count: count, start: start) client.read_all_streams_backward(count: count, start: start) client.read_events_forward(stream_name, count: count, start: start) client.read_events_backward(stream_name, count: count, start: start) client.read_stream_events_forward(stream_name) client.read_stream_events_backward(stream_name)
Is now:
client = Rails.configuration.event_store client.read.from(start).limit(count).each.to_a client.read.from(start).limit(count).backward.each.to_a client.read.stream(stream_name).from(start).limit(count).each.to_a client.read.stream(stream_name).from(start).limit(count).backward.each.to_a client.read.stream(stream_name).each.to_a client.read.stream(stream_name).backward.each.to_a
Building query starts from
read
. You can appendlimit
,stream
,forward
,backward
andfrom
to refine the query further. Finally callingeach
executes the read, returning enumerator.By default
forward
andfrom(:head)
are applied when you don't specify anything. Beware, queries are not bounded unless you say so withlimit
.Old reader methods are now deprecated and will be removed in future releases.
To help with migration:- warnings remind of deprecated API usage with some hints on new API equivalent
- script to rewrite old API to new one is distributed with
ruby_event_store
gem
Usage for dry run that outputs changes to stderr without modifying source:
bundle exec res-deprecated-read-api-migrator FILE_OR_DIRECTORY
Usage for in-place file modification:
bundle exec res-deprecated-read-api-migrator -m FILE_OR_DIRECTORY
When in doubt, you can also use this script to translate queries from STDIN, i.e.
bundle exec res-deprecated-read-api-migrator -e 'client.read_all_streams_forward'
-
Add: Batch API to retrieve data in batches of given size (by default of 100) [#349]
Used internally inRailsEventStore::Projection
andAggregateRoot
.Usage:
client = Rails.configuration.event_store client.read.in_batches.each do |event| # do something with event, handling batches transparently end client.read.in_batches.each_batch do |batch| # do something with batch of default size end client.read.in_batches_of(1000).each_batch do |batch| # do something with batch of size 1000 end
-
Add:
RailsEventStore::Event#correlate_with(event_or_command)
,RailsEventStore::Event#correlation_id
andRailsEventStore::Event#causation_id
. You can now correlate messages together which makes debugging much easier [#364] -
Remove: Deprecated
subscribe
andsubscribe_to_all_events
syntax is no more [#350]
RubyEventStore
- Change: Introduce new read API with fluent interface. See usage and migration steps above [#184]
- Add: Introduce batch API. See usage and migration steps above [#349]
- Add:
RubyEventStore::Event#correlate_with(event_or_command)
,RubyEventStore::Event#correlation_id
andRubyEventStore::Event#causation_id
. You can now correlate messages together which makes debugging much easier [#364] - Remove: Deprecated
subscribe
andsubscribe_to_all_events
syntax is no more [#350]
RailsEventStoreActiveRecord
- no changes
AggregateRoot
- Change: Use newly-introduced batch reading API to load stream events. This minimizes the risk of huge aggregates allocating lots of memory when reading aggregate stream [#360]
RailsEventStore::RSpec
-
Add:
have_published(...).from(start)
matcher can now assert on events read from particular starting point in stream. This correlates withclient.read.from(start)
on client read API [c582f2a] -
Add:
have_published(...).strict
andhave_applied(...).strict
matchers to check if only events given as an expectation have been returned and nothing else [6c44cc8, 5e0e548, #119] -
Change: Improve phrasing in documentation format [#358, #355]
-
Change:
have_published
matcher now reads stream events forward (from the oldest published) and without limit. Previously we did have a backward read (from the newest published) up to 100 events in order to avoid situation were lastly published event would not fit in (over 100) and not be matched.expect(event_store).to have_published(FooEvent, BarEvent)
should have published events that have to (be a FooEvent and be a BarEvent)
expect(FooEvent.new(data: { foo: "bar" }, metadata: { timestamp: Time.now })) .to(be_event(FooEvent).with_data(foo: "bar") .and(be_event(FooEvent).with_metadata(timestamp: kind_of(Time))))
should be an event FooEvent (with data including {:foo=>"bar"}) and be an event FooEvent (with metadata including {:timestamp=>kind of Time})
BoundedContext
- no changes
RailsEventStore::Browser
- no changes
RubyEventStore::ROM
- no changes
RailsEventStoreActiveRecord::Legacy
- no changes
v0.29.0
RailsEventStore
- Change: Rewrote the middleware so that it now uses
RubyEventStore::Client#with_metadata
to enrich published events' metadata when using aRailsEventStore::Client
fromRails.application.config.event_store
. By default metadata is enriched withremote_ip
andrequest_id
, you can set your own lambda inrequest_metadata
keyword argument when initializing a client
RubyEventStore
- Add: Added
RubyEventStore::Client#with_metadata
method that enriches all events published inside a block with metadata set with method argument.with_metadata
calls can be nested, in such case metadata from all levels are merged - Change: Deprecated
metadata_proc
keyword argument inRubyEventStore::Client
-with_metadata
method should be used instead
RailsEventStoreActiveRecord
- no changes
AggregateRoot
- no changes
RailsEventStore::RSpec
-
Fix: Matchers now have
description
, making them usable with--format documentation
[#127, #282, #326, #342] -
Fix: Matchers now have
failure_message_when_negated
, making them usable withexpect(...).not_to
[#326, #342]
BoundedContext
- no changes
RailsEventStore::Browser
- no changes
RubyEventStore::ROM
RailsEventStoreActiveRecord::Legacy
- no changes
v0.28.2
RailsEventStore
- no changes
RubyEventStore
- no changes
RailsEventStoreActiveRecord
- no changes
AggregateRoot
- no changes
RailsEventStore::RSpec
- no changes
BoundedContext
- no changes
RailsEventStore::Browser
- no changes
RubyEventStore::ROM
- no changes
RailsEventStoreActiveRecord::Legacy
v0.28.1
RailsEventStore
RubyEventStore
RailsEventStoreActiveRecord
- no changes
AggregateRoot
- no changes
RailsEventStore::RSpec
- no changes
BoundedContext
- no changes
RailsEventStore::Browser
- no changes
RubyEventStore::ROM
- no changes
RailsEventStoreActiveRecord::Legacy
- no changes
v0.28.0
RailsEventStore
-
Add: Support Rails 5.2
-
Change: Mappers (and serializers) now operate above the repository layer. If you have custom mapper or serializer move its configuration. [#257]
Was:
RailsEventStore::Client.new( repository: RailsEventStoreActiveRecord::EventRepository.new( mapper: RubyEventStore::Mappers::Default.new( serializer: JSON ) ) )
is now:
RailsEventStore::Client.new( mapper: RubyEventStore::Mappers::Default.new( serializer: JSON ) )
RubyEventStore
-
Change: Mappers (and serializers) now operate above the repository layer. If you have custom mapper or serializer move its configuration. [#257]
Was:
RubyEventStore::Client.new( repository: RailsEventStoreActiveRecord::EventRepository.new( mapper: RubyEventStore::Mappers::Default.new( serializer: JSON ) ) )
is now:
RubyEventStore::Client.new( mapper: RubyEventStore::Mappers::Default.new( serializer: JSON ) )
-
Add:
NullMapper
mapper. Useful in pair withInMemoryRepository
for faster unit tests. Setup and usage in docs [#321] [#240] -
Fixed: Protobuf mapper can be used with async handlers [#228]
-
Fixed: Documented
InMemoryRepository
which can be used for faster unit tests [#240] [#321] -
Change:
RubyEventStore#publish_event
,RubyEventStore#publish_events
andRubyEventStore#append_to_stream
now raiseIncorrectStreamData
when passednil
or empty stream name [#267] -
Breaking: Metadata keys are limited to symbols. Metadata values are limited to
[String, Integer, Float, Date, Time, TrueClass, FalseClass]
. UsingHash
, 'Array` or custom objects is no longer supported. [#271] -
Breaking: Using protobuf mapper requires manual migration of columns to binary format [#280]
change_column :event_store_events, :data, :binary, null: true change_column :event_store_events, :metadata, :binary, null: true
-
Breaking: Using protobuf mapper requires adding
protobuf_nested_struct
gem toGemfile
[#280] -
Breaking: When using protobuf mapper, the
event_id
is no longer stored in event'sdata
[#280] -
Breaking: When using protobuf mapper, the
metadata
fields are no longer stored in event'sdata
[#280] -
Breaking: When using protobuf mapper you need to use
RubyEventStore::Proto
class [#280]Was:
event = MyApp::OrderPlaced.new( event_id: "f90b8848-e478-47fe-9b4a-9f2a1d53622b", customer_id: 123, order_id: "K3THNX9" ) event_store.publish_event(event, stream_name: "Order-K3THNX9")
Is now:
event = RubyEventStore::Proto.new( data: MyApp::OrderPlaced.new( customer_id: 123, order_id: "K3THNX9", ) ) event_store.publish_event(event, stream_name: "Order-K3THNX9")
-
Remove: Custom mappers no longer should implement
add_metadata
method [#280] -
Remove: Remove API to get all stream names
RubyEventStore::Client#get_all_streams
(8d7d3bc) -
Breaking: Custom repositories should expect
RubyEventStore::Stream
andRubyEventStore::ExpectedVersion
where previouslystream_name
andexpected_version
primitives were passed, in example:Was:
def append_to_stream(events, stream_name, expected_version) # stream_name # expected_version end
Is now:
def append_to_stream(events, stream, expected_version) # stream.name # expected_version.any? end
-
Breaking: Custom repositories are expected to respond to
read(specification)
and return anEnumerator
. TheRubyEventStore::Specification::Result
struct describes query conditions. This API replaces previous reader methods on repository [#184]:read_events_forward(stream, after_event_id, count)
read_events_backward(stream, before_event_id, count)
read_stream_events_forward(stream)
read_stream_events_backward(stream)
read_all_streams_forward(after_event_id, count)
read_all_streams_backward(before_event_id, count)
RailsEventStoreActiveRecord
- Add: Support Rails 5.2
- Remove:
LegacyEventRepository
has been moved to separaterails_event_store_active_record-legacy
gem, not installed as a dependency. SeeRailsEventStoreActiveRecord::Legacy
section below. - Remove: Remove API to get all stream names
RailsEventStoreActiveRecord::EventRepository
[8d7d3bc] - Change: Restricted access to internal stream
all
with methods not intended to read from global stream. This stream name is an implementation detail ofRailsEventStoreActiveRecord::EventRepository
repository and reading from it using non-global stream API might result in different order of events.RubyEventStore::ReservedInternalName
is raised whenread_events_forward('all')
is used over desiredread_all_streams_forward
.
AggregateRoot
- Change: Dropped dependency on
activesupport
gem [#288]
RailsEventStore::RSpec
- Add: Support Rails 5.2
BoundedContext
- Fix: Generate better folders structure [#243]
- Add: Support Rails 5.2
RailsEventStore::Browser
- Add: Support Rails 5.2
- Change: Remove stream names browsing and start with global stream events as a main screen. This is a workaround to avoid problem with inefficient API when browsing huge number of stream names. [#212, #298]
RubyEventStore::ROM
First release of Ruby Object Model (ROM) implementation of events repository for Ruby Event Store. This version of the ROM adapter supports rom-sql
at this time. It is an alternative to the Active Record events repository implementation from rails_event_store_active_record
gem.
Read the docs to get started.
RailsEventStoreActiveRecord::Legacy
Release of LegacyEventRepository
as a separate gem. This repository has been deprecated and is compatible with single-table database schema we no longer support. If you haven't migrated and you're stuck with events repository schema from version below v0.19
then this is your option to defer it a bit more:
require 'rails_event_store_active_record/legacy'
Rails.application.configure do
config.to_prepare do
Rails.configuration.event_store = RailsEventStore::Client.new(
repository: RailsEventStoreActiveRecord::Legacy::EventRepository.new
)
end
end
v0.27.1
RailsEventStore
- no changes
RubyEventStore
- no changes
RailsEventStoreActiveRecord
- no changes
AggregateRoot
- no changes
RailsEventStore::RSpec
- no changes
BoundedContext
- no changes
RailsEventStore::Browser
- Fix: Re-release with correctly-built Browser javascript that failed when releasing 0.27.0 (#209)
v0.27.0
RailsEventStore
-
Add: Allows providing custom event mapper #154.
This makes possible to use events which don't inherit from
RailsEventStore::Event
. You can now serialize your events however you want: protbuf, messagepack, Apache Avro, BSON, Thrift, Cap’n Proto. It's up to you.Documentation: http://railseventstore.org/docs/mapping_serialization/ and tutorial for using Rails Event Store with Protobuf: http://railseventstore.org/docs/protobuf/ . We are still working on enabling this feature for async handlers
-
Add:
arkency-command_bus
gem is included in dependencies and automatically installed.Documentation: http://railseventstore.org/docs/command_bus/
-
Change: Async handler powered by ActiveJob no longer require custom configuration: #126
Documentation: http://railseventstore.org/docs/subscribe/
-
Breaking: We dropped support for Ruby 2.2. It might continue to work, but we no longer test it and we don't guarantee it anymore.
-
Breaking:
RailsEventStore.event_repository
global configuration option was removed. Pass repository as dependency when initializing the client. - #230Rails.application.configure do config.to_prepare do Rails.configuration.event_store = RailsEventStore::Client.new( repository: YourCustomRepository.new ) end end
Documentation: http://railseventstore.org/docs/repository/
RubyEventStore
-
Add: Allow using
ruby_event_store
with repository fromrails_event_store_active_record
withoutrails
- #236Documentation: http://railseventstore.org/docs/without_rails/
-
Add:
ruby_event_store
no longer usesactive_support
as dependency #232 -
Breaking: We dropped support for Ruby 2.2. It might continue to work, but we no longer test it and we don't guarantee it anymore.
RailsEventStoreActiveRecord
-
Add: Allow using
rails_event_store_active_record
withoutrails
. - #236Documentation: http://railseventstore.org/docs/without_rails/
-
Breaking: We dropped support for Ruby 2.2. It might continue to work, but we no longer test it and we don't guarantee it anymore.
AggregateRoot
- Breaking: We dropped support for Ruby 2.2. It might continue to work, but we no longer test it and we don't guarantee it anymore.
RailsEventStore::RSpec
- Breaking: We dropped support for Ruby 2.2. It might continue to work, but we no longer test it and we don't guarantee it anymore.
BoundedContext
- Breaking: We dropped support for Ruby 2.2. It might continue to work, but we no longer test it and we don't guarantee it anymore.
RailsEventStore::Browser
- Breaking: We dropped support for Ruby 2.2. It might continue to work, but we no longer test it and we don't guarantee it anymore.
v0.26
RailsEventStore
-
Deprecate:
subscribe(handler, array_of_event_types)
is deprecated. Usesubscribe(handler, to: event_types)
instead. Exampleclient = RailsEventStore::Client.new client.subscribe(OrderSummaryEmail.new, to: [OrderPlaced])
-
Deprecate:
subscribe(subscriber, event_types, &task)
has been deprecated. Usewithin(&task).subscribe(subscriber, to: event_types).call
instead. #155 - Example:client = RailsEventStore::Client.new client.within do PlaceOrder.new end.subscribe(OrderSummaryEmail.new, to: [OrderPlaced]).call
-
Deprecate:
subscribe_to_all_events(subscriber, &task)
has been deprecated. Usewithin(&task).subscribe_to_all_events(subscriber).call
instead. #155 - Example:client = RailsEventStore::Client.new client.within do PlaceOrder.new end.subscribe_to_all_events(LogEvents.new).call
-
Fix: Temporary subscribers are thread safe now - #196
-
Fix: Test the gem with newest Rails version. No changes required but the testing infrastructure - #192 #194
-
Add:
subscribe(to:, &subscriber)
API allows passing a subscriber as proc. - #155 #197 - Example:client = RailsEventStore::Client.new client.subscribe(to: [OrderPlaced]) do |ev| order = Order.find(event.data.fetch(:event_id)) OrderMailer.summary(order).deliver_later end
-
Add:
subscribe_to_all_events(&subscriber)
API allows passing a subscriber as proc. - #155 #197 - Example:client = RailsEventStore::Client.new client.subscribe_to_all_events do |ev| Rails.logger.debug(ev.inspect) end
-
Add: Chainable API for temporary subscribers was added. Start with
within(&task)
then callsubscribe
orsubscribe_to_all_events
as many times you want passing either a handler or a block and then callcall
to trigger execution of thetask
with subscribers temporarily subscribed. - #155 #197 - Example:success = 0 failure = 0 client.within do ImportCustomer.call end.subscribe(to: [CustomerImported]) do |_ev| success += 1 end.subscribe(to: [CustomerImportFailed]) do |_ev| failure += 1 end.subscribe_to_all_events do |ev| Rails.logger.debug(ev.inspect) end.call
RubyEventStore
- Deprecate/Add: Same API changes as for RailsEventStore listed above.
- Fix: No more race conditions for
InMemoryAdapter
with multi-threading when used with:any
expected version on the same stream. This more closely resembles production behavior ofRailsEventStoreActiveRecord
repository. #188
RailsEventStoreActiveRecord
- Fix: Testing the gem with newest Rails version - #194
AggregateRoot
-
Add: Support for declarative event handler methods - #171 #190 . You can use
on(event_class, &proc)
to define a new handler method. Example:class Order include AggregateRoot class HasBeenAlreadySubmitted < StandardError; end class HasExpired < StandardError; end def initialize @state = :new end def submit raise HasBeenAlreadySubmitted if state == :submitted raise HasExpired if state == :expired apply OrderSubmitted.new(data: {delivery_date: Time.now + 24.hours}) end def expire apply OrderExpired.new end on OrderSubmitted do |event| @state = :submitted @delivery_date = event.data.fetch(:delivery_date) end on OrderExpired do |_event| @state = :expired end private attr_reader :state end
RailsEventStore::RSpec
- No changes
BoundedContext
- Fix: Testing the gem with newest Rails version - #192
RailsEventStore::Browser
- No changes
v0.25.2
RailsEventStore
- no changes
RubyEventStore
- no changes
RailsEventStoreActiveRecord
- no changes
AggregateRoot
- no changes
RailsEventStore::RSpec
- no changes
BoundedContext
- no changes
RailsEventStore::Browser
- Fix: Excessive encoding of already encoded URLs is no more.
- Fix: Handle dots in stream names on browser backend. Previously last dot part of name could have been interpreted as a format.
v0.25.1
RailsEventStore
- no changes
RubyEventStore
- no changes
RailsEventStoreActiveRecord
- no changes
AggregateRoot
- no changes
RailsEventStore::RSpec
- no changes
BoundedContext
- no changes
RailsEventStore::Browser
- Fix: Encode stream names and event ids for internal links. An unescaped URL with slashes would be incorrectly interpreted by client-side router.