rest-api-generator 0.1.1 → 0.1.3
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 +3 -1
- data/Gemfile.lock +191 -43
- data/README.md +173 -7
- data/Rakefile +1 -1
- data/lib/generators/rest_api_generator/helpers.rb +72 -0
- data/lib/generators/rest_api_generator/resource_generator.rb +33 -16
- data/lib/generators/rest_api_generator/spec/rspec_generator.rb +36 -0
- data/lib/generators/rest_api_generator/spec/rswag_generator.rb +54 -0
- data/lib/generators/rest_api_generator/spec/templates/rspec/nested_resource_controller_spec.rb.tt +62 -0
- data/lib/generators/rest_api_generator/{templates/rest_api_spec.rb.tt → spec/templates/rspec/resource_controller_spec.rb.tt} +5 -5
- data/lib/generators/rest_api_generator/spec/templates/rswag/nested_resource_controller_spec.rb.tt +116 -0
- data/lib/generators/rest_api_generator/spec/templates/rswag/resource_controller_spec.rb.tt +111 -0
- data/lib/generators/rest_api_generator/templates/child_api_controller.rb.tt +10 -9
- data/lib/generators/rest_api_generator/templates/implicit_child_resource_controller.rb.tt +4 -0
- data/lib/generators/rest_api_generator/templates/implicit_resource_controller.rb.tt +4 -0
- data/lib/generators/rest_api_generator/templates/rest_api_controller.rb.tt +2 -0
- data/lib/rest-api-generator.rb +3 -0
- data/lib/rest_api_generator/application_controller.rb +8 -0
- data/lib/rest_api_generator/child_resource_controller.rb +97 -0
- data/lib/rest_api_generator/filterable.rb +30 -0
- data/lib/rest_api_generator/helpers/render.rb +1 -1
- data/lib/rest_api_generator/orderable.rb +30 -0
- data/lib/rest_api_generator/resource_controller.rb +73 -0
- data/lib/rest_api_generator/version.rb +1 -1
- data/lib/rest_api_generator.rb +11 -1
- data/rest-api-generator.gemspec +11 -4
- metadata +90 -8
- data/lib/generators/rest_api_generator/templates/child_api_spec.rb.tt +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a3c84db27490fa76b76096f10ba351092bfb42479890a2a279d725f579c4edb7
|
4
|
+
data.tar.gz: 25e537cd496a09eb3b5755fadf4d04bbcaad38c941bf54af60e230ed7a1ccd13
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0f07b832a6373ed5197f114a0bdc54c6a6c2088d712e3641b8d55d717a5d5b019bba3427907b73495ac6a97de2bfbdd68ee48de267651808cf3d6adbe9f2547
|
7
|
+
data.tar.gz: 565c3cc7797794a6c59008990e58727173c5fa472ef8a8a188cb2a2ba60789cf03994ba8feaff7d8d5dfcf3443333412ece5dbb926f5a44156fa71ad240531b0
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,107 +1,255 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
rest-api-generator (0.1.
|
5
|
-
|
4
|
+
rest-api-generator (0.1.3)
|
5
|
+
rails (>= 5.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
11
|
-
|
12
|
-
activesupport (=
|
13
|
-
|
10
|
+
actioncable (7.0.4)
|
11
|
+
actionpack (= 7.0.4)
|
12
|
+
activesupport (= 7.0.4)
|
13
|
+
nio4r (~> 2.0)
|
14
|
+
websocket-driver (>= 0.6.1)
|
15
|
+
actionmailbox (7.0.4)
|
16
|
+
actionpack (= 7.0.4)
|
17
|
+
activejob (= 7.0.4)
|
18
|
+
activerecord (= 7.0.4)
|
19
|
+
activestorage (= 7.0.4)
|
20
|
+
activesupport (= 7.0.4)
|
21
|
+
mail (>= 2.7.1)
|
22
|
+
net-imap
|
23
|
+
net-pop
|
24
|
+
net-smtp
|
25
|
+
actionmailer (7.0.4)
|
26
|
+
actionpack (= 7.0.4)
|
27
|
+
actionview (= 7.0.4)
|
28
|
+
activejob (= 7.0.4)
|
29
|
+
activesupport (= 7.0.4)
|
30
|
+
mail (~> 2.5, >= 2.5.4)
|
31
|
+
net-imap
|
32
|
+
net-pop
|
33
|
+
net-smtp
|
34
|
+
rails-dom-testing (~> 2.0)
|
35
|
+
actionpack (7.0.4)
|
36
|
+
actionview (= 7.0.4)
|
37
|
+
activesupport (= 7.0.4)
|
38
|
+
rack (~> 2.0, >= 2.2.0)
|
14
39
|
rack-test (>= 0.6.3)
|
15
40
|
rails-dom-testing (~> 2.0)
|
16
41
|
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
17
|
-
|
18
|
-
|
42
|
+
actiontext (7.0.4)
|
43
|
+
actionpack (= 7.0.4)
|
44
|
+
activerecord (= 7.0.4)
|
45
|
+
activestorage (= 7.0.4)
|
46
|
+
activesupport (= 7.0.4)
|
47
|
+
globalid (>= 0.6.0)
|
48
|
+
nokogiri (>= 1.8.5)
|
49
|
+
actionview (7.0.4)
|
50
|
+
activesupport (= 7.0.4)
|
19
51
|
builder (~> 3.1)
|
20
52
|
erubi (~> 1.4)
|
21
53
|
rails-dom-testing (~> 2.0)
|
22
54
|
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
23
|
-
|
55
|
+
activejob (7.0.4)
|
56
|
+
activesupport (= 7.0.4)
|
57
|
+
globalid (>= 0.3.6)
|
58
|
+
activemodel (7.0.4)
|
59
|
+
activesupport (= 7.0.4)
|
60
|
+
activerecord (7.0.4)
|
61
|
+
activemodel (= 7.0.4)
|
62
|
+
activesupport (= 7.0.4)
|
63
|
+
activestorage (7.0.4)
|
64
|
+
actionpack (= 7.0.4)
|
65
|
+
activejob (= 7.0.4)
|
66
|
+
activerecord (= 7.0.4)
|
67
|
+
activesupport (= 7.0.4)
|
68
|
+
marcel (~> 1.0)
|
69
|
+
mini_mime (>= 1.1.0)
|
70
|
+
activesupport (7.0.4)
|
24
71
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
25
72
|
i18n (>= 1.6, < 2)
|
26
73
|
minitest (>= 5.1)
|
27
74
|
tzinfo (~> 2.0)
|
28
|
-
|
75
|
+
addressable (2.8.1)
|
76
|
+
public_suffix (>= 2.0.2, < 6.0)
|
77
|
+
ammeter (1.1.5)
|
78
|
+
activesupport (>= 3.0)
|
79
|
+
railties (>= 3.0)
|
80
|
+
rspec-rails (>= 2.2)
|
29
81
|
ast (2.4.2)
|
30
82
|
builder (3.2.4)
|
31
83
|
concurrent-ruby (1.1.10)
|
32
84
|
crass (1.0.6)
|
85
|
+
database_cleaner (2.0.1)
|
86
|
+
database_cleaner-active_record (~> 2.0.0)
|
87
|
+
database_cleaner-active_record (2.0.1)
|
88
|
+
activerecord (>= 5.a)
|
89
|
+
database_cleaner-core (~> 2.0.0)
|
90
|
+
database_cleaner-core (2.0.1)
|
91
|
+
date (3.3.3)
|
33
92
|
diff-lcs (1.5.0)
|
34
|
-
erubi (1.
|
35
|
-
|
93
|
+
erubi (1.12.0)
|
94
|
+
globalid (1.0.0)
|
95
|
+
activesupport (>= 5.0)
|
96
|
+
i18n (1.12.0)
|
36
97
|
concurrent-ruby (~> 1.0)
|
37
|
-
|
98
|
+
json (2.6.3)
|
99
|
+
json-schema (3.0.0)
|
100
|
+
addressable (>= 2.8)
|
101
|
+
loofah (2.19.1)
|
38
102
|
crass (~> 1.0.2)
|
39
103
|
nokogiri (>= 1.5.9)
|
104
|
+
mail (2.8.0)
|
105
|
+
mini_mime (>= 0.1.1)
|
106
|
+
net-imap
|
107
|
+
net-pop
|
108
|
+
net-smtp
|
109
|
+
marcel (1.0.2)
|
40
110
|
method_source (1.0.0)
|
41
|
-
|
42
|
-
|
111
|
+
mini_mime (1.1.2)
|
112
|
+
minitest (5.16.3)
|
113
|
+
net-imap (0.3.4)
|
114
|
+
date
|
115
|
+
net-protocol
|
116
|
+
net-pop (0.1.2)
|
117
|
+
net-protocol
|
118
|
+
net-protocol (0.2.1)
|
119
|
+
timeout
|
120
|
+
net-smtp (0.3.3)
|
121
|
+
net-protocol
|
122
|
+
nio4r (2.5.8)
|
123
|
+
nokogiri (1.13.10-x86_64-linux)
|
43
124
|
racc (~> 1.4)
|
44
125
|
parallel (1.22.1)
|
45
|
-
parser (3.1.
|
126
|
+
parser (3.1.3.0)
|
46
127
|
ast (~> 2.4.1)
|
47
|
-
|
128
|
+
public_suffix (5.0.1)
|
129
|
+
racc (1.6.2)
|
48
130
|
rack (2.2.4)
|
49
131
|
rack-test (2.0.2)
|
50
132
|
rack (>= 1.3)
|
133
|
+
rails (7.0.4)
|
134
|
+
actioncable (= 7.0.4)
|
135
|
+
actionmailbox (= 7.0.4)
|
136
|
+
actionmailer (= 7.0.4)
|
137
|
+
actionpack (= 7.0.4)
|
138
|
+
actiontext (= 7.0.4)
|
139
|
+
actionview (= 7.0.4)
|
140
|
+
activejob (= 7.0.4)
|
141
|
+
activemodel (= 7.0.4)
|
142
|
+
activerecord (= 7.0.4)
|
143
|
+
activestorage (= 7.0.4)
|
144
|
+
activesupport (= 7.0.4)
|
145
|
+
bundler (>= 1.15.0)
|
146
|
+
railties (= 7.0.4)
|
51
147
|
rails-dom-testing (2.0.3)
|
52
148
|
activesupport (>= 4.2.0)
|
53
149
|
nokogiri (>= 1.6)
|
54
|
-
rails-html-sanitizer (1.4.
|
55
|
-
loofah (~> 2.
|
56
|
-
railties (
|
57
|
-
actionpack (=
|
58
|
-
activesupport (=
|
150
|
+
rails-html-sanitizer (1.4.4)
|
151
|
+
loofah (~> 2.19, >= 2.19.1)
|
152
|
+
railties (7.0.4)
|
153
|
+
actionpack (= 7.0.4)
|
154
|
+
activesupport (= 7.0.4)
|
59
155
|
method_source
|
60
156
|
rake (>= 12.2)
|
61
157
|
thor (~> 1.0)
|
158
|
+
zeitwerk (~> 2.5)
|
62
159
|
rainbow (3.1.1)
|
63
160
|
rake (13.0.6)
|
64
|
-
regexp_parser (2.
|
161
|
+
regexp_parser (2.6.1)
|
65
162
|
rexml (3.2.5)
|
66
|
-
rspec (3.
|
67
|
-
rspec-core (~> 3.
|
68
|
-
rspec-expectations (~> 3.
|
69
|
-
rspec-mocks (~> 3.
|
70
|
-
rspec-core (3.
|
71
|
-
rspec-support (~> 3.
|
72
|
-
rspec-expectations (3.
|
163
|
+
rspec (3.12.0)
|
164
|
+
rspec-core (~> 3.12.0)
|
165
|
+
rspec-expectations (~> 3.12.0)
|
166
|
+
rspec-mocks (~> 3.12.0)
|
167
|
+
rspec-core (3.12.0)
|
168
|
+
rspec-support (~> 3.12.0)
|
169
|
+
rspec-expectations (3.12.1)
|
73
170
|
diff-lcs (>= 1.2.0, < 2.0)
|
74
|
-
rspec-support (~> 3.
|
75
|
-
rspec-mocks (3.
|
171
|
+
rspec-support (~> 3.12.0)
|
172
|
+
rspec-mocks (3.12.1)
|
76
173
|
diff-lcs (>= 1.2.0, < 2.0)
|
77
|
-
rspec-support (~> 3.
|
78
|
-
rspec-
|
79
|
-
|
174
|
+
rspec-support (~> 3.12.0)
|
175
|
+
rspec-rails (6.0.1)
|
176
|
+
actionpack (>= 6.1)
|
177
|
+
activesupport (>= 6.1)
|
178
|
+
railties (>= 6.1)
|
179
|
+
rspec-core (~> 3.11)
|
180
|
+
rspec-expectations (~> 3.11)
|
181
|
+
rspec-mocks (~> 3.11)
|
182
|
+
rspec-support (~> 3.11)
|
183
|
+
rspec-support (3.12.0)
|
184
|
+
rswag (2.8.0)
|
185
|
+
rswag-api (= 2.8.0)
|
186
|
+
rswag-specs (= 2.8.0)
|
187
|
+
rswag-ui (= 2.8.0)
|
188
|
+
rswag-api (2.8.0)
|
189
|
+
railties (>= 3.1, < 7.1)
|
190
|
+
rswag-specs (2.8.0)
|
191
|
+
activesupport (>= 3.1, < 7.1)
|
192
|
+
json-schema (>= 2.2, < 4.0)
|
193
|
+
railties (>= 3.1, < 7.1)
|
194
|
+
rspec-core (>= 2.14)
|
195
|
+
rswag-ui (2.8.0)
|
196
|
+
actionpack (>= 3.1, < 7.1)
|
197
|
+
railties (>= 3.1, < 7.1)
|
198
|
+
rubocop (1.40.0)
|
199
|
+
json (~> 2.3)
|
80
200
|
parallel (~> 1.10)
|
81
|
-
parser (>= 3.1.
|
201
|
+
parser (>= 3.1.2.1)
|
82
202
|
rainbow (>= 2.2.2, < 4.0)
|
83
203
|
regexp_parser (>= 1.8, < 3.0)
|
84
|
-
rexml
|
85
|
-
rubocop-ast (>= 1.
|
204
|
+
rexml (>= 3.2.5, < 4.0)
|
205
|
+
rubocop-ast (>= 1.23.0, < 2.0)
|
86
206
|
ruby-progressbar (~> 1.7)
|
87
207
|
unicode-display_width (>= 1.4.0, < 3.0)
|
88
|
-
rubocop-ast (1.
|
208
|
+
rubocop-ast (1.24.0)
|
89
209
|
parser (>= 3.1.1.0)
|
210
|
+
rubocop-performance (1.15.2)
|
211
|
+
rubocop (>= 1.7.0, < 2.0)
|
212
|
+
rubocop-ast (>= 0.4.0)
|
213
|
+
rubocop-rails (2.17.4)
|
214
|
+
activesupport (>= 4.2.0)
|
215
|
+
rack (>= 1.1)
|
216
|
+
rubocop (>= 1.33.0, < 2.0)
|
217
|
+
rubocop-rspec (2.16.0)
|
218
|
+
rubocop (~> 1.33)
|
219
|
+
rubocop-shopify (2.10.1)
|
220
|
+
rubocop (~> 1.35)
|
90
221
|
ruby-progressbar (1.11.0)
|
222
|
+
sqlite3 (1.5.4-x86_64-linux)
|
223
|
+
switchcop (0.1.2)
|
224
|
+
rubocop (~> 1.40.0)
|
225
|
+
rubocop-performance (~> 1.15.1)
|
226
|
+
rubocop-rails (~> 2.17.3)
|
227
|
+
rubocop-rspec (~> 2.16.0)
|
228
|
+
rubocop-shopify (~> 2.10.1)
|
91
229
|
thor (1.2.1)
|
92
|
-
|
230
|
+
timeout (0.3.1)
|
231
|
+
tzinfo (2.0.5)
|
93
232
|
concurrent-ruby (~> 1.0)
|
94
|
-
unicode-display_width (2.
|
95
|
-
|
233
|
+
unicode-display_width (2.3.0)
|
234
|
+
websocket-driver (0.7.5)
|
235
|
+
websocket-extensions (>= 0.1.0)
|
236
|
+
websocket-extensions (0.1.5)
|
237
|
+
zeitwerk (2.6.6)
|
96
238
|
|
97
239
|
PLATFORMS
|
98
240
|
x86_64-linux
|
99
241
|
|
100
242
|
DEPENDENCIES
|
243
|
+
ammeter (~> 1.1.5)
|
244
|
+
database_cleaner
|
101
245
|
rake (~> 13.0)
|
102
246
|
rest-api-generator!
|
103
247
|
rspec (~> 3.0)
|
104
|
-
|
248
|
+
rspec-rails (~> 6.0.0)
|
249
|
+
rswag
|
250
|
+
rswag-specs
|
251
|
+
sqlite3
|
252
|
+
switchcop
|
105
253
|
|
106
254
|
BUNDLED WITH
|
107
255
|
2.3.3
|
data/README.md
CHANGED
@@ -5,7 +5,7 @@ practices.
|
|
5
5
|
|
6
6
|
## How it works?
|
7
7
|
|
8
|
-
The gems use vanilla Rails generators
|
8
|
+
The gems use vanilla Rails generators in combination with our templates to create all the resources needed to build a
|
9
9
|
REST API.
|
10
10
|
|
11
11
|
Following [Switch Dreams's](https://www.switchdreams.com.br/]) coding practices, the controllers are built with:
|
@@ -16,14 +16,31 @@ Following [Switch Dreams's](https://www.switchdreams.com.br/]) coding practices,
|
|
16
16
|
|
17
17
|
- For tests, we use RSpec and FactoryBot.
|
18
18
|
|
19
|
+
## Current Features
|
20
|
+
|
21
|
+
- [Automatic rest api crud generation](#example)
|
22
|
+
- [Nested Resource](#nested-resource)
|
23
|
+
- :goal_net: [Modular error handler](#modular-error-handler)
|
24
|
+
- :memo: [Automated documentation](#specsdocs)
|
25
|
+
- [Resource ordering](#ordering)
|
26
|
+
- [Resource filter](#filtering)
|
27
|
+
|
28
|
+
## Next Features
|
29
|
+
|
30
|
+
- Serialization https://github.com/SwitchDreams/rest-api-generator/issues/14
|
31
|
+
https://github.com/SwitchDreams/rest-api-generator/issues/11
|
32
|
+
- Pagination https://github.com/SwitchDreams/rest-api-generator/issues/15
|
33
|
+
- Integration with AVO
|
34
|
+
- Select fields
|
35
|
+
- User auth module
|
36
|
+
|
19
37
|
## Installation
|
20
38
|
|
21
39
|
Add this line to your application's Gemfile:
|
22
40
|
|
23
41
|
```ruby
|
24
|
-
|
25
|
-
|
26
|
-
end
|
42
|
+
# Build a Ruby on Rails REST API faster
|
43
|
+
gem 'rest-api-generator'
|
27
44
|
```
|
28
45
|
|
29
46
|
And then execute:
|
@@ -61,13 +78,15 @@ This error handler will rescue from: `ActiveRecord::RecordNotFound`
|
|
61
78
|
### Generate Resource
|
62
79
|
|
63
80
|
```bash
|
64
|
-
$ rails g
|
81
|
+
$ rails g rest_api_generator:resource table_name attributes
|
65
82
|
```
|
66
83
|
|
67
84
|
This command will create:
|
68
85
|
|
69
86
|
- **Model and Migration**: Using rails default model generator
|
70
|
-
- **Controller**: A controller
|
87
|
+
- **Controller**: A controller that implementes CRUD by inheritance of `RestApiGenerator::ResourceController`, or you
|
88
|
+
can use eject option for create a controller
|
89
|
+
that implements index, show, create, update and destroy methods.
|
71
90
|
- **Specs for the created controller**
|
72
91
|
- **Factory bot factory for created model**
|
73
92
|
- **Routes**: with rails resources
|
@@ -75,11 +94,97 @@ This command will create:
|
|
75
94
|
### Example
|
76
95
|
|
77
96
|
```bash
|
78
|
-
$ rails g
|
97
|
+
$ rails g rest_api_generator:resource car name:string color:string
|
79
98
|
```
|
80
99
|
|
81
100
|
Will generate following controller and the other files:
|
82
101
|
|
102
|
+
```ruby
|
103
|
+
# app/controllers/cars_controller.rb
|
104
|
+
class CarsController < RestApiGenerator::ResourceController
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
For a better experience you can override some methods from the
|
109
|
+
[default controller](https://github.com/SwitchDreams/rest-api-generator/blob/main/lib/rest_api_generator/resource_controller.rb)
|
110
|
+
|
111
|
+
### Options
|
112
|
+
|
113
|
+
| Option | Goal | Default | Usage Example |
|
114
|
+
|--------|--------------------------------------------------------------|---------|-----------------|
|
115
|
+
| father | Generate nested resource | nil | --father Users |
|
116
|
+
| scope | Scope the resource for other route or namespace organization | nil | --scope Api::V1 |
|
117
|
+
| eject | Eject the controller to high customization | false | true |
|
118
|
+
| spec | Choose the spec format. Current options: "rspec" or "rswag" | rspec | --spec rswag |
|
119
|
+
|
120
|
+
#### Scope
|
121
|
+
|
122
|
+
In REST api one of the best practices is versioning the end-points, and you can achieve this using scope options,
|
123
|
+
example:
|
124
|
+
|
125
|
+
```bash
|
126
|
+
# Command
|
127
|
+
rails g rest_api_generator:resource car name:string color:string --scope Api::V1
|
128
|
+
```
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
# GET api/v1/cars
|
132
|
+
module Api::V1
|
133
|
+
class CarsController < RestApiGenerator::ResourceController
|
134
|
+
end
|
135
|
+
end
|
136
|
+
```
|
137
|
+
|
138
|
+
For this option you need to manually setup routes, for this example:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
# routes.rb
|
142
|
+
namespace :api do
|
143
|
+
namespace :v1 do
|
144
|
+
resources :cars
|
145
|
+
end
|
146
|
+
end
|
147
|
+
```
|
148
|
+
|
149
|
+
#### Nested resource
|
150
|
+
|
151
|
+
In REST api sometimes we need to build a nested resource, for example when we need to get all devices from a user, for
|
152
|
+
this we have nested resource option:
|
153
|
+
|
154
|
+
```bash
|
155
|
+
# Command
|
156
|
+
rails g rest_api_generator:resource Devices name:string color:string users:references --scope Users
|
157
|
+
```
|
158
|
+
|
159
|
+
```ruby
|
160
|
+
# GET users/:user_id/devices
|
161
|
+
module Users
|
162
|
+
class DevicesController < RestApiGenerator::ChildResourceController
|
163
|
+
end
|
164
|
+
end
|
165
|
+
```
|
166
|
+
|
167
|
+
For this option you need to manually setup routes, for this example:
|
168
|
+
|
169
|
+
```ruby
|
170
|
+
# routes.rb
|
171
|
+
resources :users do
|
172
|
+
resources :devices, controller: 'users/devices'
|
173
|
+
end
|
174
|
+
```
|
175
|
+
|
176
|
+
Considerations:
|
177
|
+
|
178
|
+
- The children model needs to belongs_to parent model and parent model needs to have has_many children model
|
179
|
+
|
180
|
+
#### Eject
|
181
|
+
|
182
|
+
Or you can use the `eject` option for create the controller with the implemented methods:
|
183
|
+
|
184
|
+
```bash
|
185
|
+
rails g rest_api_generator:resource car name:string color:string --eject true
|
186
|
+
```
|
187
|
+
|
83
188
|
```ruby
|
84
189
|
|
85
190
|
class CarsController < ApplicationController
|
@@ -118,9 +223,70 @@ class CarsController < ApplicationController
|
|
118
223
|
params.require(:car).permit(:name, :color)
|
119
224
|
end
|
120
225
|
end
|
226
|
+
```
|
227
|
+
|
228
|
+
#### Specs/Docs
|
229
|
+
|
230
|
+
The default generated spec for this gem is using plain rspec, but you can choose rswag, for scaffold you specs and docs
|
231
|
+
at the same time:
|
232
|
+
|
233
|
+
For this you need to setup https://github.com/rswag/rswag and you the following flag when generating resources.
|
234
|
+
|
235
|
+
```shell
|
236
|
+
rails g rest_api_generator:resource Car name:string color:string --spec rswag
|
237
|
+
```
|
238
|
+
|
239
|
+
This spec options work as generators too, so you can call them individually:
|
240
|
+
|
241
|
+
```shell
|
242
|
+
# rest_api_generator:spec:rswag or rest_api_generator:spec:rspec
|
243
|
+
rails g rest_api_generator:spec:rswag Car name:string color:string
|
244
|
+
```
|
245
|
+
|
246
|
+
### Resource Features
|
247
|
+
|
248
|
+
#### Modular Error Handler
|
121
249
|
|
250
|
+
The error module will return a json in this following format when any active record or custom error raises.
|
251
|
+
|
252
|
+
```json
|
253
|
+
{
|
254
|
+
"status": 422,
|
255
|
+
"error": "",
|
256
|
+
"message": ""
|
257
|
+
}
|
122
258
|
```
|
123
259
|
|
260
|
+
This is good to padronize the error handler in front-end too.
|
261
|
+
|
262
|
+
#### Ordering
|
263
|
+
|
264
|
+
For ordering use this format:
|
265
|
+
|
266
|
+
- Ordering asc: `GET /cars?sort=+name or GET /cars?sort=name`
|
267
|
+
- Ordering desc: `GET /card?sort=-name`
|
268
|
+
|
269
|
+
By default, every resource column can be the key for ordering.
|
270
|
+
|
271
|
+
#### Filtering
|
272
|
+
|
273
|
+
For filter is needed to add some scopes in Model file, example:
|
274
|
+
|
275
|
+
```ruby
|
276
|
+
# app/models/car.rb
|
277
|
+
|
278
|
+
class Car < ApplicationRecord
|
279
|
+
include RestApiGenerator::Filterable
|
280
|
+
|
281
|
+
filter_scope :filter_by_color, ->(color) { where(color: color) }
|
282
|
+
filter_scope :filter_by_name, ->(name) { where("name LIKE ?", "%#{name}%") }
|
283
|
+
end
|
284
|
+
```
|
285
|
+
|
286
|
+
And It's done, you can filter your index end-point:
|
287
|
+
|
288
|
+
- `GET /cars?color=blue or GET /cars?color=red&name=Ferrari`
|
289
|
+
|
124
290
|
## Development
|
125
291
|
|
126
292
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
|
data/Rakefile
CHANGED
@@ -4,8 +4,12 @@ module RestApiGenerator
|
|
4
4
|
module Helpers
|
5
5
|
attr_accessor :options, :attributes
|
6
6
|
|
7
|
+
API_CONTROLLER_DIR_PATH = "app/controllers"
|
8
|
+
API_TEST_DIR_PATH = "spec/requests"
|
9
|
+
|
7
10
|
private
|
8
11
|
|
12
|
+
# Columns handlers
|
9
13
|
def model_columns_for_attributes
|
10
14
|
class_name.singularize.constantize.columns.reject do |column|
|
11
15
|
column.name.to_s =~ /^(id|user_id|created_at|updated_at)$/
|
@@ -17,5 +21,73 @@ module RestApiGenerator
|
|
17
21
|
Rails::Generators::GeneratedAttribute.new(column.name.to_s, column.type.to_s)
|
18
22
|
end
|
19
23
|
end
|
24
|
+
|
25
|
+
# Namespace scope
|
26
|
+
|
27
|
+
def scope_namespacing(&block)
|
28
|
+
content = capture(&block)
|
29
|
+
content = wrap_with_scope(content) if options["scope"].present? || options["father"].present?
|
30
|
+
concat(content)
|
31
|
+
end
|
32
|
+
|
33
|
+
def module_namespace
|
34
|
+
if options["scope"].present? && options["father"].present?
|
35
|
+
options["scope"] + "::" + options["father"]
|
36
|
+
else
|
37
|
+
options["scope"] + options["father"]
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def wrap_with_scope(content)
|
42
|
+
content = indent(content).chomp
|
43
|
+
"module #{module_namespace}\n#{content}\nend\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
# Paths handlers
|
47
|
+
def controller_path
|
48
|
+
"#{API_CONTROLLER_DIR_PATH}#{scope_path}/#{file_name.pluralize}_controller.rb"
|
49
|
+
end
|
50
|
+
|
51
|
+
def scope_path
|
52
|
+
return "" if options["scope"].blank? && options["father"].blank?
|
53
|
+
|
54
|
+
if options["scope"].present? && options["father"].present?
|
55
|
+
"/" + option_to_path(options["scope"]) + "/" + option_to_path(options["father"])
|
56
|
+
else
|
57
|
+
"/" + option_to_path(options["scope"]) + option_to_path(options["father"])
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def option_to_path(option)
|
62
|
+
option.downcase.split("::").join("/")
|
63
|
+
end
|
64
|
+
|
65
|
+
def scope_route_path
|
66
|
+
return "" if options["scope"].blank?
|
67
|
+
|
68
|
+
option_to_path(options["scope"])
|
69
|
+
end
|
70
|
+
|
71
|
+
def nested_routes
|
72
|
+
return "" if options["father"].blank?
|
73
|
+
|
74
|
+
"#{options["father"].downcase.pluralize}/\#{#{options["father"].singularize.downcase}.id}/#{plural_name}"
|
75
|
+
end
|
76
|
+
|
77
|
+
def initial_route
|
78
|
+
return "/#{plural_name}" if options["father"].blank? && options["scope"].blank?
|
79
|
+
|
80
|
+
scope_route_path + "/" + nested_routes
|
81
|
+
end
|
82
|
+
|
83
|
+
def spec_routes
|
84
|
+
{
|
85
|
+
index: initial_route,
|
86
|
+
show: initial_route + "\#{#{singular_name}.id}",
|
87
|
+
create: initial_route,
|
88
|
+
update: initial_route + "\#{#{singular_name}.id}",
|
89
|
+
delete: initial_route + "\#{#{singular_name}.id}",
|
90
|
+
}
|
91
|
+
end
|
20
92
|
end
|
21
93
|
end
|