u-service 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/README.md +6 -1
- data/comparisons/interactor.rb +57 -0
- data/comparisons/u-service.rb +61 -0
- data/lib/micro/service/pipeline.rb +18 -1
- data/lib/micro/service/version.rb +1 -1
- data/test.sh +6 -2
- data/u-service.gemspec +1 -2
- metadata +8 -21
- data/Gemfile.lock +0 -32
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e760358632fb06d0fb235f3b01723b1de144c21be568f7db9bca62b7e9b1910b
|
4
|
+
data.tar.gz: 7601fde72507d36673a6868a29b2ce382c8e1ce910514530c275ffb8bb6ec1b5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd4ea2da734b495a14fcfdf2c42513eb80d5cd677910c8b84eb0e093effaee151c124393f25a08bc2e41c249d50aa0022b15a734e55aa6fccd24755d9b4be236
|
7
|
+
data.tar.gz: 81981c5a33bb3558f40a233cc0e5112cda17c2b2938ee3106cda1ec2dce7b98eddd384b58dbd2e6a4ae29e9c2e86ac4fb23c2d3b61b64cf485669ac6d0779845
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -8,6 +8,11 @@
|
|
8
8
|
|
9
9
|
Create simple and powerful service objects.
|
10
10
|
|
11
|
+
The main goals of this project are:
|
12
|
+
1. The smallest possible learning curve.
|
13
|
+
2. Referential transparency and data integrity.
|
14
|
+
3. No callbacks, compose a pipeline of service objects to represents complex business logic. (input >> process/transform >> output)
|
15
|
+
|
11
16
|
- [μ-service (Micro::Service)](#%ce%bc-service-microservice)
|
12
17
|
- [Required Ruby version](#required-ruby-version)
|
13
18
|
- [Installation](#installation)
|
@@ -342,7 +347,7 @@ Note: You can blend any of the [syntaxes/approaches to create the pipelines](#ho
|
|
342
347
|
|
343
348
|
## Development
|
344
349
|
|
345
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
350
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `./test.sh` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
346
351
|
|
347
352
|
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).
|
348
353
|
|
@@ -0,0 +1,57 @@
|
|
1
|
+
class CreateResponse
|
2
|
+
include Interactor
|
3
|
+
|
4
|
+
def call
|
5
|
+
responder = context.responder
|
6
|
+
|
7
|
+
survey_response = responder.survey_responses.build(
|
8
|
+
response_text: context.answers[:text],
|
9
|
+
rating: answers[:rating]
|
10
|
+
survey: context.survey
|
11
|
+
)
|
12
|
+
|
13
|
+
if survey_response.save
|
14
|
+
context.survey_response = survey_response
|
15
|
+
else
|
16
|
+
context.fail!(errors: survey_response.errors)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class AddRewardPoints
|
22
|
+
include Interactor
|
23
|
+
|
24
|
+
def call
|
25
|
+
reward_account = context.responder.reward_account
|
26
|
+
|
27
|
+
reward_account.balance += context.survey.reward_points
|
28
|
+
|
29
|
+
unless reward_account.save
|
30
|
+
context.fail!(errors: reward_account.errors)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class SendNotifications
|
36
|
+
include Interactor
|
37
|
+
|
38
|
+
def call
|
39
|
+
sender = context.survey.sender
|
40
|
+
|
41
|
+
SurveyMailer.delay.notify_responder(context.responder.id)
|
42
|
+
SurveyMailer.delay.notify_sender(sender.id)
|
43
|
+
|
44
|
+
unless sender.add_survey_response_notification
|
45
|
+
context.fail!(errors: sender.errors)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class ReplyToSurvey
|
51
|
+
include Interactor::Organizer
|
52
|
+
|
53
|
+
organize CreateResponse, AddRewardPoints, SendNotifications
|
54
|
+
end
|
55
|
+
|
56
|
+
# https://gist.githubusercontent.com/raderj89/cbb84b1f75e67087388bc4cdbe617138/raw/a39c3ba6b416ac3919cc7d32bfa58e82211f24ef/interactor_example.rb
|
57
|
+
# https://medium.com/reflektive-engineering/from-service-objects-to-interactors-db7d2bb7dfd9
|
@@ -0,0 +1,61 @@
|
|
1
|
+
class CreateResponse < Micro::Service::Strict
|
2
|
+
attributes :responder, :answers, :survey
|
3
|
+
|
4
|
+
def call!
|
5
|
+
survey_response = responder.survey_responses.build(
|
6
|
+
response_text: answers[:text],
|
7
|
+
rating: answers[:rating]
|
8
|
+
survey: survey
|
9
|
+
)
|
10
|
+
|
11
|
+
return Success { attributes(:responder, :survey) } if survey_response.save
|
12
|
+
|
13
|
+
Failure(:survey_response) { survey_response.errors }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class AddRewardPoints < Micro::Service::Strict
|
18
|
+
attributes :responder, :survey
|
19
|
+
|
20
|
+
def call!
|
21
|
+
reward_account = responder.reward_account
|
22
|
+
reward_account.balance += survey.reward_points
|
23
|
+
|
24
|
+
return Success { attributes(:responder, :survey) } if reward_account.save
|
25
|
+
|
26
|
+
Failure(:reward_account) { reward_account.errors }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class SendNotifications < Micro::Service::Strict
|
31
|
+
attributes :responder, :survey
|
32
|
+
|
33
|
+
def call!
|
34
|
+
sender = survey.sender
|
35
|
+
|
36
|
+
SurveyMailer.delay.notify_responder(responder.id)
|
37
|
+
SurveyMailer.delay.notify_sender(sender.id)
|
38
|
+
|
39
|
+
return Success { attributes(:survey) } if sender.add_survey_response_notification
|
40
|
+
|
41
|
+
Failure(:sender) { sender.errors }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
ReplyToSurvey = CreateResponse >> AddRewardPoints >> SendNotifications
|
46
|
+
|
47
|
+
# or
|
48
|
+
|
49
|
+
ReplyToSurvey = Micro::Service::Pipeline[
|
50
|
+
CreateResponse,
|
51
|
+
AddRewardPoints,
|
52
|
+
SendNotifications
|
53
|
+
]
|
54
|
+
|
55
|
+
# or
|
56
|
+
|
57
|
+
class ReplyToSurvey
|
58
|
+
include Micro::Service::Pipeline
|
59
|
+
|
60
|
+
pipeline CreateResponse, AddRewardPoints, SendNotifications
|
61
|
+
end
|
@@ -41,10 +41,17 @@ module Micro
|
|
41
41
|
private
|
42
42
|
|
43
43
|
def initial_result(arg)
|
44
|
+
return arg.call if arg_to_call?(arg)
|
44
45
|
return arg if arg.is_a?(Micro::Service::Result)
|
45
46
|
|
46
47
|
Micro::Service::Result::Success[value: arg]
|
47
48
|
end
|
49
|
+
|
50
|
+
def arg_to_call?(arg)
|
51
|
+
return true if arg.is_a?(Micro::Service::Base) || arg.is_a?(Reducer)
|
52
|
+
return true if arg.is_a?(Class) && (arg < Micro::Service::Base || arg < Micro::Service::Pipeline)
|
53
|
+
return false
|
54
|
+
end
|
48
55
|
end
|
49
56
|
|
50
57
|
module ClassMethods
|
@@ -67,9 +74,19 @@ module Micro
|
|
67
74
|
Reducer.build(args)
|
68
75
|
end
|
69
76
|
|
77
|
+
UNDEFINED_PIPELINE = "This class hasn't declared its pipeline. Please, use the `pipeline()` macro to define one.".freeze
|
78
|
+
|
79
|
+
private_constant :UNDEFINED_PIPELINE
|
80
|
+
|
70
81
|
def self.included(base)
|
71
82
|
base.extend(ClassMethods)
|
72
|
-
base.class_eval(
|
83
|
+
base.class_eval(<<-RUBY)
|
84
|
+
def initialize(options)
|
85
|
+
@options = options
|
86
|
+
pipeline = self.class.__pipeline__
|
87
|
+
raise ArgumentError, UNDEFINED_PIPELINE unless pipeline
|
88
|
+
end
|
89
|
+
RUBY
|
73
90
|
end
|
74
91
|
|
75
92
|
def call
|
data/test.sh
CHANGED
data/u-service.gemspec
CHANGED
@@ -39,7 +39,6 @@ Gem::Specification.new do |spec|
|
|
39
39
|
|
40
40
|
spec.add_runtime_dependency 'u-attributes', '~> 1.1'
|
41
41
|
|
42
|
-
spec.add_development_dependency 'bundler'
|
42
|
+
spec.add_development_dependency 'bundler'
|
43
43
|
spec.add_development_dependency 'rake', '~> 10.0'
|
44
|
-
spec.add_development_dependency 'minitest', '~> 5.0'
|
45
44
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: u-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Serradura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-08-
|
11
|
+
date: 2019-08-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: u-attributes
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,20 +52,6 @@ dependencies:
|
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '10.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: minitest
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '5.0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '5.0'
|
69
55
|
description: Create simple and powerful service objects.
|
70
56
|
email:
|
71
57
|
- rodrigo.serradura@gmail.com
|
@@ -79,12 +65,13 @@ files:
|
|
79
65
|
- ".travis.yml"
|
80
66
|
- CODE_OF_CONDUCT.md
|
81
67
|
- Gemfile
|
82
|
-
- Gemfile.lock
|
83
68
|
- LICENSE.txt
|
84
69
|
- README.md
|
85
70
|
- Rakefile
|
86
71
|
- bin/console
|
87
72
|
- bin/setup
|
73
|
+
- comparisons/interactor.rb
|
74
|
+
- comparisons/u-service.rb
|
88
75
|
- lib/micro/service.rb
|
89
76
|
- lib/micro/service/base.rb
|
90
77
|
- lib/micro/service/pipeline.rb
|
data/Gemfile.lock
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
u-service (0.10.0)
|
5
|
-
u-attributes (~> 1.1)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
docile (1.3.2)
|
11
|
-
json (2.2.0)
|
12
|
-
minitest (5.11.3)
|
13
|
-
rake (10.5.0)
|
14
|
-
simplecov (0.17.0)
|
15
|
-
docile (~> 1.1)
|
16
|
-
json (>= 1.8, < 3)
|
17
|
-
simplecov-html (~> 0.10.0)
|
18
|
-
simplecov-html (0.10.2)
|
19
|
-
u-attributes (1.2.0)
|
20
|
-
|
21
|
-
PLATFORMS
|
22
|
-
ruby
|
23
|
-
|
24
|
-
DEPENDENCIES
|
25
|
-
bundler (~> 1.17)
|
26
|
-
minitest (~> 5.0)
|
27
|
-
rake (~> 10.0)
|
28
|
-
simplecov
|
29
|
-
u-service!
|
30
|
-
|
31
|
-
BUNDLED WITH
|
32
|
-
1.17.3
|