blacksheep 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5e39f0b5524839016bc9a6811e51257f49a2d5f00cf42d3d9fe07ab01de6b602
4
- data.tar.gz: c0d169df550b722a11ffa2aaf7ea0ef5657f3c64ad5f7b8b6ac2c10419ba7ef0
3
+ metadata.gz: 75dfef125950bec755e918dba9e56bf6877ab8a3baedc2e42d16b62e31aa395c
4
+ data.tar.gz: 4ef04a290cd93670d126e910022cada3a16bb446af06eb26e759073c87e2a3b6
5
5
  SHA512:
6
- metadata.gz: 589637c6979dbaebe1756f95ebe0038a7b707059b4a809f56d1d6575bbd4b5e2f8822bb54815e93491f0517b22a71ccb06d690da05b5396ea30fbe6c9acabb59
7
- data.tar.gz: b12064a64112255dc2b75aacf1a3ff2245131c96ccd5a12a863242e5642c10d97096f19010981c97b53940a905988bffd04508d77f337846e24dded666e874de
6
+ metadata.gz: '0084555561e9b92801cf7524379c6e3523eda987a612beb869f8be81abf69c4ebba673ebf609c1310074f7f2d65c954998061cb70701e1052a6efb6507431eeb'
7
+ data.tar.gz: d5e729097addb0df435e051c8289de2e8c0ca06d1d17d1690c630ab251a657d169719b5dc70cde2744537aac5f0cf544d9ee05d2596668151ff306609d5054b2
data/README.md CHANGED
@@ -22,7 +22,108 @@ Or install it yourself as:
22
22
 
23
23
  ## Usage
24
24
 
25
- TODO: Write usage instructions here
25
+ ### Actions
26
+
27
+ Core if blacksheep is the Blacksheep::Action. It provides basic fuctionality to handle rest API actions - but can handle other actions as well. The core methods of Actions are:
28
+
29
+ * #perform, and…
30
+ * #call
31
+
32
+ `#perform` takes a block that is executed with the params passed. #perform has the following api:
33
+ `#perform(params, current_user: (default to nil), **options)`
34
+
35
+ `#call` can be used when a Blacksheep::Action is sublassed as an action processing its opertation in a call method with the same signature of `#perform`
36
+
37
+
38
+ ```ruby
39
+ ##perform sample
40
+ action_result = Blacksheep::Action.new.perform(params) do |params|
41
+ # do somethin with the params that return a `Blacksheep::ActionResult`
42
+ end
43
+
44
+ ##perform sample
45
+ action_result = MyAction.new.call(params, current_user: current_user)
46
+ ```
47
+
48
+ `Blacksheeep::ActionResult` has a data and a status attribute. In case of json api actions its expected to store a json response into the data attribute, and the respective http status into the status attribute.
49
+
50
+
51
+ ### Decorators
52
+
53
+ This alone does not give any benefit. It more interesting to modifiy the action with decorators such as:
54
+
55
+ * `JsonTransformer`
56
+ * `Localizer`
57
+ * `DefaultErrorHandler`
58
+ * `ResultMatcher`
59
+
60
+ The decaorators can be configured globaly by defining them in an initializer.
61
+
62
+ ```ruby
63
+ # Defining decorator wheras innermost is first
64
+ Blacksheep::Action.add_decorator(Blacksheep::Decorators::Localizer)
65
+ Blacksheep::Action.add_decorator(Blacksheep::Decorators::DefaultErrorHandler)
66
+ Blacksheep::Action.add_decorator(Blacksheep::Decorators::JsonTransformer)
67
+ Blacksheep::Action.add_decorator(Blacksheep::Decorators::ResultMatcher)
68
+ ```
69
+
70
+ #### Blacksheep::Decorators::Localizer
71
+
72
+ A localizer sets the I18n locale when passed in a request parameter named `_locale`.
73
+
74
+
75
+ #### Blacksheep::Decorators::DefaultErrorHandler
76
+
77
+ A default error handler can be used in API opertions. The handler catches an error and returns a JsonResultObject such as
78
+
79
+ ```ruby
80
+ def handle_exception(exception)
81
+ json = {
82
+ errors: [
83
+ pointer: {
84
+ source: 'Internal'
85
+ },
86
+ title: "#{exception.class}",
87
+ detail: "#{exception.message}",
88
+ ]
89
+ }
90
+ status = :internal_server_error # 500
91
+
92
+ ActionResult.new(json, status)
93
+ end
94
+ ```
95
+
96
+ You can write your own Errorhandler by including the module `Blacksheep::Decorators::ErrorHandler` and implementing the method `#handle(exception)`.
97
+
98
+
99
+ #### Blacksheep::Decorators::JsonTransformer
100
+
101
+ Assuming the params is a json payload with a specific caseing (e.g. camelCase when used in a JS application such as vue) the JsonTransfomer takes the params and tranforms it's keys into snake_case as used in ruby often.
102
+ The request has to define the case passed (and hence desired response casing) in the parameter `_case`. If the case is requests as `camel` then paramter keys are tranformed to `snake_case` before going into the action and are transformed back into CamelCase when leaving the operation.
103
+
104
+ If JsonTransfomer is used the action should return a simple JSON structure which is transfformed and stored in an ActionResult.
105
+
106
+
107
+ #### Blacksheep::Decorators::ResultMatcher
108
+
109
+ This decorator can be used when implementing your own actions by subclassing `Blacksheep::Action` and using the `#call` style for processing. Adding the matcher decorator enables to write a matchers such as e.g.
110
+
111
+ ```ruby
112
+ MyAction.new.call(params) do |m|
113
+ m.success do |action_result|
114
+ # do something in success case
115
+ end
116
+ m.failure :unauthorized do |action_result|
117
+ # special handling for unauthorized access
118
+ end
119
+ m.failure do |v|
120
+ # any other failure
121
+ end
122
+ end
123
+ ```
124
+
125
+ The action has to return a Blacksheep::ActionResult which is check for status :ok in sucess case and any other status in failure case.
126
+
26
127
 
27
128
  ## Development
28
129
 
@@ -30,6 +131,11 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
30
131
 
31
132
  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).
32
133
 
134
+ ```
135
+ gem build blacksheep
136
+ gem push blacksheep-0.x.y.gem
137
+ ```
138
+
33
139
  ## Contributing
34
140
 
35
141
  Bug reports and pull requests are welcome on GitHub at https://github.com/verticonaut/blacksheep.
data/lib/blacksheep.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "blacksheep/version"
2
- require "blacksheep/json_meta"
3
- require "blacksheep/json_result"
2
+ require "blacksheep/action_result"
4
3
  require "blacksheep/action_decorator"
5
4
  require "blacksheep/decorators/default_error_handler"
6
5
  require "blacksheep/decorators/json_transformer"
@@ -57,8 +57,8 @@ module Blacksheep
57
57
  block.call(params)
58
58
  end
59
59
 
60
- def json_result(json, status: :ok)
61
- JsonResult.new(json, status)
60
+ def action_result(data, status: :ok)
61
+ ActionResult.new(data, status)
62
62
  end
63
63
 
64
64
  end
@@ -1,15 +1,15 @@
1
1
  module Blacksheep
2
- class JsonResult
2
+ class ActionResult
3
3
 
4
- attr_reader :json, :status
4
+ attr_reader :data, :status
5
5
 
6
- def initialize(json, status)
7
- @json = json
6
+ def initialize(data, status)
7
+ @data = data
8
8
  @status = status
9
9
  end
10
10
 
11
- def set_json(value)
12
- @json = value
11
+ def set_data(value)
12
+ @data = value
13
13
 
14
14
  self
15
15
  end
@@ -24,9 +24,9 @@ module Blacksheep
24
24
  @status == :ok
25
25
  end
26
26
 
27
- def render(json_wrap: 'data')
27
+ def render_json(json_wrap: 'data')
28
28
  {
29
- json: wrap(json, json_wrap: json_wrap),
29
+ json: wrap(@data, json_wrap: json_wrap),
30
30
  status: status
31
31
  }
32
32
  end
@@ -2,19 +2,7 @@ module Blacksheep
2
2
  module Decorators
3
3
  # @class Blacksheep::Decorators::DefaultErrorHandler
4
4
  class DefaultErrorHandler < ActionDecorator
5
-
6
- def call(*)
7
- puts error_handler: "*" * 50
8
- super
9
- rescue => exception
10
- handle(exception)
11
- end
12
-
13
- def perform(*)
14
- super
15
- rescue => exception
16
- handle(exception)
17
- end
5
+ include ErrorHandler
18
6
 
19
7
  def handle(exception)
20
8
  json = status = nil
@@ -78,7 +66,7 @@ module Blacksheep
78
66
  }
79
67
  status = :internal_server_error # 500
80
68
 
81
- JsonResult.new(json, status)
69
+ ActionResult.new(json, status)
82
70
  end
83
71
 
84
72
  # def not_authorized_pointer(exception)
@@ -0,0 +1,24 @@
1
+ module Blacksheep
2
+ module Decorators
3
+ # @class Blacksheep::Decorators::ErrorHandler
4
+ class ErrorHandler
5
+
6
+ def call(*)
7
+ super
8
+ rescue => exception
9
+ handle(exception)
10
+ end
11
+
12
+ def perform(*)
13
+ super
14
+ rescue => exception
15
+ handle(exception)
16
+ end
17
+
18
+ def handle(exception)
19
+ raise Blacksheep::Error, 'Subclass responsibility'
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -6,7 +6,6 @@ module Blacksheep
6
6
  attr_reader :case, :params
7
7
 
8
8
  def call(params, **options)
9
- puts transformer: "*" * 50
10
9
  detect_case(params)
11
10
 
12
11
  transformed_params = self.transformed_params(params)
@@ -15,7 +14,7 @@ module Blacksheep
15
14
 
16
15
  transformed_json = transform_result(json)
17
16
 
18
- JsonResult.new(transformed_json, :ok)
17
+ ActionResult.new(transformed_json, :ok)
19
18
  end
20
19
 
21
20
  def perform(params, current_user: nil, **options, &block)
@@ -26,7 +25,7 @@ module Blacksheep
26
25
  json = block.call(transformed_params)
27
26
  transformed_json = transform_result(json)
28
27
 
29
- JsonResult.new(transformed_json, :ok)
28
+ ActionResult.new(transformed_json, :ok)
30
29
  end
31
30
 
32
31
 
@@ -42,7 +41,7 @@ module Blacksheep
42
41
  when 'camel'
43
42
  snakecase_keys(params)
44
43
  else
45
- raise Blackseep::Error, "unknown_case #{@case}"
44
+ raise Blacksheep::Error, "unknown_case #{@case}"
46
45
  end
47
46
  end
48
47
 
@@ -54,14 +53,22 @@ module Blacksheep
54
53
  # @return [Array, Hash] The rsult structure with keys converted to source caseing
55
54
  # @see #camelize_keys
56
55
  def transform_result(obj)
57
- case @case
56
+ is_action_result, data = if obj.kind_of?(Blacksheep::ActionResult)
57
+ [ true, obj.data ]
58
+ else
59
+ [ false, obj ]
60
+ end
61
+
62
+ converted_data = case @case
58
63
  when 'snake', 'as_is'
59
- obj
64
+ data
60
65
  when 'camel'
61
- camelize_keys(obj)
66
+ camelize_keys(data)
62
67
  else
63
- raise Blackseep::Error, "unknown_case #{@case}"
68
+ raise Blacksheep::Error, "unknown_case #{@case}"
64
69
  end
70
+
71
+ is_action_result ? obj.set_data(converted_data) : converted_data
65
72
  end
66
73
 
67
74
  #
@@ -5,19 +5,19 @@ module Blacksheep
5
5
  # @class Blacksheep::Decorators::ResultMatcher
6
6
  class ResultMatcher < ActionDecorator
7
7
  Matcher = -> {
8
- # Match `json_result` with status :ok for success
9
- success_case = Dry::Matcher::Case.new do |json_result, _|
10
- if json_result.success?
11
- json_result
8
+ # Match `action_result` with status :ok for success
9
+ success_case = Dry::Matcher::Case.new do |action_result, _|
10
+ if action_result.success?
11
+ action_result
12
12
  else
13
13
  # this is a constant from dry/core/constants
14
14
  Dry::Matcher::Undefined
15
15
  end
16
16
  end
17
17
 
18
- # Match `json_result` with status not :ok` for failure - other status' can be distinguished
19
- failure_case = Dry::Matcher::Case.new do |json_result, patterns|
20
- if !json_result.success! && (patterns.empty? || patterns.include?(json_result.status))
18
+ # Match `action_result` with status not :ok` for failure - other status' can be distinguished
19
+ failure_case = Dry::Matcher::Case.new do |action_result, patterns|
20
+ if !action_result.success! && (patterns.empty? || patterns.include?(action_result.status))
21
21
  value
22
22
  else
23
23
  Dry::Matcher::Undefined
@@ -31,12 +31,11 @@ module Blacksheep
31
31
  include Dry::Matcher.for(:call, with: Matcher)
32
32
 
33
33
  def call(*)
34
- puts matcher: "*" * 50
35
34
  super
36
35
  end
37
36
 
38
37
  def perform(*)
39
- raise Blackseep::Error, 'JsonResultMatcher does not support #perform'
38
+ raise Blacksheep::Error, 'ResultMatcher does not support #perform'
40
39
  end
41
40
 
42
41
  end
@@ -1,3 +1,3 @@
1
1
  module Blacksheep
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blacksheep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Schweizer
@@ -87,12 +87,12 @@ files:
87
87
  - lib/blacksheep.rb
88
88
  - lib/blacksheep/action.rb
89
89
  - lib/blacksheep/action_decorator.rb
90
+ - lib/blacksheep/action_result.rb
90
91
  - lib/blacksheep/decorators/default_error_handler.rb
92
+ - lib/blacksheep/decorators/error_handler.rb
91
93
  - lib/blacksheep/decorators/json_transformer.rb
92
94
  - lib/blacksheep/decorators/localizer.rb
93
95
  - lib/blacksheep/decorators/result_matcher.rb
94
- - lib/blacksheep/json_meta.rb
95
- - lib/blacksheep/json_result.rb
96
96
  - lib/blacksheep/version.rb
97
97
  homepage: http://verticonaut.me
98
98
  licenses:
@@ -1,41 +0,0 @@
1
- module Blacksheep
2
- class JsonMeta
3
-
4
- attr_reader :json
5
-
6
- def initialize(json = {})
7
- @json = json
8
- end
9
-
10
- class << self
11
- def success(title: nil, detail: nil)
12
- new.success(title: title, detail: detail)
13
- end
14
- end
15
-
16
- def success(title: nil, detail: nil)
17
- result = {
18
- success: true,
19
- }
20
-
21
- if title.present?
22
- result[:title] = title
23
- elsif detail.present?
24
- result[:title] = 'Success'
25
- end
26
-
27
- result[:detail] = detail if detail.present?
28
-
29
- json[:result] = result
30
-
31
- self
32
- end
33
-
34
- def as_json
35
- {
36
- jsonMeta: json
37
- }
38
- end
39
-
40
- end
41
- end