salestation 0.2.1 → 0.3.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/README.md +44 -0
- data/lib/salestation/web.rb +1 -0
- data/lib/salestation/web/extractors.rb +103 -0
- data/salestation.gemspec +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1b525e1ec3e904fe1121233b9c9334348df43d0
|
4
|
+
data.tar.gz: 8b74d25e23e0c52c214591b55ad8a347765e2b32
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4c90e2e8ca7df677c87888b70788c0ac1337e78beb4f777a4825d2a57d6cd5167a19e9e80b383732ba8a390400bc2127050c67a8429adf9d1c2d2dd90d5b84f3
|
7
|
+
data.tar.gz: 5a50bc06f24eda87d84955e84eeffc253c87b33729b5c3cdb797f0ac521037278ccb949e976f06bd2e5134adae4b9e99af52fee26e5afc9a10614d2f5adf0e70
|
data/README.md
CHANGED
@@ -75,6 +75,50 @@ Salestation allows and recommends you to define your own custom errors. This is
|
|
75
75
|
})
|
76
76
|
```
|
77
77
|
|
78
|
+
### Using Extractors
|
79
|
+
|
80
|
+
Salestation provides extractors to fetch parameters from the request and pass them to the chain.
|
81
|
+
Available extractors are `BodyParamExtractor`, `QueryParamExtractor`, `ConstantInput`, `HeadersExtractor`.
|
82
|
+
Multiple extractors can be merged together. If two or more extractors use the same key, the value will be from the last extractor in the merge chain.
|
83
|
+
|
84
|
+
`coercions` can optionally be provided to `BodyParamExtractor` and `QueryParamExtractor`. These can be used to transform the values of the extracted parameters.
|
85
|
+
|
86
|
+
Define a route
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
include Salestation::Web::Extractors
|
90
|
+
|
91
|
+
post '/hello/:name' do |name|
|
92
|
+
coercions = {age: ->(age) { age.to_s }}
|
93
|
+
|
94
|
+
extractor = BodyParamExtractor[:age, coercions: coercions]
|
95
|
+
.merge(ConstantInput[name: name])
|
96
|
+
.merge(HeadersExtractor[{'authorization' => :auth}])
|
97
|
+
|
98
|
+
process extractor do |request|
|
99
|
+
HelloUser.call(request)
|
100
|
+
.map(Responses.to_ok)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
ERROR_MAPPER = Salestation::Web::ErrorMapper.new
|
105
|
+
|
106
|
+
def process(extract_input, &process_request)
|
107
|
+
response = extract_input.call(request).match do
|
108
|
+
Success() do |value|
|
109
|
+
create_request(value)
|
110
|
+
.map(process_request)
|
111
|
+
.map_err(&ERROR_MAPPER.map)
|
112
|
+
end
|
113
|
+
Failure() do |value|
|
114
|
+
Result::Success(value)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
rescue Salestation::Web::ErrorMapper::UndefinedErrorClass => exception
|
118
|
+
raise exception
|
119
|
+
end
|
120
|
+
```
|
121
|
+
|
78
122
|
### Using a logger
|
79
123
|
|
80
124
|
Salestation provides a rack logging middleware which can be used to log structured objects.
|
data/lib/salestation/web.rb
CHANGED
@@ -0,0 +1,103 @@
|
|
1
|
+
module Salestation
|
2
|
+
class Web < Module
|
3
|
+
module Extractors
|
4
|
+
class InputExtractor
|
5
|
+
include Deterministic
|
6
|
+
|
7
|
+
def initialize(&block)
|
8
|
+
@block = block
|
9
|
+
end
|
10
|
+
|
11
|
+
def call(rack_request)
|
12
|
+
@block.call(rack_request)
|
13
|
+
end
|
14
|
+
|
15
|
+
def merge(other)
|
16
|
+
CombinedInputExtractor.new([self, other])
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
class CombinedInputExtractor
|
21
|
+
def initialize(extractors)
|
22
|
+
@extractors = extractors
|
23
|
+
end
|
24
|
+
|
25
|
+
def compose_seq(fns, input)
|
26
|
+
fns.reduce(Deterministic::Result::Success({})) do |result, fn|
|
27
|
+
result.map do |previous_value|
|
28
|
+
fn.call(input).map do |new_value|
|
29
|
+
Deterministic::Result::Success(yield(previous_value, new_value))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def call(rack_request)
|
36
|
+
compose_seq(@extractors, rack_request) do |previous_input, new_input|
|
37
|
+
previous_input.merge(new_input)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def merge(other_extractor)
|
42
|
+
CombinedInputExtractor.new(@extractors + [other_extractor])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class HeadersExtractor
|
47
|
+
include Deterministic
|
48
|
+
|
49
|
+
def self.[](headers)
|
50
|
+
InputExtractor.new do |rack_request|
|
51
|
+
input = headers.map do |header, key|
|
52
|
+
value = rack_request.env["HTTP_#{header.upcase.tr('-', '_')}"]
|
53
|
+
next if value.nil?
|
54
|
+
[key, value]
|
55
|
+
end.compact.to_h
|
56
|
+
|
57
|
+
Result::Success(input)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
class ParamExtractor
|
63
|
+
include Deterministic
|
64
|
+
|
65
|
+
def self.[](*keys, coercions: {}, rack_key:)
|
66
|
+
InputExtractor.new do |rack_request|
|
67
|
+
request_hash = rack_request.env[rack_key] || {}
|
68
|
+
|
69
|
+
input = keys
|
70
|
+
.select { |key| request_hash.key?(key.to_s) }
|
71
|
+
.map { |key| [key, request_hash[key.to_s]] }
|
72
|
+
.map { |key, value| coercions.key?(key) ? [key, coercions[key].call(value)] : [key, value] }
|
73
|
+
.to_h
|
74
|
+
|
75
|
+
Result::Success(input)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
class QueryParamExtractor
|
81
|
+
def self.[](*keys, coercions: {})
|
82
|
+
ParamExtractor[*keys, coercions: coercions, rack_key: 'rack.request.query_hash']
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class BodyParamExtractor
|
87
|
+
def self.[](*keys, coercions: {})
|
88
|
+
ParamExtractor[*keys, coercions: coercions, rack_key: 'rack.request.form_hash']
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
class ConstantInput
|
93
|
+
include Deterministic
|
94
|
+
|
95
|
+
def self.[](input)
|
96
|
+
InputExtractor.new do |**|
|
97
|
+
Result::Success(input)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/salestation.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: salestation
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SaleMove TechMovers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -131,6 +131,7 @@ files:
|
|
131
131
|
- lib/salestation/web.rb
|
132
132
|
- lib/salestation/web/active_record_connection_management.rb
|
133
133
|
- lib/salestation/web/error_mapper.rb
|
134
|
+
- lib/salestation/web/extractors.rb
|
134
135
|
- lib/salestation/web/request_logger.rb
|
135
136
|
- lib/salestation/web/responses.rb
|
136
137
|
- lib/salestation/web/statsd_middleware.rb
|
@@ -155,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
155
156
|
version: '0'
|
156
157
|
requirements: []
|
157
158
|
rubyforge_project:
|
158
|
-
rubygems_version: 2.6.
|
159
|
+
rubygems_version: 2.6.11
|
159
160
|
signing_key:
|
160
161
|
specification_version: 4
|
161
162
|
summary: ''
|