rest-api-generator 0.2.0 → 0.3.0

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
  SHA256:
3
- metadata.gz: b15131fc7fcedabae2098ef8f2e5e255683acda454d022304ea855ac9ce0a98a
4
- data.tar.gz: 413967d92aca8c5c65075a8dfd5d0159be5c00b29a918b5bc3a39275217b3b6b
3
+ metadata.gz: a42f65c1630afe3db2bc1acb7c66272b9703e61ac761d509b0561e6c9369d7df
4
+ data.tar.gz: 898e903b7b81efa687f272a18ec7179f42ac566da404b1f046002b74345c9f77
5
5
  SHA512:
6
- metadata.gz: 439eb464b272818413629d6ca448c1e976603d97543600f521ff9386ba47e514c4a380b367c087a75a96cdeb5a501d707b365ca5d52d35a4cd3adf08fbddf9ec
7
- data.tar.gz: 79ec324210477f42878cadebaf87566083c6db14251de20206a2cb2a98f2fd9bcbaba969170ecc3cfcee5dae89a51a37381aeaddb29fe30c7fd4d817d769f2de
6
+ metadata.gz: 83e49d124a05cee3c742a69d5d2b1f798014e331c2a662a2bd7b0b19cb99ca45d66bdd290fa996e0c7e969d302fc9ecd49e9c69554836fe582d55adbb06f8f66
7
+ data.tar.gz: 14bd2117229d7cc2cb6b17371f7d0767720e3b6051ddcfc5fa6fb95aec438c29db25800ec5d44505284e4c56ba817e36666fa9118262228d5ab6086d740b0016
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rest-api-generator (0.2.0)
4
+ rest-api-generator (0.3.0)
5
5
  anyway_config (>= 2.0.0)
6
6
  pagy
7
7
  rails (>= 5.0)
data/README.md CHANGED
@@ -3,6 +3,11 @@
3
3
  This gem helps you to build a Ruby on Rails REST API faster, using a scaffold-like generator that follows the best
4
4
  practices.
5
5
 
6
+ ## Get started
7
+
8
+ :zap: **Quick Start**: [docs](https://rest-api-generator.switchdreams.com.br/quick-start)\
9
+ :books: **Documentation**: [docs](https://rest-api-generator.switchdreams.com.br/)
10
+
6
11
  ## How it works?
7
12
 
8
13
  The gems use vanilla Rails generators in combination with our templates to create all the resources needed to build a
@@ -27,6 +32,7 @@ Following [Switch Dreams's](https://www.switchdreams.com.br/]) coding practices,
27
32
  - [Resource pagination](#pagination)
28
33
  - [Resource serialization](#serialization)
29
34
  - [Configurable](#configuration)
35
+ - [Callbacks](#callbacks)
30
36
 
31
37
  ## Next Features
32
38
 
@@ -34,344 +40,6 @@ Following [Switch Dreams's](https://www.switchdreams.com.br/]) coding practices,
34
40
  - Select fields
35
41
  - User auth module
36
42
 
37
- ## Installation
38
-
39
- Add this line to your application's Gemfile:
40
-
41
- ```ruby
42
- # Build a Ruby on Rails REST API faster
43
- gem 'rest-api-generator'
44
- ```
45
-
46
- And then execute:
47
-
48
- $ bundle install
49
-
50
- Or install it yourself as:
51
-
52
- $ gem install rest-api-generator
53
-
54
- ## Requirements
55
-
56
- 1. You need to have installed RSpec and FactoryBot in your application.
57
-
58
- <ul>
59
- <li>RSpec: https://github.com/rspec/rspec-rails</li>
60
- <li>Factory bot: https://github.com/thoughtbot/factory_bot_rails</li>
61
- </ul>
62
-
63
- 2. Include in ApplicationController the error handler module:
64
-
65
- ```ruby
66
-
67
- class ApplicationController < ActionController::API
68
- include RestApiGenerator::ErrorHandler
69
- end
70
- ```
71
-
72
- This error handler will rescue from: `ActiveRecord::RecordNotFound`
73
- , `ActiveRecord::ActiveRecordError`, `ActiveRecord::RecordInvalid`, `ActiveModel::ValidationError`
74
- , `RestApiGenerator::CustomError`.
75
-
76
- ## Usage
77
-
78
- ### Generate Resource
79
-
80
- ```bash
81
- $ rails g rest_api_generator:resource table_name attributes
82
- ```
83
-
84
- This command will create:
85
-
86
- - **Model and Migration**: Using rails default model generator
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.
90
- - **Specs for the created controller**
91
- - **Factory bot factory for created model**
92
- - **Routes**: with rails resources
93
-
94
- ### Example
95
-
96
- ```bash
97
- $ rails g rest_api_generator:resource car name:string color:string
98
- ```
99
-
100
- Will generate following controller and the other files:
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
-
188
- ```ruby
189
-
190
- class CarsController < ApplicationController
191
- before_action :set_car, only: %i[show update destroy]
192
-
193
- def index
194
- @car = Car.all
195
- render json: @car, status: :ok
196
- end
197
-
198
- def show
199
- render json: @car, status: :ok
200
- end
201
-
202
- def create
203
- @car = Car.create!(car_params)
204
- render json: @car, status: :created
205
- end
206
-
207
- def update
208
- @car = Car.update!(car_params)
209
- render json: @car, status: :ok
210
- end
211
-
212
- def destroy
213
- @car.destroy!
214
- end
215
-
216
- private
217
-
218
- def set_car
219
- @car = Car.find(params[:id])
220
- end
221
-
222
- def car_params
223
- params.require(:car).permit(:name, :color)
224
- end
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
- #### Configuration for specs
247
-
248
- By default, the plain rspec and rswag specs are going to be generated in the _spec/requests_ and _spec/docs_
249
- directories, respectively. You can override using the (config options)[#configuration]]. :
250
-
251
- ### Resource Features
252
-
253
- #### Modular Error Handler
254
-
255
- The error module will return a json in this following format when any active record or custom error raises.
256
-
257
- ```json
258
- {
259
- "status": 422,
260
- "error": "",
261
- "message": ""
262
- }
263
- ```
264
-
265
- This is good to padronize the error handler in front-end too.
266
-
267
- #### Ordering
268
-
269
- For ordering use this format:
270
-
271
- - Ordering asc: `GET /cars?sort=+name or GET /cars?sort=name`
272
- - Ordering desc: `GET /card?sort=-name`
273
-
274
- By default, every resource column can be the key for ordering.
275
-
276
- #### Filtering
277
-
278
- For filter is needed to add some scopes in Model file, example:
279
-
280
- ```ruby
281
- # app/models/car.rb
282
-
283
- class Car < ApplicationRecord
284
- include RestApiGenerator::Filterable
285
-
286
- filter_scope :filter_by_color, ->(color) { where(color: color) }
287
- filter_scope :filter_by_name, ->(name) { where("name LIKE ?", "%#{name}%") }
288
- end
289
- ```
290
-
291
- And It's done, you can filter your index end-point:
292
-
293
- - `GET /cars?color=blue or GET /cars?color=red&name=Ferrari`
294
-
295
- ### Pagination
296
-
297
- For pagination, you need to create pagy initialializer file (pagy.rb) in the config directory of your project.
298
- Follow [pagy's example](https://ddnexus.github.io/pagy/quick-start/) for more information.
299
-
300
- Next, you should add some lines on top of the previously created pagy file:
301
-
302
- ```ruby
303
- # config/initializers/pagy.rb
304
- require "pagy"
305
- require "pagy/extras/headers"
306
- ```
307
-
308
- At last, change the pagination variable on RestApiGenerator initializer to true;
309
-
310
- ```rb
311
- # config/initializers/rest_api_generator.rb
312
- config.pagination = true # default: false
313
- ```
314
-
315
- Note, if the parent controller is changed, it is necessary to include Pagy::Backend in the new parent.
316
-
317
- ```rb
318
- # new_parent_controller.rb
319
- class NewParentController < ActionController::Base
320
- include Pagy::Backend
321
- end
322
- ```
323
-
324
- ### Serialization
325
-
326
- If you are working with [ams](https://github.com/rails-api/active_model_serializers), the serializer will work without
327
- any extra configuration.
328
- But if you need to customize you can override the serializer method in the controller:
329
-
330
- ```ruby
331
- # Example with panko serializer: https://github.com/panko-serializer/panko_serializer
332
- class CarsController < RestApiGenerator::ResourceController
333
-
334
- # serializer used in show, create, update.
335
- def serializer(resource)
336
- Panko::CarSerializer.new.serialize_to_json(resource)
337
- end
338
-
339
- # serializer used in index.
340
- def index_serializer(resources)
341
- Panko::ArraySerializer.new(resources, each_serializer: Panko::CarSerializer).to_json
342
- end
343
- end
344
- ```
345
-
346
- ```ruby
347
- # Example with ams
348
- class CarsController < RestApiGenerator::ResourceController
349
- def serializer(resource)
350
- ActiveModelSerializers::SerializableResource.new(resource, each_serializer: Ams::CarSerializer).to_json
351
- end
352
- end
353
- ```
354
-
355
- The gem is tested with [panko serializer](https://github.com/panko-serializer/panko_serializer)
356
- and [ams](https://github.com/rails-api/active_model_serializers). But should works with any serializer, feel free to add
357
- tests for your favorite serializer.
358
-
359
- ## Configuration
360
-
361
- You can override this gem configuration using the initializer or any other method
362
- from [anyway_config](https://github.com/palkan/anyway_config):
363
-
364
- ```rb
365
- # config/initializers/rest_api_generator.rb
366
-
367
- RestApiGenerator.configure do |config|
368
- config.test_path = "custom_test_dir/requests" # default: spec/requests
369
- config.docs_path = "custom_docs_dir/rswag" # default: spec/docs
370
- config.parent_class = "ApplicationController" # default: RestApiGenerator::ResourceController
371
- config.pagination = true # default: false
372
- end
373
- ```
374
-
375
43
  ## Development
376
44
 
377
45
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can
@@ -2,6 +2,7 @@
2
2
 
3
3
  module RestApiGenerator
4
4
  class ChildResourceController < RestApiGenerator.configuration.parent_controller.constantize
5
+ include ControllerCallbacks
5
6
  include Orderable
6
7
  include Serializable
7
8
 
@@ -74,11 +75,15 @@ module RestApiGenerator
74
75
 
75
76
  # Before actions
76
77
  def set_parent_resource
77
- @parent_resource = parent_resource_class.find(parent_record_id)
78
+ run_callbacks :set_parent_resource do
79
+ @parent_resource = parent_resource_class.find(parent_record_id)
80
+ end
78
81
  end
79
82
 
80
83
  def set_resource
81
- @resource = resources.find(record_id)
84
+ run_callbacks :set_resource do
85
+ @resource = resources.find(record_id)
86
+ end
82
87
  end
83
88
 
84
89
  # UsersController => User
@@ -2,11 +2,11 @@
2
2
 
3
3
  module RestApiGenerator
4
4
  class ResourceController < RestApiGenerator.configuration.parent_controller.constantize
5
+ include ControllerCallbacks
5
6
  include Orderable
6
7
  include Serializable
7
8
 
8
9
  before_action :set_resource, only: [:show, :update, :destroy]
9
-
10
10
  def index
11
11
  @resources = resource_class.all
12
12
  @resources = @resources.filter_resource(params_for_filter) if resource_class.include?(Filterable)
@@ -63,7 +63,9 @@ module RestApiGenerator
63
63
  end
64
64
 
65
65
  def set_resource
66
- @resource = resource_class.find(record_id)
66
+ run_callbacks :set_resource do
67
+ @resource = resource_class.find(record_id)
68
+ end
67
69
  end
68
70
 
69
71
  # UsersController => User
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RestApiGenerator
4
+ module ControllerCallbacks
5
+ extend ActiveSupport::Concern
6
+ include ActiveSupport::Callbacks
7
+
8
+ included do
9
+ define_callbacks :set_resource
10
+ define_callbacks :set_parent_resource
11
+ end
12
+
13
+ module ClassMethods
14
+ # Code from rails source code
15
+ [:before, :after, :around].each do |callback|
16
+ define_method "#{callback}_set_resource" do |*names, &blk|
17
+ _insert_callbacks(names, blk) do |name, options|
18
+ set_callback(:set_resource, callback, name, options)
19
+ end
20
+ end
21
+
22
+ define_method "#{callback}_set_parent_resource" do |*names, &blk|
23
+ _insert_callbacks(names, blk) do |name, options|
24
+ set_callback(:set_parent_resource, callback, name, options)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RestApiGenerator
4
- VERSION = "0.2.0"
4
+ VERSION = "0.3.0"
5
5
  end
@@ -9,6 +9,7 @@ require_relative "rest_api_generator/helpers/render"
9
9
  require_relative "rest_api_generator/filterable"
10
10
  require_relative "rest_api_generator/orderable"
11
11
  require_relative "rest_api_generator/serializable"
12
+ require_relative "rest_api_generator/controller_callbacks"
12
13
 
13
14
  module RestApiGenerator
14
15
  class Error < StandardError; end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-api-generator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - PedroAugustoRamalhoDuarte
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2023-05-15 00:00:00.000000000 Z
11
+ date: 2023-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: anyway_config
@@ -155,6 +155,7 @@ files:
155
155
  - lib/rest-api-generator.rb
156
156
  - lib/rest_api_generator.rb
157
157
  - lib/rest_api_generator/config.rb
158
+ - lib/rest_api_generator/controller_callbacks.rb
158
159
  - lib/rest_api_generator/custom_error.rb
159
160
  - lib/rest_api_generator/error_handler.rb
160
161
  - lib/rest_api_generator/filterable.rb