rest-api-generator 0.2.0 → 0.3.0

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 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