fit_api 1.1.2 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 0d176cc7557464b1cb5b9756b11feb083c8ec735799d2d89e587d3a271794b86
4
- data.tar.gz: 5a0a48d8fbf84fd0abd3e82b004b34f9393a522a2cdec75250d6698840cc8dd7
2
+ SHA1:
3
+ metadata.gz: 5922975501ebc48453cb5a6f7ad438befbe85d0b
4
+ data.tar.gz: 9d93fc4af41f39e28581820d75d699d0638c9ce6
5
5
  SHA512:
6
- metadata.gz: c079a3c4f083fd3543878d9e6d9cf030ee28b9f91ce67a94b4ca31a5d70c6128f3de32c09822b109ce4188ff897b6dc6b7298f8aa73205a7d05f56c67253fc36
7
- data.tar.gz: ca6de1c94256a2840192be7e3fea05d5575a4d57a747be8026540590ca22448a6d40f5fcee52b713a3d7b0f84873b685521a45e7f388be66c00b83d239276fe5
6
+ metadata.gz: 88eb8fa868fd5e0084a81c3bb4ed2e1672b128b27f6be74914cda3f13d527dae03d4dd54e167551473ef8b91317218f6e3ad898fe229e4361a41d9c5b21e4d52
7
+ data.tar.gz: c9e11e13e75c4f5bf4a88ac62b63a73c198be62b77a07810635ee959d434cde146db11218c40b7b9a0df06b4285cf00974723ae7bb2f3e28c466fa4ccd30e981
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source 'https://rubygems.org'
2
2
  ruby '2.5.3'
3
3
 
4
- gem 'rack', git: 'https://github.com/rack/rack.git'
4
+ gem 'rack', '~> 2.2.2'
5
5
  gem 'rack-test', '~> 1.1.0'
6
6
  gem 'dry-inflector', '~> 0.1.2'
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # fit-api
2
2
 
3
- Lightweight framework for building JSON API's
3
+ Lightweight framework for building JSON API"s
4
4
 
5
5
  ## Introduction
6
6
 
@@ -37,63 +37,61 @@ $ gem install fit_api
37
37
  ## Usage
38
38
 
39
39
  This is a basic example showing how it works... you can check the demo app from this repository:
40
- [fit-api-demo](http://github.com/bermanya/fit-api-demo)
40
+ [fit-api-demo](http://github.com/bermanya/minesweeper-api)
41
41
 
42
42
  **api.rb**
43
43
 
44
44
  ```ruby
45
- require 'fit_api'
45
+ # optional:
46
+ FitApi::Router.auto_load_path "controllers"
46
47
 
47
48
  FitApi::Router.define do
48
- get '/:name', to: 'app#show'
49
+ get "/:name", to: "app#show"
49
50
 
50
- root to: 'app#index'
51
+ root to: "app#index"
51
52
  end
53
+ ```
54
+
55
+ **controllers/app_controllers.rb**
52
56
 
57
+ ```
53
58
  class AppController < FitApi::Controller
54
59
  def index
55
- json({ message: 'Hello world' })
60
+ json(message: "Hello world")
56
61
  end
57
62
 
58
63
  def show
59
- json({ message: "Welcome #{params.name}" })
64
+ if found
65
+ json(message: "Welcome #{params.name}")
66
+ else
67
+ json(404, error: "not found")
68
+ end
60
69
  end
61
70
  end
62
-
63
- # You can setup any Rack Middleware
64
-
65
- FitApi.use Rack::CommonLogger, Logger.new('log/app.log')
66
-
67
- Rack::Handler::WEBrick.run FitApi.app
68
71
  ```
69
72
 
70
73
  ```bash
71
- ruby api.rb
74
+ rackup
72
75
  ```
73
76
 
74
77
  ## Router
75
78
 
76
- It recognizes URLs and invoke the controller's action... the DSL is pretty similar to Rails (obviously not so powerful):
79
+ It recognizes URLs and invoke the controller"s action... the DSL is pretty similar to Rails (obviously not so powerful):
77
80
 
78
81
  ### HTTP methods:
79
82
 
80
83
  ```ruby
81
- get '/test/:name', to: 'app#test_show'
82
- post '/test', to: 'app#test_post'
83
- put '/test', to: 'app#test_put'
84
- delete '/test/:id', to: 'app#test_delete'
84
+ get "/test/:name", to: "app#test_show"
85
+ post "/test", to: "app#test_post"
86
+ put "/test", to: "app#test_put"
87
+ delete "/test/:id", to: "app#test_delete"
85
88
  ```
86
89
 
87
90
  ----
88
91
 
89
92
  ### Resources
90
93
 
91
- You can pass the following options:
92
-
93
- ```
94
- only
95
- except
96
- controller
94
+ You can pass the following options: `only, except, controller`
97
95
  ```
98
96
 
99
97
  **Nested:**
@@ -133,7 +131,7 @@ end
133
131
  **Member & Collection:**
134
132
 
135
133
  ```ruby
136
- resources :contacts, only: %i(index) do
134
+ resources :contacts, only: :index do
137
135
  member do
138
136
  post :add_activity
139
137
  end
@@ -171,14 +169,14 @@ end
171
169
  -----
172
170
 
173
171
  ```ruby
174
- namespace '/hello/world', controller: :test do
172
+ namespace "/hello/world", controller: :test do
175
173
  get :test
176
174
  end
177
175
  ```
178
176
 
179
177
  | Method | Path | Controller & action |
180
178
  |----------|-------------------|-----------------------|
181
- | **GET** | /test/world/test | test#test |
179
+ | **GET** | /hello/world/test | test#test |
182
180
 
183
181
  -----
184
182
 
@@ -187,7 +185,7 @@ end
187
185
  ```ruby
188
186
  controller :app do
189
187
  get :another_action
190
- get '/welcome', action: 'hello_world'
188
+ get "/welcome", action: "hello_world"
191
189
  end
192
190
  ```
193
191
 
@@ -201,7 +199,7 @@ end
201
199
  ### Root
202
200
 
203
201
  ```ruby
204
- root to: 'app#index'
202
+ root to: "app#index"
205
203
  ```
206
204
 
207
205
  | Method | Path | Controller & action |
@@ -213,7 +211,7 @@ root to: 'app#index'
213
211
  ### Customize error 404 message
214
212
 
215
213
  ```ruby
216
- not_found to: 'app#error_404'
214
+ not_found to: "app#error_404"
217
215
  ```
218
216
 
219
217
  ## Controllers
@@ -224,17 +222,15 @@ One limitation is the class name of your controller must end with "Controller",
224
222
  ```ruby
225
223
  class AppController < FitApi::Controller
226
224
  def index
227
- json 'hello world'
225
+ json "hello world"
228
226
  end
229
227
 
230
- def process_post
231
- json resource, 201
228
+ def create
229
+ json 201, resource
232
230
  end
233
231
  end
234
232
  ```
235
233
 
236
- You have the method `#json` available, which basically sets the response body.
237
-
238
234
  Default status code: ```200```
239
235
 
240
236
  ----
@@ -254,8 +250,8 @@ You can exit the current action throwing an exception... the default status code
254
250
  ```ruby
255
251
  halt
256
252
  halt 500
257
- halt 404, 'Not found'
258
- halt 'Error message'
253
+ halt 404, "Not found"
254
+ halt "Error message"
259
255
  ```
260
256
 
261
257
  ----
@@ -265,33 +261,33 @@ halt 'Error message'
265
261
  #### GET /users
266
262
 
267
263
  ```bash
268
- curl -i http://localhost:1337/users/:id?name=Berna&age=28&height=180
264
+ curl -i http://localhost:1337/users/:id?name=Berna&level=1&xp=70
269
265
  ```
270
266
 
271
267
  ```ruby
272
268
  params.id # 1
273
269
  params.name # "Berna"
274
- params[:age] # 28
275
- params['height'] # 180
270
+ params[:level] # 1
271
+ params["xp"] # 70
276
272
  ```
277
273
 
278
274
  #### POST with params:
279
275
 
280
276
  ```bash
281
- curl -i -X POST -d 'user[name]=Berna&user[age]=28' http://localhost:1337/users
277
+ curl -i -X POST -d "user[name]=Berna&user[level]=1" http://localhost:1337/users
282
278
  ```
283
279
 
284
280
  #### POST with JSON:
285
281
 
286
282
  ```bash
287
- curl -i -X POST -H "Content-Type: application/json" -d '{ "user": { "name": "Berna", "age": 28 } }' http://localhost:1337/users
283
+ curl -i -X POST -H "Content-Type: application/json" -d "{ "user": { "name": "Berna", "xp": 50 } }" http://localhost:1337/users
288
284
  ```
289
285
 
290
286
  Result:
291
287
 
292
288
  ```ruby
293
289
  params.user.name # "Berna"
294
- params[:user][:age] # "28"
290
+ params[:user][:xp] # 50
295
291
  ```
296
292
 
297
293
  ----
@@ -299,7 +295,7 @@ params[:user][:age] # "28"
299
295
  #### #permit
300
296
 
301
297
  ```ruby
302
- params.user.permit(:name, :age)
298
+ params.user.permit(:name, :level, :xp)
303
299
  ```
304
300
 
305
301
  ----
@@ -315,7 +311,7 @@ params.user.except(:height)
315
311
  ### Request Headers
316
312
 
317
313
  ```ruby
318
- request.headers['Authorization']
314
+ request.headers["Authorization"]
319
315
  ```
320
316
 
321
317
  ----
@@ -323,7 +319,7 @@ request.headers['Authorization']
323
319
  ### Response Headers
324
320
 
325
321
  ```ruby
326
- headers['Header-Name'] = 'Header Value'
322
+ headers["Header-Name"] = "Header Value"
327
323
  ```
328
324
 
329
325
  ----
@@ -332,7 +328,7 @@ headers['Header-Name'] = 'Header Value'
332
328
 
333
329
  ```ruby
334
330
  before_action *actions, only: %i(index show)
335
- after_action *actions, except: %i(destroy)
331
+ after_action *actions, except: :destroy
336
332
  ```
337
333
 
338
334
  ## TODO:
@@ -1,10 +1,12 @@
1
- require 'rack'
2
- require 'json/ext'
3
- require 'dry/inflector'
1
+ # frozen_string_literal: true
4
2
 
5
- require 'fit_api/version'
6
- require 'fit_api/router'
7
- require 'fit_api/controller'
3
+ require "rack"
4
+ require "json/ext"
5
+ require "dry/inflector"
6
+
7
+ require "fit_api/version"
8
+ require "fit_api/router"
9
+ require "fit_api/controller"
8
10
 
9
11
  module FitApi
10
12
  def self.builder
@@ -1,14 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitApi
2
4
  class Halt < StandardError; end
3
5
 
4
6
  class Controller
5
- attr_accessor :response
7
+ attr_accessor :response, :action
6
8
  attr_reader :request, :params, :headers
7
9
 
8
10
  def initialize(request, params)
9
11
  @request = request
10
12
  @params = params
11
- @headers = {}
13
+
14
+ set_default_headers
15
+
16
+ @response = [ 501, @headers, [ 'Not implemented' ] ]
12
17
  end
13
18
 
14
19
  class << self
@@ -18,35 +23,65 @@ module FitApi
18
23
 
19
24
  %i(before after).each do |callback_type|
20
25
  define_method "#{callback_type}_action" do |*callbacks|
21
- executable_actions = callbacks.last.is_a?(Hash) ? callbacks.last : {}
26
+ options = callbacks.last.is_a?(Hash) ? callbacks.last : {}
22
27
 
23
28
  callbacks.each do |method|
24
- unless method.is_a?(Hash)
25
- actions[callback_type] << { method: method }.merge(executable_actions)
26
- end
29
+ next if method.is_a?(Hash)
30
+ actions[callback_type] << { method: method }.merge(options)
27
31
  end
28
32
  end
29
33
  end
30
34
  end
31
35
 
32
- def set_response_headers
33
- headers['Date'] ||= Rack::Utils.rfc2822(Time.now)
34
- headers['Content-Type'] ||= 'application/json'
35
-
36
- headers.each &response.method(:add_header)
37
- end
38
-
39
- def json(object, status = 200)
40
- self.response = Rack::Response.new(JSON.pretty_generate(object), status)
36
+ def json(status = 200, data)
37
+ data = data.to_h unless data.is_a?(Hash) && data.is_a?(String)
38
+ json = JSON.pretty_generate(data)
39
+ @response = [ status, headers, [ json ] ]
41
40
  end
42
41
 
43
42
  def halt(*args)
44
43
  is_int = args.first.is_a?(Integer)
45
44
  status = is_int ? args.first : 400
46
- error = is_int ? (args.count > 1 ? args.last : '') : args.first
45
+ error = is_int ? (args.count > 1 ? args.last : "") : args.first
47
46
 
48
- json(error, status)
47
+ json(status, error.to_h)
49
48
  raise Halt
50
49
  end
50
+
51
+ def invoke(action)
52
+ return unless respond_to?(action)
53
+ self.action = action.to_sym
54
+ trigger_callbacks(:before, action)
55
+ send(action)
56
+ trigger_callbacks(:after, action)
57
+ @response
58
+ end
59
+
60
+ private
61
+
62
+ def set_default_headers
63
+ @headers = {
64
+ "Date" => Rack::Utils.rfc2822(Time.now),
65
+ "Content-Type" => "application/json"
66
+ }
67
+ end
68
+
69
+ def trigger_callbacks(type, action)
70
+ klass = self.class
71
+ while klass != Object
72
+ actions = klass.actions[type].each do |rule|
73
+ send(rule[:method]) if run?(rule, action.to_sym)
74
+ end
75
+ klass = klass.superclass
76
+ end
77
+ end
78
+
79
+ def run?(rule, action)
80
+ except, only = Array(rule[:except]), Array(rule[:only])
81
+
82
+ except.any? && !except.include?(action) ||
83
+ only.any? && only.include?(action) ||
84
+ only.empty? && except.empty?
85
+ end
51
86
  end
52
87
  end
@@ -1,36 +1,45 @@
1
- require 'fit_api/router/mapper'
1
+ # frozen_string_literal: true
2
+
3
+ require "fit_api/router/mapper"
2
4
 
3
5
  module FitApi
4
6
  module Router
5
- def self.call(env)
6
- method, path = env['REQUEST_METHOD'], env['PATH_INFO']
7
- is_root = path == '/'
7
+ module_function
8
8
 
9
- if route = Router.find(method, path, !is_root)
10
- route.invoke(env)
11
- else
12
- status = is_root ? 200 : 404
13
- res = is_root ? 'fit-api is working!' : 'Action not found'
9
+ def call(env)
10
+ method, path = env["REQUEST_METHOD"], env["PATH_INFO"]
11
+ is_root = path == "/"
14
12
 
15
- [ status, { 'Content-Type' => 'application/json' }, [ res.to_json ] ]
13
+ if route = find(method, path, !is_root)
14
+ return route.invoke(env)
16
15
  end
16
+
17
+ status = is_root ? 200 : 404
18
+ res = is_root ? "fit-api is working!" : "Action not found"
19
+
20
+ [ status, { "Content-Type" => "application/json" }, [ res.to_json ] ]
17
21
  end
18
22
 
19
- def self.find(method, path, find_not_found_action = true)
23
+ def find(method, path, fetch_not_found = true)
20
24
  route = mapper.routes[method.downcase].find { |route| route.match? path }
21
25
  return route if route
22
26
 
23
- if find_not_found_action
24
- not_found = find('get', '/404', false)
27
+ if fetch_not_found
28
+ not_found = find("get", "/404", false)
25
29
  return not_found if not_found
26
30
  end
27
31
  end
28
32
 
29
- def self.define(&block)
33
+ def auto_load_path(path = nil)
34
+ return @auto_load_path unless path
35
+ @auto_load_path = path
36
+ end
37
+
38
+ def define(&block)
30
39
  mapper.instance_eval &block
31
40
  end
32
41
 
33
- def self.mapper
42
+ def mapper
34
43
  @mapper ||= Mapper.new
35
44
  end
36
45
  end
@@ -1,4 +1,6 @@
1
- require 'fit_api/router/route'
1
+ # frozen_string_literal: true
2
+
3
+ require "fit_api/router/route"
2
4
 
3
5
  module FitApi
4
6
  module Router
@@ -13,6 +15,7 @@ module FitApi
13
15
  %w(get post put delete patch).each do |verb|
14
16
  define_method verb do |path, options = {}|
15
17
  options[:controller] ||= @controller
18
+
16
19
  route = Route.new(verb, "#{@namespaces.join}#{fix_path(path)}", options)
17
20
  @routes[verb] << route
18
21
  end
@@ -25,15 +28,15 @@ module FitApi
25
28
  end
26
29
 
27
30
  def root(to:)
28
- get '', to: to
31
+ get "", to: to
29
32
  end
30
33
 
31
34
  def not_found(to:)
32
- get '/404', to: to
35
+ get "/404", to: to
33
36
  end
34
37
 
35
38
  def member(&block)
36
- namespace '/:id', controller: @controller, &block
39
+ namespace "/:id", controller: @controller, &block
37
40
  end
38
41
 
39
42
  def collection(&block)
@@ -79,8 +82,8 @@ module FitApi
79
82
  only = options[:only]
80
83
  except = options[:except]
81
84
 
82
- return actions & only if only
83
- return actions - except if except
85
+ return actions & Array(only) if only
86
+ return actions - Array(except) if except
84
87
 
85
88
  actions
86
89
  end
@@ -93,9 +96,9 @@ module FitApi
93
96
  actions.each do |action|
94
97
  case action
95
98
  when :index
96
- get '', to: "#{resource}#index"
99
+ get "", to: "#{resource}#index"
97
100
  when :create
98
- post '', to: "#{resource}#create"
101
+ post "", to: "#{resource}#create"
99
102
  when :show
100
103
  get path, to: "#{resource}#show"
101
104
  when :update
@@ -118,13 +121,13 @@ module FitApi
118
121
  end
119
122
 
120
123
  def get_resource_path(type)
121
- return type == :resources ? '/:id' : ''
124
+ return type == :resources ? "/:id" : ""
122
125
  end
123
126
 
124
127
  def fix_path(path)
125
- fix = path.is_a?(Symbol) || path[0] != '/' && path != ''
128
+ fix = path.is_a?(Symbol) || path[0] != "/" && path != ""
126
129
  path = fix ? "/#{path}" : path
127
- path.gsub(/\/$/, '')
130
+ path.gsub(/\/$/, "")
128
131
  end
129
132
 
130
133
  def s(word)
@@ -1,54 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitApi
2
4
  module Router
3
- class Params
4
- def initialize(hash)
5
- @hash = hash
6
- end
7
-
8
- def to_h
9
- @hash
10
- end
11
-
12
- def to_json
13
- @hash.to_json
14
- end
15
-
5
+ module Params
16
6
  def [](key)
17
- value = @hash[key.to_s]
18
-
7
+ value = super(key.to_s)
19
8
  if value.is_a?(Hash)
20
- self.class.new(value)
21
- else
22
- value
9
+ value.extend(Params)
23
10
  end
11
+ value
24
12
  end
25
13
 
26
- def []=(key, value)
27
- @hash[key.to_s] = value
14
+ def except(*blacklist)
15
+ blacklist.map!(&:to_s)
16
+ build(keys - blacklist)
28
17
  end
29
18
 
30
- def method_missing(method_sym, *arguments, &block)
31
- if @hash.include? method_sym.to_s
32
- send('[]', method_sym.to_s)
33
- else
34
- nil
35
- end
19
+ def permit(*whitelist)
20
+ whitelist.map!(&:to_s)
21
+ build(keys & whitelist)
36
22
  end
37
23
 
38
- def except(*blacklist)
39
- Params.new(
40
- {}.tap do |h|
41
- (@hash.keys - blacklist.map(&:to_s)).each { |k| h[k] = @hash[k] }
42
- end
43
- )
24
+ private
25
+
26
+ def build(new_keys)
27
+ {}.tap do |h|
28
+ new_keys.each { |k| h[k] = self[k] }
29
+ end.extend(Params)
44
30
  end
45
31
 
46
- def permit(*whitelist)
47
- Params.new(
48
- {}.tap do |h|
49
- (@hash.keys & whitelist.map(&:to_s)).each { |k| h[k] = @hash[k] }
50
- end
51
- )
32
+ def method_missing(method_sym, *args, &block)
33
+ attr = self.key?(method_sym) ? method_sym : method_sym.to_s
34
+ self[attr]
52
35
  end
53
36
  end
54
37
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitApi
2
4
  module Router
3
5
  class Parser
@@ -5,7 +7,7 @@ module FitApi
5
7
 
6
8
  def initialize(route, path)
7
9
  @route = route
8
- @path = path.gsub(/\/$/, '')
10
+ @path = path.gsub(/\/$/, "")
9
11
  @match = false
10
12
  @params = {}
11
13
 
@@ -29,12 +31,12 @@ module FitApi
29
31
 
30
32
  params.each_index do |i|
31
33
  @params[params[i]] =
32
- result[i].match(/^\d+$/) ? result[i].to_i : URI.decode(result[i])
34
+ result[i].match(/^\d+$/) ? result[i].to_i : URI.decode_www_form_component(result[i])
33
35
  end
34
36
  end
35
37
 
36
38
  def regexp
37
- @route.gsub(/\:\w+/, '([^\/]*)')
39
+ @route.gsub(/\:\w+/, "([^\/]*)")
38
40
  end
39
41
  end
40
42
  end
@@ -1,87 +1,68 @@
1
- require 'fit_api/router/parser'
2
- require 'fit_api/router/params'
1
+ # frozen_string_literal: true
2
+
3
+ require "fit_api/router/parser"
4
+ require "fit_api/router/params"
3
5
 
4
6
  module FitApi
5
7
  module Router
6
- class Route
7
- attr_reader :verb, :path, :controller, :action
8
+ class Request < Rack::Request
9
+ def headers
10
+ env.select { |k,v| k.start_with? "HTTP_"}.
11
+ transform_keys { |k| k.sub(/^HTTP_/, "").split("_").map(&:capitalize).join("-") }
12
+ end
13
+ end
8
14
 
15
+ class Route
9
16
  def initialize(verb, path, options = {})
10
17
  @verb = verb
11
18
  @path = path
12
19
  @controller = get_controller(options)
13
20
  @action = get_action(options)
21
+
22
+ require_controller
14
23
  end
15
24
 
16
25
  def invoke(env)
17
- request = Request.new(env)
18
- route_params = parse(request.path).params
19
- json_params = JSON.parse(request.body.read) rescue {}
20
- params = Params.new(request.params.merge(route_params).merge(json_params))
21
- controller = Object.const_get("#{@controller.to_s.capitalize}Controller").new(request, params)
26
+ request = Request.new(env)
27
+ params = build_params(request)
28
+ controller = Object.const_get("#{@controller.to_s.capitalize}Controller").new(request, params)
22
29
 
23
- run! controller
30
+ controller.invoke(@action)
24
31
  rescue Halt
25
- controller.set_response_headers
26
32
  controller.response
27
- rescue Exception => ex
28
- error = { message: "#{ex.message} (#{ex.class})", backtrace: ex.backtrace }
29
- controller.json(ENV['RACK_ENV'] == 'production' ? 'An error has occured' : error, 500)
30
33
  end
31
34
 
32
35
  def match?(path)
33
- parse(path).match?
36
+ Parser.new(@path, path).match?
34
37
  end
35
38
 
36
39
  private
37
40
 
38
41
  def get_controller(options)
39
42
  return options[:controller] if options[:controller]
40
- options[:to].split('#').first
43
+ options[:to].split("#").first
41
44
  end
42
45
 
43
46
  def get_action(options)
44
47
  return options[:action] if options[:action]
45
- return options[:to].split('#').last if options[:to]
46
- path[/\w+$/]
47
- end
48
-
49
- def parse(path)
50
- Parser.new(@path, path)
48
+ return options[:to].split("#").last if options[:to]
49
+ @path[/\w+$/]
51
50
  end
52
51
 
53
- def run!(controller)
54
- run_callbacks! controller, :before
55
- controller.send action
56
- run_callbacks! controller, :after
57
- controller.set_response_headers
58
- controller.response
59
- end
60
-
61
- def run_callbacks!(controller, type)
62
- klass = controller.class
63
-
64
- while klass != Object
65
- actions = klass.actions[type].each do |rule|
66
- controller.send(rule[:method]) if run?(rule)
67
- end
68
- klass = klass.superclass
52
+ def require_controller
53
+ if path = Router.auto_load_path
54
+ require "./#{path}/#{@controller}_controller"
69
55
  end
70
56
  end
71
57
 
72
- def run?(rule)
73
- except, only = rule[:except], rule[:only]
58
+ def build_params(request)
59
+ route_params = Parser.new(@path, request.path).params
60
+ params = JSON.parse(request.body.read) rescue request.params
74
61
 
75
- except && !except.map(&:to_s).include?(action) ||
76
- only && only.map(&:to_s).include?(action) ||
77
- !only && !except
78
- end
79
- end
80
-
81
- class Request < Rack::Request
82
- def headers
83
- env.select { |k,v| k.start_with? 'HTTP_'}.
84
- transform_keys { |k| k.sub(/^HTTP_/, '').split('_').map(&:capitalize).join('-') }
62
+ new_params = params.merge(route_params)
63
+ new_params.extend(Params)
64
+ new_params.with_indifferent_access
65
+ new_params
85
66
  end
86
67
  end
87
68
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module FitApi
2
4
  def self.version
3
- '1.1.2'
5
+ "1.1.3"
4
6
  end
5
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fit_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 1.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernardo Castro
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-31 00:00:00.000000000 Z
11
+ date: 2020-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -78,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
78
  version: '0'
79
79
  requirements: []
80
80
  rubyforge_project:
81
- rubygems_version: 2.7.6
81
+ rubygems_version: 2.6.13
82
82
  signing_key:
83
83
  specification_version: 4
84
84
  summary: Lightweight framework for building APIs