Rails Event Store v0.34.0 Release Notes

Release Date: 2018-11-23 // over 5 years ago
  • ๐Ÿš… RailsEventStore

    Add: New read API to filter read events by type event_store.read.of_type [#472]

     event\_store = RailsEventStore::Client.newTweetPosted = Class.new(RubyEventStore::Event) TweetRetweeted = Class.new(RubyEventStore::Event) TweetLiked = Class.new(RubyEventStore::Event) event\_store.publish(TweetPosted.new(event\_id: '54994b0e-4fe3-4d58-8ffe-16755fcbc635', data: { message: 'Hello from @RailsEventStore!' })) event\_store.publish(TweetRetweeted.new(event\_id: '3d67e05d-04c6-4771-bdcc-d22d385390cb', data: { ... })) event\_store.read.of\_type([TweetPosted]).to\_a # =\> [#\<TweetPosted:0x00007fce3cab1a00 @event\_id="54994b0e-4fe3-4d58-8ffe-16755fcbc635", @metadata=#\<RubyEventStore::Metadata:0x00007fce3cab19b0 @h={:timestamp=\>2018-10-12 17:50:27 UTC}\>, @data={:message=\>"Hello from @RailsEventStore!"}\>] event\_store.read.of\_type([TweetLiked]).to\_a # =\> []
    

    ๐Ÿ”ง Change: RailsEventStore::Event#initialize no longer calls to_h on data: argument. Default value for this argument stays effectively the same (which is {}). One now has an option to pass struct or any other object as data, provided your configured mapper knows how to handle it for serialization [#395, #480]

    Add: Bring back RailsEventStore::Browser. This time not as a separate gem, rather a thin wrapper over RubyEventStore::Browser. It is no longer needed with rails_event_store to add browser as an explicit dependency. As a bonus RailsEventStore::Browser already has event_store_locator: pre-configured to typical Rails.configuration.event_store [#497]

    ๐Ÿš… The whole process of mounting Browser in Rails is as simple as following:

    Rails.application.routes.draw do mount RailsEventStore::Browser =\> '/res' if Rails.env.development?end
    

    ๐Ÿ’Ž RubyEventStore

    Add: New read API to filter read events by type event_store.read.of_type [#472]

     event\_store = RailsEventStore::Client.newTweetPosted = Class.new(RubyEventStore::Event) TweetRetweeted = Class.new(RubyEventStore::Event) TweetLiked = Class.new(RubyEventStore::Event) event\_store.publish(TweetPosted.new(event\_id: '54994b0e-4fe3-4d58-8ffe-16755fcbc635', data: { message: 'Hello from @RailsEventStore!' })) event\_store.publish(TweetRetweeted.new(event\_id: '3d67e05d-04c6-4771-bdcc-d22d385390cb', data: { ... })) event\_store.read.of\_type([TweetPosted]).to\_a # =\> [#\<TweetPosted:0x00007fce3cab1a00 @event\_id="54994b0e-4fe3-4d58-8ffe-16755fcbc635", @metadata=#\<RubyEventStore::Metadata:0x00007fce3cab19b0 @h={:timestamp=\>2018-10-12 17:50:27 UTC}\>, @data={:message=\>"Hello from @RailsEventStore!"}\>] event\_store.read.of\_type([TweetLiked]).to\_a # =\> []
    

    Fix: Do not compare object instances of event id while looking for streams of event [#492]

    Fix: read.events([]) returning whole dataset of stored events [#498]

    ๐Ÿ”ง Change: RubyEventStore::Event#initialize no longer calls to_h on data: argument. Default value for this argument stays effectively the same (which is {}). One now has an option to pass struct or any other object as data, provided your configured mapper knows how to handle it for serialization [#395, #480]

    Add: Explicit RubyEventStore::ProtobufEncodingFailed raised when event's data is not serializable by RubyEventStore::Mappers::Protobuf [#481]

    Fix: RubyEventStore::Mappers::Default#serialized_record_to_event now symbolizes metadata keys. This helps when your serializer cannot distinguish symbols from strings (i.e. when you choose JSON as a serializer) [#367, #489]

    0๏ธโƒฃ When using RubyEventStore::Mappers::Default.new(serializer: JSON) it is advisable to make following or similar adjustment to your base Event class. That way you'll shield yourself from JSON turning symbols intro strings:

    class MyEvent \< RailsEventStore::Eventdef dataActiveSupport::HashWithIndifferentAccess.new(super) endendOrderPlaced = Class.new(MyEvent)
    

    ๐Ÿ”ง More on configuring a different serializer section.

    ๐Ÿš… RailsEventStoreActiveRecord

    Add: Support for filtering by event type [#472]

    ๐ŸŽ Add: New migration generator to add an index on event_type attribute. Strongly recommended to apply if you plan to use filtering by event types โ€” otherwise performance when using event_store.read.of_type(...) might be degraded. Added in default schema creation generator for new deployments. [#472]

    โš™ Running migration:

    rails g rails_event_store_active_record:index_by_event_type
    rails db:migrate
    

    ๐Ÿ‘‰ Feel free to inspect and change generated migration. Make sure to check if your RDBMS can run this migration online and whether that meets your operational requirements.
    https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html#online-ddl-index-operations

    Add: New migration generator to add a limit on event_id attribute in event_store_events_in_streams table. Applicable for MySQL and Sqlite databases. This migration is skipped on PostgreSQL. Feel free to skip this migration if it's too problematic to apply on existing data. Added in default schema creation generator for new deployments. [#479]

    โš™ Running migration:

    rails g rails_event_store_active_record:limit_for_event_id
    rails db:migrate
    

    ๐Ÿ‘‰ Feel free to inspect and change generated migration. Make sure to check if your RDBMS can run this migration online and whether that meets your operational requirements.
    https://dev.mysql.com/doc/refman/5.7/en/innodb-online-ddl-operations.html#online-ddl-column-operations

    Add: to_a implementation for read specification. Allows to avoid commonly used event_store.read.each.to_a by just using event_store.read.to_a. Also added to_a & first methods to BatchEnumerator. Closes #496. [#499]

    AggregateRoot

    • no changes

    ๐Ÿš… RailsEventStore::RSpec

    • no changes

    BoundedContext

    • no changes

    ๐Ÿ’Ž RubyEventStore::Browser

    Fix: Ensure Browser works with non-default metadata serialization [#491]

    Change: Provide default arguments to RubyEventStore::Browser::App.for for less required setup in typical use case [#483]

    Now only event_store_locator: is required when mounting Browser inside existing app.

    require 'ruby\_event\_store/browser/app'Rails.application.routes.draw do mount RubyEventStore::Browser::App.for( event\_store\_locator: -\> { Rails.configuration.event\_store }, ) =\> '/res' if Rails.env.development?end
    

    ๐Ÿ’Ž RubyEventStore::ROM

    • Support for filtering by event type [#472]

    ๐Ÿš… RailsEventStoreActiveRecord::Legacy

    • Support for filtering by event type [#472]