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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 169097ef08e0a724df757dd60c0b47341999bd59
4
- data.tar.gz: 6be10a74972810ca030c0a518893656b599369be
3
+ metadata.gz: 57d3bb5f544d03ed3ac7db371114203c93d9b2a8
4
+ data.tar.gz: 919fa9c7f054138822c4344ece5c7e22c332725c
5
5
  SHA512:
6
- metadata.gz: 6cdc1e63fa9169dfbb90eb275f8dbeac342bdecab7bc324733b8194d47d720a4ffbc68693499a94652f865dd267817cdb769c8a663b09534a635c135321bbc10
7
- data.tar.gz: c5be58cfc13ee4be45df0a349d6712b585cb9919f64a925c60b97d3a1a97cbceeaf6690f9faddd6572b82c76bf3f51b728cdb17af8e0ea94f257c335229ca4c2
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
@@ -14,4 +14,5 @@ gem 'coveralls', require: false
14
14
 
15
15
  group :development do
16
16
  gem 'byebug'
17
+ gem 'rb-readline'
17
18
  end
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
- In app/api/v1/my_model_api.rb:
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 <MyModel>Entity < Grape::Entity
135
+ class <NestedModel>Entity < Grape::Entity
106
136
  expose :id, :attribute
107
- expose :nested, using: <NestedModel>Entity>
108
137
  end
109
138
 
110
- class <NestedModel>Entity < Grape::Entity
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 model introspection, define a class method in the model with the param
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
- IntrospectiveGrape provides the following custom grape validators:
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
- `<action>_documentation` methods in the API class.
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
 
@@ -0,0 +1,12 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec :path => '../'
4
+
5
+ gem 'rails', '4.2.8'
6
+ gem 'grape', '> 0.17'
7
+ gem 'grape-swagger', '> 0.12.0'
8
+ gem 'coveralls', require: false
9
+
10
+ group :development,:test do
11
+ gem 'rspec'
12
+ end
@@ -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
@@ -1,3 +1,3 @@
1
1
  module IntrospectiveGrape
2
- VERSION = "0.3.1".freeze
2
+ VERSION = "0.3.2".freeze
3
3
  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.1
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-27 00:00:00.000000000 Z
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