README.md in transflow-0.0.2 vs README.md in transflow-0.1.0
- old
+ new
@@ -28,12 +28,12 @@
- a business transaction doesn't have any state
- each operation shouldn't accumulate state, instead it should receive an input and return
an output without causing any side-effects
- the only interface of a an operation is `#call(input)`
- each operation provides a meaningful functionality and can be reused
-- each operation can broadcast its result (TODO)
-- external message consumers can listen to a transaction object for specific events (TODO)
+- each operation can broadcast its result
+- external message consumers can listen to a transaction object for specific events
## Why?
The rationale for this project is quite simple - every use-case in an application
can be described as a series of processing steps where some input is turned into
@@ -51,58 +51,104 @@
yet but *probably* using pub/sub for that will do the work as we can register an
error listener that can simply gather errors and return it as a result.
## Synopsis
+Using Transflow is ridiculously simple as it doesn't make much assumptions about
+your code. You provide container with operations and they simply need to respond
+to `#call(input)` and return output or raise an error if something went wrong.
+
+### Defining a simple flow
+
``` ruby
DB = []
container = {
- validate: -> input { raise "name nil" if input[:name].nil? },
+ validate: -> input { input[:name].nil? ? raise("name nil") : input },
persist: -> input { DB << input[:name] }
}
-my_business_flow = Transflow(container: container) do
- step(:validate) { step(:persist) }
-end
+my_business_flow = Transflow(container: container) { steps :validate, :persist }
my_business_flow[{ name: 'Jane' }]
puts DB.inspect
# ["Jane"]
+```
-## The same but with events
+## Defining a flow with event publishers
-NOTIFICATIONS = []
+In many cases an individual operation may require additional behavior to be
+triggered. This can be easily achieved with a pub/sub mechanism. Transflow
+provides that mechanism through the wonderful `wisper` gem which is used under
+the hood.
-class Notify
- def persist_success(user)
+``` ruby
+DB = []
+
+NOTIFICATIONS = [] # just for the sake of the example
+
+class UserPersistListener
+ def self.persist_success(user)
NOTIFICATIONS << "#{user} persisted"
end
- def persist_failure(user, err)
+ def self.persist_failure(user, err)
# do sth about that
end
end
my_business_flow = Transflow(container: container) do
step(:validate) { step(:persist, publish: true) }
end
-notify = Notify.new
+my_business_flow.subscribe(persist: UserPersistListener)
-my_business_flow.subscribe(persist: notify)
-
my_business_flow[{ name: 'Jane' }]
puts DB.inspect
# ["Jane"]
puts NOTIFICATIONS.inspect
# ["Jane persisted"]
```
+### Passing additional arguments
+
+Another common requirement is to pass aditional arguments that we don't have in
+the moment of defining our flow. Fortunately Transflow allows you to pass any
+arguments in the moment you call the transaction. Those arguments will be curried
+which means you must use either procs as your operation or an object that responds
+to `curry`. This limitation will be removed soon.
+
+``` ruby
+DB = []
+
+operations = {
+ preprocess_input: -> input { { name: input['name'], email: input['email'] } },
+ # let's say this one needs additional argument called `email`
+ validate_input: -> email, input { input[:email] == email ? input : raise('ops') },
+ persist_input: -> input { DB << input[:name] }
+}
+
+transflow = Transflow(container: operations) do
+ step :preprocess, with: :preprocess_input do
+ step :validate, with: :validate_input do
+ step :persist, with: :persist_input
+ end
+ end
+end
+
+input = { 'name' => 'Jane', 'email' => 'jane@doe.org' }
+
+# here we say "for `validate` operation curry this additional argument
+transflow[input, validate: 'jane@doe.org']
+
+puts DB.inspect
+# ["Jane"]
+```
+
## Installation
Add this line to your application's Gemfile:
```ruby
@@ -115,18 +161,14 @@
Or install it yourself as:
$ gem install transflow
-## Usage
-
-TODO: Write usage instructions here
-
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
-Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/transflow.
+Bug reports and pull requests are welcome on GitHub at https://github.com/solnic/transflow.