README.md in u-service-0.9.0 vs README.md in u-service-0.10.0
- old
+ new
@@ -11,14 +11,15 @@
- [μ-service (Micro::Service)](#%ce%bc-service-microservice)
- [Required Ruby version](#required-ruby-version)
- [Installation](#installation)
- [Usage](#usage)
- [How to create a Service Object?](#how-to-create-a-service-object)
- - [How to use the Service Object result hooks?](#how-to-use-the-service-object-result-hooks)
+ - [How to use the result hooks?](#how-to-use-the-result-hooks)
- [How to create a pipeline of Service Objects?](#how-to-create-a-pipeline-of-service-objects)
- [What is a strict Service Object?](#what-is-a-strict-service-object)
- [How to validate Service Object attributes?](#how-to-validate-service-object-attributes)
+ - [It's possible to compose pipelines with other pipelines?](#its-possible-to-compose-pipelines-with-other-pipelines)
- [Development](#development)
- [Contributing](#contributing)
- [License](#license)
- [Code of Conduct](#code-of-conduct)
@@ -62,10 +63,11 @@
#====================#
# Calling a service #
#====================#
result = Multiply.call(a: 2, b: 2)
+
p result.success? # true
p result.value # 4
# Note:
# The result of a Micro::Service#call
@@ -74,24 +76,26 @@
#----------------------------#
# Calling a service instance #
#----------------------------#
result = Multiply.new(a: 2, b: 3).call
+
p result.success? # true
p result.value # 6
#===========================#
# Verify the result failure #
#===========================#
result = Multiply.call(a: '2', b: 2)
+
p result.success? # false
p result.failure? # true
p result.value # :invalid_data
```
-### How to use the Service Object result hooks?
+### How to use the result hooks?
```ruby
class Double < Micro::Service::Base
attributes :number
@@ -133,59 +137,84 @@
### How to create a pipeline of Service Objects?
```ruby
module Steps
class ConvertToNumbers < Micro::Service::Base
- attribute :relation
+ attribute :numbers
def call!
- if relation.all? { |value| String(value) =~ /\d+/ }
- Success(numbers: relation.map(&:to_i))
+ if numbers.all? { |value| String(value) =~ /\d+/ }
+ Success(numbers: numbers.map(&:to_i))
else
- Failure('relation must contain only numbers')
+ Failure('numbers must contain only numeric types')
end
end
end
class Add2 < Micro::Service::Strict
attribute :numbers
def call!
- Success(numbers.map { |number| number + 2 })
+ Success(numbers: numbers.map { |number| number + 2 })
end
end
class Double < Micro::Service::Strict
attribute :numbers
def call!
- Success(numbers.map { |number| number * 2 })
+ Success(numbers: numbers.map { |number| number * 2 })
end
end
+
+ class Square < Micro::Service::Strict
+ attribute :numbers
+
+ def call!
+ Success(numbers: numbers.map { |number| number * number })
+ end
+ end
end
+#=================================================#
+# Creating a pipeline using the collection syntax #
+#=================================================#
+
Add2ToAllNumbers = Micro::Service::Pipeline[
Steps::ConvertToNumbers,
Steps::Add2
]
-# An alternative way to declare pipelines within classes.
+result = Add2ToAllNumbers.call(numbers: %w[1 1 2 2 3 4])
+p result.success? # true
+p result.value # {:numbers => [3, 3, 4, 4, 5, 6]}
+
+#=======================================================#
+# An alternative way to create a pipeline using classes #
+#=======================================================#
+
class DoubleAllNumbers
include Micro::Service::Pipeline
pipeline Steps::ConvertToNumbers, Steps::Double
end
-result = Add2ToAllNumbers.call(relation: %w[1 1 2 2 3 4])
+DoubleAllNumbers
+ .call(numbers: %w[1 1 b 2 3 4])
+ .on_failure { |message| p message } # "numbers must contain only numeric types"
-p result.success? # true
-p result.value # [3, 3, 4, 4, 5, 6]
+#=================================================================#
+# Another way to create a pipeline using the composition operator #
+#=================================================================#
-DoubleAllNumbers
- .call(relation: %w[1 1 b 2 3 4])
- .on_failure { |message| p message } # "relation must contain only numbers"
+SquareAllNumbers =
+ Steps::ConvertToNumbers >> Steps::Square
+
+SquareAllNumbers
+ .call(numbers: %w[1 1 2 2 3 4])
+ .on_success { |value| p value[:numbers] } # [1, 1, 4, 4, 9, 16]
```
### What is a strict Service Object?
A: Is a service object which will require all keywords (attributes) on its initialization.
@@ -246,9 +275,71 @@
# Note:
# There is a strict variation for Micro::Service::WithValidation
# Use Micro::Service::Strict::Validation if do you want this behavior.
```
+
+### It's possible to compose pipelines with other pipelines?
+
+Answer: Yes
+
+```ruby
+module Steps
+ class ConvertToNumbers < Micro::Service::Base
+ attribute :numbers
+
+ def call!
+ if numbers.all? { |value| String(value) =~ /\d+/ }
+ Success(numbers: numbers.map(&:to_i))
+ else
+ Failure('numbers must contain only numeric types')
+ end
+ end
+ end
+
+ class Add2 < Micro::Service::Strict
+ attribute :numbers
+
+ def call!
+ Success(numbers: numbers.map { |number| number + 2 })
+ end
+ end
+
+ class Double < Micro::Service::Strict
+ attribute :numbers
+
+ def call!
+ Success(numbers: numbers.map { |number| number * 2 })
+ end
+ end
+
+ class Square < Micro::Service::Strict
+ attribute :numbers
+
+ def call!
+ Success(numbers: numbers.map { |number| number * number })
+ end
+ end
+end
+
+Add2ToAllNumbers = Steps::ConvertToNumbers >> Steps::Add2
+DoubleAllNumbers = Steps::ConvertToNumbers >> Steps::Double
+SquareAllNumbers = Steps::ConvertToNumbers >> Steps::Square
+DoubleAllNumbersAndAdd2 = DoubleAllNumbers >> Steps::Add2
+SquareAllNumbersAndAdd2 = SquareAllNumbers >> Steps::Add2
+DoubleAllNumbersAndSquareThem = DoubleAllNumbers >> SquareAllNumbersAndAdd2
+SquareAllNumbersAndDoubleThem = SquareAllNumbersAndAdd2 >> DoubleAllNumbers
+
+DoubleAllNumbersAndSquareThem
+ .call(numbers: %w[1 1 2 2 3 4])
+ .on_success { |value| p value[:numbers] } # [6, 6, 18, 18, 38, 66]
+
+SquareAllNumbersAndDoubleThem
+ .call(numbers: %w[1 1 2 2 3 4])
+ .on_success { |value| p value[:numbers] } # [6, 6, 12, 12, 22, 36]
+```
+
+Note: You can blend any of the [syntaxes/approaches to create the pipelines](#how-to-create-a-pipeline-of-service-objects)) - [examples](https://github.com/serradura/u-service/blob/master/test/micro/service/pipeline/blend_test.rb#L7-L34).
## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.