api_struct 0.1.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +25 -0
- data/Gemfile.lock +15 -14
- data/README.md +17 -9
- data/api_struct.gemspec +1 -1
- data/lib/api_struct.rb +1 -1
- data/lib/api_struct/client.rb +4 -4
- data/lib/api_struct/extensions/dry_monads.rb +9 -5
- data/lib/api_struct/version.rb +1 -1
- data/spec/api_struct/client_spec.rb +14 -14
- metadata +5 -5
- data/circle.yml +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e44363911471e7d9ba624a1a2ed6206c11f7b340
|
4
|
+
data.tar.gz: f6ba8b892e2541d50355a0f5f6f9c544f43e29d8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de40c7dbef03649602cdb0e7e7f8cb16c289a6f14275b332cb5e4d820c6fa8f08a11b32f6f44ffabbe47f94a6f7fc72129236fa238cee6007425583d34de00c3
|
7
|
+
data.tar.gz: 34e71ed56918320e1340c97ec7cfa879ba7e0a92dc357867e620a8ad4344dffdf0e2b85bbea4b575acb7484f13bbb0174109c9320deb05486b576c8c3a649c3b
|
@@ -0,0 +1,25 @@
|
|
1
|
+
version: 2
|
2
|
+
jobs:
|
3
|
+
build:
|
4
|
+
docker:
|
5
|
+
- image: circleci/ruby:2.4-node
|
6
|
+
|
7
|
+
steps:
|
8
|
+
- checkout
|
9
|
+
|
10
|
+
- restore_cache:
|
11
|
+
keys:
|
12
|
+
- api-struct-bundle-v2-{{ checksum "api_struct.gemspec" }}
|
13
|
+
|
14
|
+
- run:
|
15
|
+
name: Bundle Install
|
16
|
+
command: bundle check || bundle install
|
17
|
+
|
18
|
+
- save_cache:
|
19
|
+
key: api-struct-bundle-v2-{{ checksum "api_struct.gemspec" }}
|
20
|
+
paths:
|
21
|
+
- vendor/bundle
|
22
|
+
|
23
|
+
- run:
|
24
|
+
name: Run Rspec
|
25
|
+
command: bundle exec rspec
|
data/Gemfile.lock
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
api_struct (
|
4
|
+
api_struct (1.0.0)
|
5
5
|
dry-configurable (~> 0.7.0)
|
6
|
-
dry-monads (~> 0
|
6
|
+
dry-monads (~> 1.0)
|
7
7
|
hashie (~> 3.5, >= 3.5.6)
|
8
8
|
http (>= 2.0.3)
|
9
9
|
|
@@ -15,31 +15,32 @@ GEM
|
|
15
15
|
ast (2.3.0)
|
16
16
|
byebug (9.1.0)
|
17
17
|
coderay (1.1.2)
|
18
|
-
concurrent-ruby (1.
|
18
|
+
concurrent-ruby (1.1.3)
|
19
19
|
crack (0.4.3)
|
20
20
|
safe_yaml (~> 1.0.0)
|
21
21
|
diff-lcs (1.3)
|
22
|
-
domain_name (0.5.
|
22
|
+
domain_name (0.5.20180417)
|
23
23
|
unf (>= 0.0.5, < 1.0.0)
|
24
24
|
dry-configurable (0.7.0)
|
25
25
|
concurrent-ruby (~> 1.0)
|
26
|
-
dry-core (0.4.
|
26
|
+
dry-core (0.4.7)
|
27
27
|
concurrent-ruby (~> 1.0)
|
28
|
-
dry-equalizer (0.2.
|
29
|
-
dry-monads (
|
30
|
-
|
28
|
+
dry-equalizer (0.2.1)
|
29
|
+
dry-monads (1.1.0)
|
30
|
+
concurrent-ruby (~> 1.0)
|
31
|
+
dry-core (~> 0.4, >= 0.4.4)
|
31
32
|
dry-equalizer
|
32
33
|
ffaker (2.8.0)
|
33
34
|
hashdiff (0.3.7)
|
34
|
-
hashie (3.
|
35
|
-
http (
|
35
|
+
hashie (3.6.0)
|
36
|
+
http (4.0.0)
|
36
37
|
addressable (~> 2.3)
|
37
38
|
http-cookie (~> 1.0)
|
38
|
-
http-form_data (
|
39
|
+
http-form_data (~> 2.0)
|
39
40
|
http_parser.rb (~> 0.6.0)
|
40
41
|
http-cookie (1.0.3)
|
41
42
|
domain_name (~> 0.5)
|
42
|
-
http-form_data (2.
|
43
|
+
http-form_data (2.1.1)
|
43
44
|
http_parser.rb (0.6.0)
|
44
45
|
method_source (0.9.0)
|
45
46
|
parallel (1.12.0)
|
@@ -79,7 +80,7 @@ GEM
|
|
79
80
|
safe_yaml (1.0.4)
|
80
81
|
unf (0.1.4)
|
81
82
|
unf_ext
|
82
|
-
unf_ext (0.0.7.
|
83
|
+
unf_ext (0.0.7.5)
|
83
84
|
unicode-display_width (1.3.0)
|
84
85
|
vcr (3.0.3)
|
85
86
|
webmock (3.2.1)
|
@@ -102,4 +103,4 @@ DEPENDENCIES
|
|
102
103
|
webmock (~> 3.2, >= 3.2.1)
|
103
104
|
|
104
105
|
BUNDLED WITH
|
105
|
-
1.
|
106
|
+
1.17.1
|
data/README.md
CHANGED
@@ -2,6 +2,10 @@
|
|
2
2
|
|
3
3
|
**ApiStruct** consists of two main interfaces: `ApiStruct::Client` and `ApiStruct::Entity`. The `ApiStruct::Client` class is aimed at using the same interface for describing requests to different APIs. The `ApiStruct::Entity` enables you to use *ApiStruct* clients in ORM-like style.
|
4
4
|
|
5
|
+
[![Gem Version](https://badge.fury.io/rb/api_struct.svg)](https://badge.fury.io/rb/api_struct)
|
6
|
+
![Maintainability](https://api.codeclimate.com/v1/badges/dc07c83ccbcaaebc6c44/maintainability)
|
7
|
+
[![CircleCI](https://circleci.com/gh/rubygarage/api_struct/tree/master.svg?style=svg)](https://circleci.com/gh/rubygarage/api_struct/tree/master)
|
8
|
+
|
5
9
|
## Installation
|
6
10
|
|
7
11
|
Add this line to your application's Gemfile:
|
@@ -54,13 +58,13 @@ class PostsClient < ApiStruct::Client
|
|
54
58
|
def index
|
55
59
|
get
|
56
60
|
end
|
57
|
-
|
61
|
+
|
58
62
|
def user_posts(user_id, post_id = nil)
|
59
|
-
get(post_id, prefix: [:users, user_id])
|
60
|
-
# alias:
|
63
|
+
get(post_id, prefix: [:users, user_id])
|
64
|
+
# alias:
|
61
65
|
# get(post_id, prefix: '/users/:id', id: user_id)
|
62
66
|
end
|
63
|
-
|
67
|
+
|
64
68
|
def custom_path(user_id)
|
65
69
|
get(path: 'users_posts/:user_id', user_id: user_id)
|
66
70
|
end
|
@@ -71,16 +75,16 @@ Usage:
|
|
71
75
|
```ruby
|
72
76
|
PostsClient.new.get(1) # -> /posts/1
|
73
77
|
```
|
74
|
-
Returns `
|
78
|
+
Returns `Result` [monad](https://dry-rb.org/gems/dry-monads/1.0/result/)
|
75
79
|
```ruby
|
76
|
-
# =>
|
80
|
+
# => Success({:id=>1, :title=>"Post"})
|
77
81
|
```
|
78
82
|
|
79
83
|
Other methods from sample:
|
80
84
|
```ruby
|
81
85
|
post_client = PostsClient.new
|
82
86
|
|
83
|
-
post_client.index # -> /posts
|
87
|
+
post_client.index # -> /posts
|
84
88
|
post_client.user_posts(1) # -> /users/1/posts
|
85
89
|
post_client.user_posts(1, 2) # -> /users/1/posts/2
|
86
90
|
post_client.custom_path(1) # -> /users_posts/1/
|
@@ -95,9 +99,9 @@ class User < ApiStruct::Entity
|
|
95
99
|
client_service UsersClient
|
96
100
|
|
97
101
|
client_service AuthorsClient, prefix: true, only: :index
|
98
|
-
# alias:
|
102
|
+
# alias:
|
99
103
|
# client_service AuthorsClient, prefix: :prefix, except: :index
|
100
|
-
|
104
|
+
|
101
105
|
attr_entity :name, :id
|
102
106
|
end
|
103
107
|
```
|
@@ -201,3 +205,7 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/rubyga
|
|
201
205
|
## License
|
202
206
|
|
203
207
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
208
|
+
***
|
209
|
+
<a href="https://rubygarage.org/"><img src="https://rubygarage.s3.amazonaws.com/assets/assets/rg_color_logo_horizontal-919afc51a81d2e40cb6a0b43ee832e3fcd49669d06785156d2d16fd0d799f89e.png" alt="RubyGarage Logo" width="415" height="128"></a>
|
210
|
+
|
211
|
+
RubyGarage is a leading software development and consulting company in Eastern Europe. Our main expertise includes Ruby and Ruby on Rails, but we successfully employ other technologies to deliver the best results to our clients. [Check out our portfolio](https://rubygarage.org/portfolio) for even more exciting works!
|
data/api_struct.gemspec
CHANGED
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.add_dependency 'dry-monads', '~> 0
|
21
|
+
spec.add_dependency 'dry-monads', '~> 1.0'
|
22
22
|
spec.add_dependency 'dry-configurable', '~> 0.7.0'
|
23
23
|
spec.add_dependency 'http', '>= 2.0.3'
|
24
24
|
spec.add_dependency 'hashie', '~> 3.5', '>= 3.5.6'
|
data/lib/api_struct.rb
CHANGED
data/lib/api_struct/client.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module ApiStruct
|
2
2
|
class Client
|
3
|
-
DEFAULT_HEADERS = {
|
3
|
+
DEFAULT_HEADERS = {
|
4
4
|
'Accept': 'application/json',
|
5
|
-
'Content-Type': 'application/json'
|
5
|
+
'Content-Type': 'application/json'
|
6
6
|
}
|
7
7
|
URL_OPTION_REGEXP = /\/:([a-z_]+)/.freeze
|
8
8
|
|
@@ -47,12 +47,12 @@ module ApiStruct
|
|
47
47
|
def success(response)
|
48
48
|
body = response.body.to_s
|
49
49
|
result = !body.empty? ? JSON.parse(body, symbolize_names: true) : nil
|
50
|
-
Dry::Monads
|
50
|
+
Dry::Monads::Success(result)
|
51
51
|
end
|
52
52
|
|
53
53
|
def failure(response)
|
54
54
|
result = ApiStruct::Errors::Client.new(response)
|
55
|
-
Dry::Monads
|
55
|
+
Dry::Monads::Failure(result)
|
56
56
|
end
|
57
57
|
|
58
58
|
def first_arg(args)
|
@@ -2,16 +2,20 @@ module ApiStruct
|
|
2
2
|
module Extensions
|
3
3
|
module DryMonads
|
4
4
|
def from_monad(monad)
|
5
|
-
monad
|
5
|
+
monad
|
6
|
+
.fmap { |v| from_success(v) }.or_fmap { |e| from_failure(e) }.value!
|
6
7
|
end
|
7
8
|
|
8
|
-
def
|
9
|
-
return Dry::Monads::
|
9
|
+
def from_success(value)
|
10
|
+
return Dry::Monads::Success(nil) if value.nil?
|
11
|
+
|
10
12
|
value.is_a?(Array) ? collection(value) : new(value)
|
11
13
|
end
|
12
14
|
|
13
|
-
def
|
14
|
-
ApiStruct::Errors::Entity.new(
|
15
|
+
def from_failure(error)
|
16
|
+
ApiStruct::Errors::Entity.new(
|
17
|
+
{ status: error.status, body: error.body, error: true }, false
|
18
|
+
)
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
data/lib/api_struct/version.rb
CHANGED
@@ -9,7 +9,7 @@ describe ApiStruct::Client do
|
|
9
9
|
def show(id)
|
10
10
|
get(id)
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def update(id, params)
|
14
14
|
patch(id, json: params)
|
15
15
|
end
|
@@ -61,8 +61,8 @@ describe ApiStruct::Client do
|
|
61
61
|
VCR.use_cassette('users/1/posts') do
|
62
62
|
response = StubClient.new.get(prefix: 'users/:id', id: 1)
|
63
63
|
expect(response).to be_success
|
64
|
-
expect(response.value).to be_kind_of Array
|
65
|
-
expect(response.value).not_to be_empty
|
64
|
+
expect(response.value!).to be_kind_of Array
|
65
|
+
expect(response.value!).not_to be_empty
|
66
66
|
end
|
67
67
|
end
|
68
68
|
|
@@ -70,9 +70,9 @@ describe ApiStruct::Client do
|
|
70
70
|
VCR.use_cassette('todos') do
|
71
71
|
response = StubClient.new.get(path: 'todos/1')
|
72
72
|
expect(response).to be_success
|
73
|
-
expect(response.value[:id]).to eq(1)
|
74
|
-
expect(response.value[:title]).not_to be_empty
|
75
|
-
expect(response.value
|
73
|
+
expect(response.value![:id]).to eq(1)
|
74
|
+
expect(response.value![:title]).not_to be_empty
|
75
|
+
expect(response.value!.keys).to include(:completed)
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
@@ -80,20 +80,20 @@ describe ApiStruct::Client do
|
|
80
80
|
VCR.use_cassette('todos') do
|
81
81
|
response = StubClient.new.get(path: [:todos, 1])
|
82
82
|
expect(response).to be_success
|
83
|
-
expect(response.value[:id]).to eq(1)
|
84
|
-
expect(response.value[:title]).not_to be_empty
|
85
|
-
expect(response.value
|
83
|
+
expect(response.value![:id]).to eq(1)
|
84
|
+
expect(response.value![:title]).not_to be_empty
|
85
|
+
expect(response.value!.keys).to include(:completed)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
context 'GET' do
|
91
91
|
it 'when successful response' do
|
92
92
|
VCR.use_cassette('posts/show_success') do
|
93
93
|
response = StubClient.new.show(1)
|
94
94
|
expect(response).to be_success
|
95
|
-
expect(response.value[:id]).to eq(1)
|
96
|
-
expect(response.value[:title]).not_to be_empty
|
95
|
+
expect(response.value![:id]).to eq(1)
|
96
|
+
expect(response.value![:title]).not_to be_empty
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -101,7 +101,7 @@ describe ApiStruct::Client do
|
|
101
101
|
VCR.use_cassette('posts/show_failure') do
|
102
102
|
response = StubClient.new.show(101)
|
103
103
|
expect(response).to be_failure
|
104
|
-
expect(response.
|
104
|
+
expect(response.failure.status).to eq(404)
|
105
105
|
end
|
106
106
|
end
|
107
107
|
end
|
@@ -111,7 +111,7 @@ describe ApiStruct::Client do
|
|
111
111
|
VCR.use_cassette('posts/update_success') do
|
112
112
|
response = StubClient.new.update(1, title: FFaker::Name.name)
|
113
113
|
expect(response).to be_success
|
114
|
-
expect(response.value[:id]).to eq(1)
|
114
|
+
expect(response.value![:id]).to eq(1)
|
115
115
|
end
|
116
116
|
end
|
117
117
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: api_struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- bezrukavyi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2018-
|
13
|
+
date: 2018-11-24 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: dry-monads
|
@@ -18,14 +18,14 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0
|
21
|
+
version: '1.0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - "~>"
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 0
|
28
|
+
version: '1.0'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: dry-configurable
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
@@ -207,6 +207,7 @@ executables: []
|
|
207
207
|
extensions: []
|
208
208
|
extra_rdoc_files: []
|
209
209
|
files:
|
210
|
+
- ".circleci/config.yml"
|
210
211
|
- ".gitignore"
|
211
212
|
- ".rspec"
|
212
213
|
- ".rubocop.yml"
|
@@ -220,7 +221,6 @@ files:
|
|
220
221
|
- api_struct.svg
|
221
222
|
- bin/console
|
222
223
|
- bin/setup
|
223
|
-
- circle.yml
|
224
224
|
- lib/api_struct.rb
|
225
225
|
- lib/api_struct/client.rb
|
226
226
|
- lib/api_struct/collection.rb
|
data/circle.yml
DELETED