json_api_model 0.1.1 → 0.1.2
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/Gemfile.lock +67 -0
- data/README.md +113 -21
- data/json_api_model.gemspec +2 -0
- data/lib/json_api_model/model.rb +6 -5
- data/lib/json_api_model/result_set.rb +6 -3
- data/lib/json_api_model/scope.rb +8 -8
- data/lib/json_api_model/version.rb +1 -1
- metadata +31 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c0c2e854a3a779030b0ab788040d6481ec4f72c8
|
4
|
+
data.tar.gz: 0bac3b49d6310dca35407b67411e615d6d422643
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4733844d6db1d48f8353d0e384bdfaa8e3695e51260668bdf546ca9e7c625ea21d218c295f5f663df34628301392d3d20517c7d8619559a7d5d3e67189e843db
|
7
|
+
data.tar.gz: 92d708f1e39de4cdb028785cc489edc3029b8c99e5d8631129500e225d62dfeca65d60a506fa30bd0f6f9f104d602e658f0055d01ef29cf32b68f5a76b823910
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
json_api_model (0.1.1)
|
5
|
+
json_api_client
|
6
|
+
|
7
|
+
GEM
|
8
|
+
remote: https://rubygems.org/
|
9
|
+
specs:
|
10
|
+
activemodel (5.2.0)
|
11
|
+
activesupport (= 5.2.0)
|
12
|
+
activesupport (5.2.0)
|
13
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
|
+
i18n (>= 0.7, < 2)
|
15
|
+
minitest (~> 5.1)
|
16
|
+
tzinfo (~> 1.1)
|
17
|
+
addressable (2.5.2)
|
18
|
+
public_suffix (>= 2.0.2, < 4.0)
|
19
|
+
concurrent-ruby (1.0.5)
|
20
|
+
crack (0.4.3)
|
21
|
+
safe_yaml (~> 1.0.0)
|
22
|
+
docile (1.3.1)
|
23
|
+
faraday (0.15.2)
|
24
|
+
multipart-post (>= 1.2, < 3)
|
25
|
+
faraday_middleware (0.12.2)
|
26
|
+
faraday (>= 0.7.4, < 1.0)
|
27
|
+
hashdiff (0.3.7)
|
28
|
+
i18n (1.0.1)
|
29
|
+
concurrent-ruby (~> 1.0)
|
30
|
+
json (2.1.0)
|
31
|
+
json_api_client (1.5.3)
|
32
|
+
activemodel (>= 3.2.0)
|
33
|
+
activesupport (>= 3.2.0)
|
34
|
+
addressable (~> 2.2)
|
35
|
+
faraday (~> 0.9)
|
36
|
+
faraday_middleware (~> 0.9)
|
37
|
+
minitest (5.11.3)
|
38
|
+
multipart-post (2.0.0)
|
39
|
+
public_suffix (3.0.2)
|
40
|
+
rake (10.5.0)
|
41
|
+
safe_yaml (1.0.4)
|
42
|
+
simplecov (0.16.1)
|
43
|
+
docile (~> 1.1)
|
44
|
+
json (>= 1.8, < 3)
|
45
|
+
simplecov-html (~> 0.10.0)
|
46
|
+
simplecov-html (0.10.2)
|
47
|
+
thread_safe (0.3.6)
|
48
|
+
tzinfo (1.2.5)
|
49
|
+
thread_safe (~> 0.1)
|
50
|
+
webmock (3.4.2)
|
51
|
+
addressable (>= 2.3.6)
|
52
|
+
crack (>= 0.3.2)
|
53
|
+
hashdiff
|
54
|
+
|
55
|
+
PLATFORMS
|
56
|
+
ruby
|
57
|
+
|
58
|
+
DEPENDENCIES
|
59
|
+
bundler (~> 1.16)
|
60
|
+
json_api_model!
|
61
|
+
minitest (~> 5.0)
|
62
|
+
rake (~> 10.0)
|
63
|
+
simplecov
|
64
|
+
webmock
|
65
|
+
|
66
|
+
BUNDLED WITH
|
67
|
+
1.16.1
|
data/README.md
CHANGED
@@ -20,11 +20,94 @@ Or install it yourself as:
|
|
20
20
|
|
21
21
|
$ gem install json_api_model
|
22
22
|
|
23
|
+
## Disclaimer
|
24
|
+
|
25
|
+
This is a work in progress. Right now only fetching data works. This will soon change.
|
26
|
+
|
23
27
|
## Usage
|
24
28
|
|
25
|
-
|
29
|
+
Using the model wrappers is pretty straighforward. It thinly wraps `JsonApiClient` to separate communication defintions from your in-app business specific logic. To specify what client class your model is wrapping, use the `wraps` method.
|
30
|
+
|
31
|
+
Any instance or class(non-query) level method will fall thorugh to the client.
|
32
|
+
|
33
|
+
### Example
|
34
|
+
|
35
|
+
If you have an app that talks to a `user` service. Here's how your `User` model might look:
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
module UserService
|
39
|
+
class User < JsonApiModel::Model
|
40
|
+
wraps UserService::Client::User
|
41
|
+
|
42
|
+
def lucky_number
|
43
|
+
42
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
```
|
48
|
+
|
49
|
+
And the interaction with it is not that different from how you would work with the client:
|
50
|
+
|
51
|
+
```ruby
|
52
|
+
# fetching looks identical to as json_api_client (because it thinly wraps it)
|
53
|
+
user = UserService::User.where( id: 8 ).first
|
54
|
+
|
55
|
+
# now you can access your app logic
|
56
|
+
user.lucky_number
|
57
|
+
|
58
|
+
# => 42
|
59
|
+
|
60
|
+
# but also transparently access the client properties
|
61
|
+
user.id
|
62
|
+
# => 8
|
63
|
+
```
|
64
|
+
|
65
|
+
### Rendering
|
66
|
+
|
67
|
+
If you need to propagate your response set up, `JsonApiModel` adds `as_json` handling so that:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
class WhateversController < ApplicationController
|
71
|
+
def index
|
72
|
+
render json: MyService::MyModel.where( params ).all
|
73
|
+
end
|
74
|
+
end
|
75
|
+
```
|
76
|
+
|
77
|
+
Would produce the standard JSONAPI response of:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
{
|
81
|
+
data: data,
|
82
|
+
meta: meta
|
83
|
+
}
|
84
|
+
```
|
85
|
+
|
86
|
+
But if that's not the structure you want, you can modify the `to_json` output as:
|
87
|
+
|
88
|
+
```ruby
|
89
|
+
class MyModelInRussianConroller < ApplicationController
|
90
|
+
|
91
|
+
def индекс
|
92
|
+
@response = MyModel.where( params ).all
|
93
|
+
|
94
|
+
@response.as_json do |data, meta|
|
95
|
+
{
|
96
|
+
данные: data,
|
97
|
+
мета: {
|
98
|
+
счёт: meta["record_count"],
|
99
|
+
страницы: meta["page_count"]
|
100
|
+
}
|
101
|
+
}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
|
108
|
+
### Configuration
|
26
109
|
|
27
|
-
|
110
|
+
If you don't want to override the connection configuration of the client gem in an initializer, you can modify the connection options inside an inhrited class.
|
28
111
|
|
29
112
|
```ruby
|
30
113
|
module MyService
|
@@ -45,31 +128,40 @@ module MyService
|
|
45
128
|
end
|
46
129
|
```
|
47
130
|
|
48
|
-
|
131
|
+
### Monitoring
|
49
132
|
|
50
|
-
|
51
|
-
module MySerive
|
52
|
-
class MyModel < Base
|
53
|
-
wraps MyService::Client::MyModel
|
133
|
+
`JsonApiModel` emits several `ActiveSupport::Notifications` events you can subscribe to:
|
54
134
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
135
|
+
* `find.json_api_model`: fires on every `find`/`all`/`to_a` call. Probably most common.
|
136
|
+
|
137
|
+
| key | value |
|
138
|
+
|------|-------|
|
139
|
+
| url | full url hit |
|
140
|
+
| args | args passed into the requestor |
|
61
141
|
|
62
|
-
|
142
|
+
* `first.json_api_model`: fires on `Model.first`
|
143
|
+
|
144
|
+
| key | value |
|
145
|
+
|------|-------|
|
146
|
+
| url | full url hit |
|
147
|
+
|
148
|
+
* `last.json_api_model`: fired on `Model.last`
|
149
|
+
|
150
|
+
| key | value |
|
151
|
+
|------|-------|
|
152
|
+
| url | full url hit |
|
153
|
+
|
154
|
+
**NOTE**: By default the instrumenter is null, so be sure to configure your app to actually have a notifier and subscribe to the events
|
63
155
|
|
64
156
|
```ruby
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
157
|
+
# config/initializers/json_api_model.rb
|
158
|
+
JsonApiModel.instrumenter = ActiveSupport::Notifications.instrumenter
|
159
|
+
|
160
|
+
ActiveSupport::Notifications.subscribe "find.json_api_model" do |name, started, finished, unique_id, payload|
|
161
|
+
Rails.logger.debug ['notification:', name, started, finished, unique_id, payload].join(' ')
|
69
162
|
end
|
70
163
|
```
|
71
164
|
|
72
|
-
|
73
165
|
## Development
|
74
166
|
|
75
167
|
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.
|
@@ -78,7 +170,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
78
170
|
|
79
171
|
## Contributing
|
80
172
|
|
81
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
173
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/gaorlov/json_api_model. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
82
174
|
|
83
175
|
## License
|
84
176
|
|
@@ -86,4 +178,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
86
178
|
|
87
179
|
## Code of Conduct
|
88
180
|
|
89
|
-
Everyone interacting in the JsonApiModel project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
181
|
+
Everyone interacting in the JsonApiModel project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/gaorlov/json_api_model/blob/master/CODE_OF_CONDUCT.md).
|
data/json_api_model.gemspec
CHANGED
@@ -25,4 +25,6 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_development_dependency "bundler", "~> 1.16"
|
26
26
|
spec.add_development_dependency "rake", "~> 10.0"
|
27
27
|
spec.add_development_dependency "minitest", "~> 5.0"
|
28
|
+
spec.add_development_dependency "simplecov"
|
29
|
+
spec.add_development_dependency "webmock"
|
28
30
|
end
|
data/lib/json_api_model/model.rb
CHANGED
@@ -13,6 +13,7 @@ module JsonApiModel
|
|
13
13
|
def new_from_client( client )
|
14
14
|
model = new
|
15
15
|
model.client = client
|
16
|
+
model
|
16
17
|
end
|
17
18
|
|
18
19
|
def connection( &block )
|
@@ -26,7 +27,7 @@ module JsonApiModel
|
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
29
|
-
|
30
|
+
attr_accessor :client
|
30
31
|
|
31
32
|
def initialize( attributes = {} )
|
32
33
|
@client = self.class.client_class.new( attributes )
|
@@ -36,10 +37,10 @@ module JsonApiModel
|
|
36
37
|
client.send m, *args, &block
|
37
38
|
end
|
38
39
|
|
39
|
-
|
40
|
-
|
41
|
-
def client=( client )
|
42
|
-
@client = client
|
40
|
+
def as_json
|
41
|
+
client.as_json
|
43
42
|
end
|
43
|
+
|
44
|
+
RESERVED_FIELDS = [ :type, :id ]
|
44
45
|
end
|
45
46
|
end
|
@@ -1,14 +1,17 @@
|
|
1
1
|
module JsonApiModel
|
2
2
|
class ResultSet
|
3
|
-
def initialize( client_result_set,
|
4
|
-
@set = client_result_set
|
3
|
+
def initialize( client_result_set, model_class )
|
4
|
+
@set = client_result_set.clone
|
5
|
+
@set.map! do | resource |
|
6
|
+
model_class.new_from_client( resource )
|
7
|
+
end
|
5
8
|
end
|
6
9
|
|
7
10
|
def as_json( opts = {} )
|
8
11
|
if block_given?
|
9
12
|
yield @set, meta
|
10
13
|
else
|
11
|
-
{ data: @set,
|
14
|
+
{ data: @set.map(&:as_json),
|
12
15
|
meta: meta
|
13
16
|
}
|
14
17
|
end
|
data/lib/json_api_model/scope.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module JsonApiModel
|
2
2
|
class Scope
|
3
|
-
def initialize(
|
4
|
-
@
|
5
|
-
@client_scope = JsonApiClient::Query::Builder.new(
|
3
|
+
def initialize( model_class )
|
4
|
+
@model_class = model_class
|
5
|
+
@client_scope = JsonApiClient::Query::Builder.new( model_class.client_class )
|
6
6
|
end
|
7
7
|
|
8
8
|
def to_a
|
@@ -17,24 +17,24 @@ module JsonApiModel
|
|
17
17
|
args: args,
|
18
18
|
url: url do
|
19
19
|
results = @client_scope.find args
|
20
|
-
ResultSet.new( results, @
|
20
|
+
ResultSet.new( results, @model_class )
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
24
|
def first
|
25
25
|
JsonApiModel.instrumenter.instrument 'first.json_api_model', url: url do
|
26
|
-
@
|
26
|
+
@model_class.new_from_client @client_scope.first
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
30
|
def last
|
31
31
|
JsonApiModel.instrumenter.instrument 'last.json_api_model', url: url do
|
32
|
-
@
|
32
|
+
@model_class.new_from_client @client_scope.last
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
36
|
def build
|
37
|
-
@
|
37
|
+
@model_class.new_from_client @client_scope.build
|
38
38
|
end
|
39
39
|
|
40
40
|
def params
|
@@ -53,7 +53,7 @@ module JsonApiModel
|
|
53
53
|
private
|
54
54
|
|
55
55
|
def url
|
56
|
-
@
|
56
|
+
@model_class.client_class.requestor.send( :resource_path, params )
|
57
57
|
end
|
58
58
|
end
|
59
59
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: json_api_model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg Orlov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-07-
|
11
|
+
date: 2018-07-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json_api_client
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '5.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: simplecov
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
69
97
|
description:
|
70
98
|
email:
|
71
99
|
- gaorlov@gmail.com
|
@@ -77,6 +105,7 @@ files:
|
|
77
105
|
- ".travis.yml"
|
78
106
|
- CODE_OF_CONDUCT.md
|
79
107
|
- Gemfile
|
108
|
+
- Gemfile.lock
|
80
109
|
- LICENSE.txt
|
81
110
|
- README.md
|
82
111
|
- Rakefile
|