introspective_grape 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +10 -7
- data/Gemfile +1 -0
- data/README.md +59 -23
- data/gemfiles/Gemfile.rails.4.2.8 +12 -0
- data/introspective_grape.gemspec +1 -0
- data/lib/introspective_grape/formatter/camel_json.rb +5 -1
- data/lib/introspective_grape/version.rb +1 -1
- data/spec/requests/location_api_spec.rb +12 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 57d3bb5f544d03ed3ac7db371114203c93d9b2a8
|
4
|
+
data.tar.gz: 919fa9c7f054138822c4344ece5c7e22c332725c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8066cb3b5cb96688504e947c0d3e283a328a319604dc26c8ae437b53e9181ea9e73e24a9226d4a8c0ed7e3acb8234943fd9a3b41c4f9f66d1e7cd02579c7fa00
|
7
|
+
data.tar.gz: 5e00569a882143326e36dc1dd1e2794fa520dc47280a888200476dedf4b4d2428b8b6891cd5381dbc6cdc1e0ac596feb453f4116e37475c780e2a18ac6ada5eb
|
data/.travis.yml
CHANGED
@@ -10,8 +10,8 @@ rvm:
|
|
10
10
|
- 2.0.0
|
11
11
|
- 2.1.0
|
12
12
|
- 2.2.0
|
13
|
-
- 2.3.0
|
14
13
|
- 2.2.6
|
14
|
+
- 2.3.0
|
15
15
|
- ruby-head
|
16
16
|
- jruby-head
|
17
17
|
gemfile:
|
@@ -19,6 +19,7 @@ gemfile:
|
|
19
19
|
#- gemfiles/Gemfile.rails.4.1.13
|
20
20
|
- gemfiles/Gemfile.rails.4.2.7.1
|
21
21
|
- gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
22
|
+
- gemfiles/Gemfile.rails.4.2.8
|
22
23
|
- gemfiles/Gemfile.rails.5.0.1
|
23
24
|
- gemfiles/Gemfile.rails.master
|
24
25
|
|
@@ -27,24 +28,32 @@ matrix:
|
|
27
28
|
# We'll have to back up to grape-swagger 0.11 for earlier rubies.
|
28
29
|
- rvm: 2.0.0
|
29
30
|
gemfile: gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
31
|
+
- rvm: 2.0.0
|
32
|
+
gemfile: gemfiles/Gemfile.rails.4.2.8
|
30
33
|
- rvm: 2.0.0
|
31
34
|
gemfile: gemfiles/Gemfile.rails.5.0.1
|
32
35
|
- rvm: 2.0.0
|
33
36
|
gemfile: gemfiles/Gemfile.rails.master
|
34
37
|
- rvm: 2.1.0
|
35
38
|
gemfile: gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
39
|
+
- rvm: 2.1.0
|
40
|
+
gemfile: gemfiles/Gemfile.rails.4.2.8
|
36
41
|
- rvm: 2.1.0
|
37
42
|
gemfile: gemfiles/Gemfile.rails.5.0.1
|
38
43
|
- rvm: 2.1.0
|
39
44
|
gemfile: gemfiles/Gemfile.rails.master
|
40
45
|
- rvm: 2.2.0
|
41
46
|
gemfile: gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
47
|
+
- rvm: 2.2.0
|
48
|
+
gemfile: gemfiles/Gemfile.rails.4.2.8
|
42
49
|
- rvm: 2.2.0
|
43
50
|
gemfile: gemfiles/Gemfile.rails.5.0.1
|
44
51
|
- rvm: 2.2.0
|
45
52
|
gemfile: gemfiles/Gemfile.rails.master
|
46
53
|
- rvm: jruby-9.0.4.0
|
47
54
|
gemfile: gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
55
|
+
- rvm: jruby-9.0.4.0
|
56
|
+
gemfile: gemfiles/Gemfile.rails.4.2.8
|
48
57
|
- rvm: jruby-9.0.4.0
|
49
58
|
gemfile: gemfiles/Gemfile.rails.5.0.1
|
50
59
|
- rvm: jruby-9.0.4.0
|
@@ -54,12 +63,6 @@ matrix:
|
|
54
63
|
- rvm: jruby-head
|
55
64
|
|
56
65
|
env:
|
57
|
-
#matrix:
|
58
|
-
# - RAILS=3.2.22
|
59
|
-
# - RAILS=4.1.13
|
60
|
-
# - RAILS=4.2.5.1
|
61
|
-
# - RAILS=5.0.1
|
62
|
-
# - RAILS=master
|
63
66
|
global:
|
64
67
|
- JRUBY_OPTS="-J-Xmx1024m --debug"
|
65
68
|
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -85,11 +85,39 @@ The joke goes that you may find you need to allow an unauthenticated user to att
|
|
85
85
|
|
86
86
|
## Generate End Points for Models
|
87
87
|
|
88
|
-
|
88
|
+
The simplest app/api/v1/my_model_api.rb with the broadest functionality would look like:
|
89
|
+
|
90
|
+
```
|
91
|
+
class MyModelAPI < IntrospectiveGrape::API
|
92
|
+
filter_on :all
|
93
|
+
|
94
|
+
restful MyModel, [:strong, :param, :fields, :and, { nested_model_attributes: [:nested,:fields, :_destroy] }]
|
95
|
+
|
96
|
+
class <NestedModel>Entity < Grape::Entity
|
97
|
+
expose :id, :attribute
|
98
|
+
end
|
99
|
+
|
100
|
+
class MyModelEntity < Grape::Entity
|
101
|
+
expose :id, :attribute1, :attribute2
|
102
|
+
expose :nested, using: <NestedModel>Entity>
|
103
|
+
end
|
104
|
+
end
|
105
|
+
```
|
106
|
+
|
107
|
+
This would set up all the basic RESTFUL actions with nested routes for the associated model and its association, providing a good deal of flexibility for API consumers out of the box.
|
108
|
+
|
109
|
+
IntrospectiveGrape looks in the MyModelAPI class for grape-entity definitions. If you prefer to define your entities elsewhere you could inherit them here instead.
|
110
|
+
|
111
|
+
Note that nested entities must be defined before their parents.
|
112
|
+
|
113
|
+
## Customizing End Points
|
114
|
+
|
115
|
+
Many simple customizations are available to carve out from the default behaviors:
|
89
116
|
|
90
117
|
```
|
91
118
|
class MyModelAPI < IntrospectiveGrape::API
|
92
119
|
skip_presence_validations :attribute_with_generated_default_value
|
120
|
+
|
93
121
|
exclude_actions Model, <:index,:show,:create,:update,:destroy>
|
94
122
|
default_includes Model, <associations for eager loading>
|
95
123
|
|
@@ -98,27 +126,49 @@ class MyModelAPI < IntrospectiveGrape::API
|
|
98
126
|
|
99
127
|
paginate per_page 25, offset: 0, max_per_page: false
|
100
128
|
|
129
|
+
filter_on :param
|
130
|
+
|
101
131
|
restful MyModel, [:strong, :param, :fields, :and, { nested_model_attributes: [:nested,:fields, :_destroy] }] do
|
102
132
|
# Add additional end points to the model's namespace
|
103
133
|
end
|
104
134
|
|
105
|
-
class <
|
135
|
+
class <NestedModel>Entity < Grape::Entity
|
106
136
|
expose :id, :attribute
|
107
|
-
expose :nested, using: <NestedModel>Entity>
|
108
137
|
end
|
109
138
|
|
110
|
-
class <
|
139
|
+
class <MyModel>Entity < Grape::Entity
|
111
140
|
expose :id, :attribute
|
141
|
+
expose :nested, using: <NestedModel>Entity>
|
112
142
|
end
|
113
143
|
end
|
114
144
|
```
|
115
145
|
|
146
|
+
|
147
|
+
## Skipping a Presence Validation for a Required Field
|
148
|
+
|
116
149
|
If a model has, say, a procedurally generated default for a not-null field
|
117
150
|
`skip_presence_validations` will make IntrospectiveGrape declare the parameter
|
118
151
|
optional rather than required.
|
119
152
|
|
153
|
+
## Excluding Endpoints
|
154
|
+
|
155
|
+
By default any association included in the strong params argument will have all
|
156
|
+
RESTful (`:index,:show,:create,:update, :destroy`) endpoints defined. These can
|
157
|
+
be excluded (or conversely included) with the `exclude_actions` or `include_actions`
|
158
|
+
declarations in the API class. You can also include or exclude :all or :none as shorthand.
|
159
|
+
|
160
|
+
## Eager Loading
|
161
|
+
|
162
|
+
Declaring `default_includes` on an activerecord class will tell IntrospectiveGrape which associations to eager load when fetching a collection or instance.
|
163
|
+
|
164
|
+
## Pagination
|
165
|
+
|
166
|
+
The index action by default will not be paginated, simply declared `paginate` before the `restful` declaration will enable [Kaminari](https://github.com/amatsuda/kaminari) pagination on the index results using a default 25 results per page with an offset of 0. You can pass Kaminari's options to the paginate declaration, `per_page`, `max_per_page`, etc.
|
167
|
+
|
168
|
+
## Validating Virtual Attributes and Overriding Grape Validations
|
169
|
+
|
120
170
|
To define a Grape param type for a virtual attribute or override the defaut param
|
121
|
-
type from
|
171
|
+
type from database introspection, define a class method in the model with the param
|
122
172
|
types for the attributes specified in a hash, e.g.:
|
123
173
|
|
124
174
|
```
|
@@ -140,7 +190,9 @@ class method ("grape_validations") that will be applied to that field's param de
|
|
140
190
|
end
|
141
191
|
```
|
142
192
|
|
143
|
-
|
193
|
+
## Validating JSON Parameters
|
194
|
+
|
195
|
+
IntrospectiveGrape provides the following custom grape validators for JSON string parameters:
|
144
196
|
|
145
197
|
```
|
146
198
|
json: true # validates that the JSON string parses
|
@@ -148,11 +200,6 @@ json_array: true # validates that the JSON string parses and returns an Array
|
|
148
200
|
json_hash: true # validates that the JSON string parses and returns a Hash
|
149
201
|
```
|
150
202
|
|
151
|
-
For nested models declared in Rails' strong params both the Grape params for the
|
152
|
-
nested params as well as nested routes will be declared, allowing for
|
153
|
-
a good deal of flexibility for API consumers out of the box, such as implicitly
|
154
|
-
creating bulk update endpoints for nested models.
|
155
|
-
|
156
203
|
|
157
204
|
## Filtering and Searching
|
158
205
|
|
@@ -215,18 +262,7 @@ end
|
|
215
262
|
## Documenting Endpoints
|
216
263
|
|
217
264
|
If you wish to provide additional documentation for end points you can define
|
218
|
-
|
219
|
-
|
220
|
-
## Pagination
|
221
|
-
|
222
|
-
The index action by default will not be paginated, simply declared `paginate` before the `restful` declaration will enable [Kaminari](https://github.com/amatsuda/kaminari) pagination on the index results using a default 25 results per page with an offset of 0. You can pass Kaminari's options to the paginate declaration, `per_page`, `max_per_page`, etc.
|
223
|
-
|
224
|
-
## Excluding Endpoints
|
225
|
-
|
226
|
-
By default any association included in the strong params argument will have all
|
227
|
-
RESTful (`:index,:show,:create,:update, :destroy`) endpoints defined. These can
|
228
|
-
be excluded (or conversely included) with the `exclude_actions` or `include_actions`
|
229
|
-
declarations in the API class. You can also include or exclude :all or :none as shorthand.
|
265
|
+
`self.<action>_documentation` class methods in the API class (or extend them from a module).
|
230
266
|
|
231
267
|
## Grape Hooks
|
232
268
|
|
data/introspective_grape.gemspec
CHANGED
@@ -38,6 +38,7 @@ Gem::Specification.new do |s|
|
|
38
38
|
end
|
39
39
|
|
40
40
|
#s.add_development_dependency "byebug"
|
41
|
+
#s.add_development_dependency "rb-readline"
|
41
42
|
s.add_development_dependency "rspec-rails", '>= 3.0'
|
42
43
|
s.add_development_dependency 'devise'
|
43
44
|
#s.add_development_dependency 'devise-async'
|
@@ -8,10 +8,14 @@ module IntrospectiveGrape
|
|
8
8
|
if object.respond_to?(:to_json) && !object.respond_to?(:with_camel_keys) &&
|
9
9
|
(parsed_object = JSON.parse(object.to_json)).respond_to?(:with_camel_keys)
|
10
10
|
object = parsed_object
|
11
|
+
elsif object.kind_of?(Array) && object.first.kind_of?(Grape::Entity)
|
12
|
+
# Force arrays of Grape::Entities into their hash representations before camelizing
|
13
|
+
object = JSON.parse(object.to_json)
|
11
14
|
end
|
12
15
|
object = object.with_camel_keys if object.respond_to?(:with_camel_keys)
|
16
|
+
|
13
17
|
Grape::Formatter::Json.call(object, _env)
|
14
18
|
end
|
15
19
|
end
|
16
20
|
end
|
17
|
-
end
|
21
|
+
end
|
@@ -10,6 +10,17 @@ describe Dummy::LocationAPI, type: :request do
|
|
10
10
|
Location.make!(name: "TEST2", kind: "airport")
|
11
11
|
end
|
12
12
|
|
13
|
+
|
14
|
+
it "should return an array of camelized location entities" do
|
15
|
+
get '/api/v1/locations'
|
16
|
+
response.should be_success
|
17
|
+
j = JSON.parse(response.body)
|
18
|
+
j.each {|l| l.key?('childLocations').should be_truthy }
|
19
|
+
j.each {|l| l.key?('parentLocationId').should be_truthy }
|
20
|
+
j.each {|l| l.key?('updatedAt').should be_truthy }
|
21
|
+
j.each {|l| l.key?('createdAt').should be_truthy }
|
22
|
+
end
|
23
|
+
|
13
24
|
it "should return a list of top level locations and their children" do
|
14
25
|
get '/api/v1/locations'
|
15
26
|
response.should be_success
|
@@ -20,6 +31,7 @@ describe Dummy::LocationAPI, type: :request do
|
|
20
31
|
json.first['child_locations'].map{|l| l['id'].to_i}.sort.should == location.child_locations.map(&:id).sort
|
21
32
|
end
|
22
33
|
|
34
|
+
|
23
35
|
it "should generate basic filters on the whitelisted model attributes" do
|
24
36
|
get '/api/v1/locations', { name: "TEST" }
|
25
37
|
response.should be_success
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: introspective_grape
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Buermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -252,6 +252,7 @@ files:
|
|
252
252
|
- gemfiles/Gemfile.rails.4.1.13
|
253
253
|
- gemfiles/Gemfile.rails.4.2.7.1
|
254
254
|
- gemfiles/Gemfile.rails.4.2.7.1.new.swagger
|
255
|
+
- gemfiles/Gemfile.rails.4.2.8
|
255
256
|
- gemfiles/Gemfile.rails.5.0.1
|
256
257
|
- gemfiles/Gemfile.rails.master
|
257
258
|
- introspective_grape.gemspec
|