grape 0.8.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of grape might be problematic. Click here for more details.

Files changed (78) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -2
  3. data/.rubocop_todo.yml +80 -0
  4. data/.travis.yml +2 -2
  5. data/CHANGELOG.md +21 -2
  6. data/Gemfile +1 -6
  7. data/Guardfile +1 -5
  8. data/README.md +110 -27
  9. data/Rakefile +1 -1
  10. data/UPGRADING.md +35 -0
  11. data/grape.gemspec +5 -2
  12. data/lib/grape.rb +20 -4
  13. data/lib/grape/api.rb +25 -467
  14. data/lib/grape/api/helpers.rb +7 -0
  15. data/lib/grape/dsl/callbacks.rb +27 -0
  16. data/lib/grape/dsl/configuration.rb +27 -0
  17. data/lib/grape/dsl/helpers.rb +86 -0
  18. data/lib/grape/dsl/inside_route.rb +227 -0
  19. data/lib/grape/dsl/middleware.rb +33 -0
  20. data/lib/grape/dsl/parameters.rb +79 -0
  21. data/lib/grape/dsl/request_response.rb +152 -0
  22. data/lib/grape/dsl/routing.rb +172 -0
  23. data/lib/grape/dsl/validations.rb +29 -0
  24. data/lib/grape/endpoint.rb +6 -226
  25. data/lib/grape/error_formatter/base.rb +28 -0
  26. data/lib/grape/error_formatter/json.rb +2 -0
  27. data/lib/grape/error_formatter/txt.rb +2 -0
  28. data/lib/grape/error_formatter/xml.rb +2 -0
  29. data/lib/grape/exceptions/base.rb +6 -0
  30. data/lib/grape/exceptions/validation.rb +3 -3
  31. data/lib/grape/exceptions/validation_errors.rb +19 -6
  32. data/lib/grape/locale/en.yml +5 -3
  33. data/lib/grape/middleware/auth/base.rb +28 -12
  34. data/lib/grape/middleware/auth/dsl.rb +35 -0
  35. data/lib/grape/middleware/auth/strategies.rb +24 -0
  36. data/lib/grape/middleware/auth/strategy_info.rb +15 -0
  37. data/lib/grape/validations.rb +3 -92
  38. data/lib/grape/validations/at_least_one_of.rb +25 -0
  39. data/lib/grape/validations/coerce.rb +2 -2
  40. data/lib/grape/validations/exactly_one_of.rb +2 -2
  41. data/lib/grape/validations/mutual_exclusion.rb +2 -2
  42. data/lib/grape/validations/presence.rb +1 -1
  43. data/lib/grape/validations/regexp.rb +1 -1
  44. data/lib/grape/validations/values.rb +1 -1
  45. data/lib/grape/version.rb +1 -1
  46. data/spec/grape/api/helpers_spec.rb +36 -0
  47. data/spec/grape/api_spec.rb +72 -19
  48. data/spec/grape/dsl/callbacks_spec.rb +44 -0
  49. data/spec/grape/dsl/configuration_spec.rb +37 -0
  50. data/spec/grape/dsl/helpers_spec.rb +54 -0
  51. data/spec/grape/dsl/inside_route_spec.rb +222 -0
  52. data/spec/grape/dsl/middleware_spec.rb +40 -0
  53. data/spec/grape/dsl/parameters_spec.rb +108 -0
  54. data/spec/grape/dsl/request_response_spec.rb +123 -0
  55. data/spec/grape/dsl/routing_spec.rb +132 -0
  56. data/spec/grape/dsl/validations_spec.rb +55 -0
  57. data/spec/grape/endpoint_spec.rb +60 -11
  58. data/spec/grape/entity_spec.rb +9 -4
  59. data/spec/grape/exceptions/validation_errors_spec.rb +31 -1
  60. data/spec/grape/middleware/auth/base_spec.rb +34 -0
  61. data/spec/grape/middleware/auth/dsl_spec.rb +53 -0
  62. data/spec/grape/middleware/auth/strategies_spec.rb +81 -0
  63. data/spec/grape/middleware/error_spec.rb +33 -1
  64. data/spec/grape/middleware/exception_spec.rb +13 -0
  65. data/spec/grape/validations/at_least_one_of_spec.rb +63 -0
  66. data/spec/grape/validations/exactly_one_of_spec.rb +1 -1
  67. data/spec/grape/validations/presence_spec.rb +159 -122
  68. data/spec/grape/validations/zh-CN.yml +1 -1
  69. data/spec/grape/validations_spec.rb +77 -15
  70. data/spec/spec_helper.rb +1 -0
  71. data/spec/support/endpoint_faker.rb +23 -0
  72. metadata +93 -15
  73. data/lib/grape/middleware/auth/basic.rb +0 -13
  74. data/lib/grape/middleware/auth/digest.rb +0 -13
  75. data/lib/grape/middleware/auth/oauth2.rb +0 -83
  76. data/spec/grape/middleware/auth/basic_spec.rb +0 -31
  77. data/spec/grape/middleware/auth/digest_spec.rb +0 -47
  78. data/spec/grape/middleware/auth/oauth2_spec.rb +0 -135
@@ -24,13 +24,16 @@ Gem::Specification.new do |s|
24
24
  s.add_runtime_dependency 'virtus', '>= 1.0.0'
25
25
  s.add_runtime_dependency 'builder'
26
26
 
27
- s.add_development_dependency 'grape-entity', '>= 0.2.0'
27
+ s.add_development_dependency 'grape-entity', '>= 0.4.4'
28
28
  s.add_development_dependency 'rake'
29
29
  s.add_development_dependency 'maruku'
30
30
  s.add_development_dependency 'yard'
31
31
  s.add_development_dependency 'rack-test'
32
- s.add_development_dependency 'rspec', '~> 2.9'
32
+ s.add_development_dependency 'rspec', '~> 3.0'
33
33
  s.add_development_dependency 'bundler'
34
+ s.add_development_dependency 'cookiejar'
35
+ s.add_development_dependency 'rack-contrib'
36
+ s.add_development_dependency 'mime-types'
34
37
 
35
38
  s.files = `git ls-files`.split("\n")
36
39
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -77,10 +77,10 @@ module Grape
77
77
  autoload :Error, 'grape/middleware/error'
78
78
 
79
79
  module Auth
80
- autoload :OAuth2, 'grape/middleware/auth/oauth2'
81
- autoload :Base, 'grape/middleware/auth/base'
82
- autoload :Basic, 'grape/middleware/auth/basic'
83
- autoload :Digest, 'grape/middleware/auth/digest'
80
+ autoload :Base, 'grape/middleware/auth/base'
81
+ autoload :DSL, 'grape/middleware/auth/dsl'
82
+ autoload :StrategyInfo, 'grape/middleware/auth/strategy_info'
83
+ autoload :Strategies, 'grape/middleware/auth/strategies'
84
84
  end
85
85
 
86
86
  module Versioner
@@ -94,6 +94,22 @@ module Grape
94
94
  module Util
95
95
  autoload :HashStack, 'grape/util/hash_stack'
96
96
  end
97
+
98
+ module DSL
99
+ autoload :Callbacks, 'grape/dsl/callbacks'
100
+ autoload :Configuration, 'grape/dsl/configuration'
101
+ autoload :InsideRoute, 'grape/dsl/inside_route'
102
+ autoload :Helpers, 'grape/dsl/helpers'
103
+ autoload :Middleware, 'grape/dsl/middleware'
104
+ autoload :Parameters, 'grape/dsl/parameters'
105
+ autoload :RequestResponse, 'grape/dsl/request_response'
106
+ autoload :Routing, 'grape/dsl/routing'
107
+ autoload :Validations, 'grape/dsl/validations'
108
+ end
109
+
110
+ class API
111
+ autoload :Helpers, 'grape/api/helpers'
112
+ end
97
113
  end
98
114
 
99
115
  require 'grape/version'
@@ -3,22 +3,21 @@ module Grape
3
3
  # creating Grape APIs.Users should subclass this
4
4
  # class in order to build an API.
5
5
  class API
6
- extend Validations::ClassMethods
6
+ extend Grape::Middleware::Auth::DSL
7
+
8
+ include Grape::DSL::Validations
9
+ include Grape::DSL::Callbacks
10
+ include Grape::DSL::Configuration
11
+ include Grape::DSL::Helpers
12
+ include Grape::DSL::Middleware
13
+ include Grape::DSL::RequestResponse
14
+ include Grape::DSL::Routing
7
15
 
8
16
  class << self
9
- attr_reader :endpoints, :instance, :routes, :route_set, :settings, :versions
10
- attr_writer :logger
17
+ attr_reader :instance
11
18
 
12
19
  LOCK = Mutex.new
13
20
 
14
- def logger(logger = nil)
15
- if logger
16
- @logger = logger
17
- else
18
- @logger ||= Logger.new($stdout)
19
- end
20
- end
21
-
22
21
  def reset!
23
22
  @settings = Grape::Util::HashStack.new
24
23
  @route_set = Rack::Mount::RouteSet.new
@@ -44,6 +43,21 @@ module Grape
44
43
  instance.call(env)
45
44
  end
46
45
 
46
+ # Create a scope without affecting the URL.
47
+ #
48
+ # @param name [Symbol] Purely placebo, just allows to to name the scope to make the code more readable.
49
+ def scope(name = nil, &block)
50
+ nest(block)
51
+ end
52
+
53
+ def cascade(value = nil)
54
+ if value.nil?
55
+ settings.key?(:cascade) ? !!settings[:cascade] : true
56
+ else
57
+ set(:cascade, value)
58
+ end
59
+ end
60
+
47
61
  # Set a configuration value for this namespace.
48
62
  #
49
63
  # @param key [Symbol] The key of the configuration variable.
@@ -61,433 +75,6 @@ module Grape
61
75
  settings.imbue(key, value)
62
76
  end
63
77
 
64
- # Define a root URL prefix for your entire API.
65
- def prefix(prefix = nil)
66
- prefix ? set(:root_prefix, prefix) : settings[:root_prefix]
67
- end
68
-
69
- # Do not route HEAD requests to GET requests automatically
70
- def do_not_route_head!
71
- set(:do_not_route_head, true)
72
- end
73
-
74
- # Do not automatically route OPTIONS
75
- def do_not_route_options!
76
- set(:do_not_route_options, true)
77
- end
78
-
79
- # Specify an API version.
80
- #
81
- # @example API with legacy support.
82
- # class MyAPI < Grape::API
83
- # version 'v2'
84
- #
85
- # get '/main' do
86
- # {some: 'data'}
87
- # end
88
- #
89
- # version 'v1' do
90
- # get '/main' do
91
- # {legacy: 'data'}
92
- # end
93
- # end
94
- # end
95
- #
96
- def version(*args, &block)
97
- if args.any?
98
- options = args.pop if args.last.is_a? Hash
99
- options ||= {}
100
- options = { using: :path }.merge(options)
101
-
102
- raise Grape::Exceptions::MissingVendorOption.new if options[:using] == :header && !options.key?(:vendor)
103
-
104
- @versions = versions | args
105
- nest(block) do
106
- set(:version, args)
107
- set(:version_options, options)
108
- end
109
- end
110
-
111
- @versions.last unless @versions.nil?
112
- end
113
-
114
- # Add a description to the next namespace or function.
115
- def desc(description, options = {})
116
- @last_description = options.merge(description: description)
117
- end
118
-
119
- # Specify the default format for the API's serializers.
120
- # May be `:json` or `:txt` (default).
121
- def default_format(new_format = nil)
122
- new_format ? set(:default_format, new_format.to_sym) : settings[:default_format]
123
- end
124
-
125
- # Specify the format for the API's serializers.
126
- # May be `:json`, `:xml`, `:txt`, etc.
127
- def format(new_format = nil)
128
- if new_format
129
- set(:format, new_format.to_sym)
130
- # define the default error formatters
131
- set(:default_error_formatter, Grape::ErrorFormatter::Base.formatter_for(new_format, {}))
132
- # define a single mime type
133
- mime_type = content_types[new_format.to_sym]
134
- raise Grape::Exceptions::MissingMimeType.new(new_format) unless mime_type
135
- settings.imbue(:content_types, new_format.to_sym => mime_type)
136
- else
137
- settings[:format]
138
- end
139
- end
140
-
141
- # Specify a custom formatter for a content-type.
142
- def formatter(content_type, new_formatter)
143
- settings.imbue(:formatters, content_type.to_sym => new_formatter)
144
- end
145
-
146
- # Specify a custom parser for a content-type.
147
- def parser(content_type, new_parser)
148
- settings.imbue(:parsers, content_type.to_sym => new_parser)
149
- end
150
-
151
- # Specify a default error formatter.
152
- def default_error_formatter(new_formatter_name = nil)
153
- if new_formatter_name
154
- new_formatter = Grape::ErrorFormatter::Base.formatter_for(new_formatter_name, {})
155
- set(:default_error_formatter, new_formatter)
156
- else
157
- settings[:default_error_formatter]
158
- end
159
- end
160
-
161
- def error_formatter(format, options)
162
- if options.is_a?(Hash) && options.key?(:with)
163
- formatter = options[:with]
164
- else
165
- formatter = options
166
- end
167
-
168
- settings.imbue(:error_formatters, format.to_sym => formatter)
169
- end
170
-
171
- # Specify additional content-types, e.g.:
172
- # content_type :xls, 'application/vnd.ms-excel'
173
- def content_type(key, val)
174
- settings.imbue(:content_types, key.to_sym => val)
175
- end
176
-
177
- # All available content types.
178
- def content_types
179
- Grape::ContentTypes.content_types_for(settings[:content_types])
180
- end
181
-
182
- # Specify the default status code for errors.
183
- def default_error_status(new_status = nil)
184
- new_status ? set(:default_error_status, new_status) : settings[:default_error_status]
185
- end
186
-
187
- # Allows you to rescue certain exceptions that occur to return
188
- # a grape error rather than raising all the way to the
189
- # server level.
190
- #
191
- # @example Rescue from custom exceptions
192
- # class ExampleAPI < Grape::API
193
- # class CustomError < StandardError; end
194
- #
195
- # rescue_from CustomError
196
- # end
197
- #
198
- # @overload rescue_from(*exception_classes, options = {})
199
- # @param [Array] exception_classes A list of classes that you want to rescue, or
200
- # the symbol :all to rescue from all exceptions.
201
- # @param [Block] block Execution block to handle the given exception.
202
- # @param [Hash] options Options for the rescue usage.
203
- # @option options [Boolean] :backtrace Include a backtrace in the rescue response.
204
- # @option options [Boolean] :rescue_subclasses Also rescue subclasses of exception classes
205
- # @param [Proc] handler Execution proc to handle the given exception as an
206
- # alternative to passing a block
207
- def rescue_from(*args, &block)
208
- if args.last.is_a?(Proc)
209
- handler = args.pop
210
- elsif block_given?
211
- handler = block
212
- end
213
-
214
- options = args.last.is_a?(Hash) ? args.pop : {}
215
- handler ||= proc { options[:with] } if options.key?(:with)
216
-
217
- if args.include?(:all)
218
- set(:rescue_all, true)
219
- imbue :all_rescue_handler, handler
220
- else
221
- handler_type =
222
- case options[:rescue_subclasses]
223
- when nil, true
224
- :rescue_handlers
225
- else
226
- :base_only_rescue_handlers
227
- end
228
-
229
- imbue handler_type, Hash[args.map { |arg| [arg, handler] }]
230
- end
231
-
232
- imbue(:rescue_options, options)
233
- end
234
-
235
- # Allows you to specify a default representation entity for a
236
- # class. This allows you to map your models to their respective
237
- # entities once and then simply call `present` with the model.
238
- #
239
- # @example
240
- # class ExampleAPI < Grape::API
241
- # represent User, with: Entity::User
242
- #
243
- # get '/me' do
244
- # present current_user # with: Entity::User is assumed
245
- # end
246
- # end
247
- #
248
- # Note that Grape will automatically go up the class ancestry to
249
- # try to find a representing entity, so if you, for example, define
250
- # an entity to represent `Object` then all presented objects will
251
- # bubble up and utilize the entity provided on that `represent` call.
252
- #
253
- # @param model_class [Class] The model class that will be represented.
254
- # @option options [Class] :with The entity class that will represent the model.
255
- def represent(model_class, options)
256
- raise Grape::Exceptions::InvalidWithOptionForRepresent.new unless options[:with] && options[:with].is_a?(Class)
257
- imbue(:representations, model_class => options[:with])
258
- end
259
-
260
- # Add helper methods that will be accessible from any
261
- # endpoint within this namespace (and child namespaces).
262
- #
263
- # When called without a block, all known helpers within this scope
264
- # are included.
265
- #
266
- # @param [Module] new_mod optional module of methods to include
267
- # @param [Block] block optional block of methods to include
268
- #
269
- # @example Define some helpers.
270
- #
271
- # class ExampleAPI < Grape::API
272
- # helpers do
273
- # def current_user
274
- # User.find_by_id(params[:token])
275
- # end
276
- # end
277
- # end
278
- #
279
- def helpers(new_mod = nil, &block)
280
- if block_given? || new_mod
281
- mod = settings.peek[:helpers] || Module.new
282
- if new_mod
283
- inject_api_helpers_to_mod(new_mod) if new_mod.is_a?(Helpers)
284
- mod.class_eval do
285
- include new_mod
286
- end
287
- end
288
- if block_given?
289
- inject_api_helpers_to_mod(mod) do
290
- mod.class_eval(&block)
291
- end
292
- end
293
- set(:helpers, mod)
294
- else
295
- mod = Module.new
296
- settings.stack.each do |s|
297
- mod.send :include, s[:helpers] if s[:helpers]
298
- end
299
- change!
300
- mod
301
- end
302
- end
303
-
304
- # Add an authentication type to the API. Currently
305
- # only `:http_basic`, `:http_digest` and `:oauth2` are supported.
306
- def auth(type = nil, options = {}, &block)
307
- if type
308
- set(:auth, { type: type.to_sym, proc: block }.merge(options))
309
- else
310
- settings[:auth]
311
- end
312
- end
313
-
314
- # Add HTTP Basic authorization to the API.
315
- #
316
- # @param [Hash] options A hash of options.
317
- # @option options [String] :realm "API Authorization" The HTTP Basic realm.
318
- def http_basic(options = {}, &block)
319
- options[:realm] ||= "API Authorization"
320
- auth :http_basic, options, &block
321
- end
322
-
323
- def http_digest(options = {}, &block)
324
- options[:realm] ||= "API Authorization"
325
- options[:opaque] ||= "secret"
326
- auth :http_digest, options, &block
327
- end
328
-
329
- def mount(mounts)
330
- mounts = { mounts => '/' } unless mounts.respond_to?(:each_pair)
331
- mounts.each_pair do |app, path|
332
- if app.respond_to?(:inherit_settings, true)
333
- app_settings = settings.clone
334
- mount_path = Rack::Mount::Utils.normalize_path([settings[:mount_path], path].compact.join("/"))
335
- app_settings.set :mount_path, mount_path
336
- app.inherit_settings(app_settings)
337
- end
338
- endpoints << Grape::Endpoint.new(
339
- settings.clone,
340
- method: :any,
341
- path: path,
342
- app: app
343
- )
344
- end
345
- end
346
-
347
- # Defines a route that will be recognized
348
- # by the Grape API.
349
- #
350
- # @param methods [HTTP Verb] One or more HTTP verbs that are accepted by this route. Set to `:any` if you want any verb to be accepted.
351
- # @param paths [String] One or more strings representing the URL segment(s) for this route.
352
- #
353
- # @example Defining a basic route.
354
- # class MyAPI < Grape::API
355
- # route(:any, '/hello') do
356
- # {hello: 'world'}
357
- # end
358
- # end
359
- def route(methods, paths = ['/'], route_options = {}, &block)
360
- endpoint_options = {
361
- method: methods,
362
- path: paths,
363
- route_options: (@namespace_description || {}).deep_merge(@last_description || {}).deep_merge(route_options || {})
364
- }
365
- endpoints << Grape::Endpoint.new(settings.clone, endpoint_options, &block)
366
-
367
- @last_description = nil
368
- reset_validations!
369
- end
370
-
371
- def before(&block)
372
- imbue(:befores, [block])
373
- end
374
-
375
- def before_validation(&block)
376
- imbue(:before_validations, [block])
377
- end
378
-
379
- def after_validation(&block)
380
- imbue(:after_validations, [block])
381
- end
382
-
383
- def after(&block)
384
- imbue(:afters, [block])
385
- end
386
-
387
- def get(paths = ['/'], options = {}, &block)
388
- route('GET', paths, options, &block)
389
- end
390
-
391
- def post(paths = ['/'], options = {}, &block)
392
- route('POST', paths, options, &block)
393
- end
394
-
395
- def put(paths = ['/'], options = {}, &block)
396
- route('PUT', paths, options, &block)
397
- end
398
-
399
- def head(paths = ['/'], options = {}, &block)
400
- route('HEAD', paths, options, &block)
401
- end
402
-
403
- def delete(paths = ['/'], options = {}, &block)
404
- route('DELETE', paths, options, &block)
405
- end
406
-
407
- def options(paths = ['/'], options = {}, &block)
408
- route('OPTIONS', paths, options, &block)
409
- end
410
-
411
- def patch(paths = ['/'], options = {}, &block)
412
- route('PATCH', paths, options, &block)
413
- end
414
-
415
- def namespace(space = nil, options = {}, &block)
416
- if space || block_given?
417
- previous_namespace_description = @namespace_description
418
- @namespace_description = (@namespace_description || {}).deep_merge(@last_description || {})
419
- @last_description = nil
420
- nest(block) do
421
- set(:namespace, Namespace.new(space, options)) if space
422
- end
423
- @namespace_description = previous_namespace_description
424
- else
425
- Namespace.joined_space_path(settings)
426
- end
427
- end
428
-
429
- # Thie method allows you to quickly define a parameter route segment
430
- # in your API.
431
- #
432
- # @param param [Symbol] The name of the parameter you wish to declare.
433
- # @option options [Regexp] You may supply a regular expression that the declared parameter must meet.
434
- def route_param(param, options = {}, &block)
435
- options = options.dup
436
- options[:requirements] = { param.to_sym => options[:requirements] } if options[:requirements].is_a?(Regexp)
437
- namespace(":#{param}", options, &block)
438
- end
439
-
440
- alias_method :group, :namespace
441
- alias_method :resource, :namespace
442
- alias_method :resources, :namespace
443
- alias_method :segment, :namespace
444
-
445
- # Create a scope without affecting the URL.
446
- #
447
- # @param name [Symbol] Purely placebo, just allows to to name the scope to make the code more readable.
448
- def scope(name = nil, &block)
449
- nest(block)
450
- end
451
-
452
- # Apply a custom middleware to the API. Applies
453
- # to the current namespace and any children, but
454
- # not parents.
455
- #
456
- # @param middleware_class [Class] The class of the middleware you'd like
457
- # to inject.
458
- def use(middleware_class, *args, &block)
459
- arr = [middleware_class, *args]
460
- arr << block if block_given?
461
- imbue(:middleware, [arr])
462
- end
463
-
464
- # Retrieve an array of the middleware classes
465
- # and arguments that are currently applied to the
466
- # application.
467
- def middleware
468
- settings.stack.inject([]) do |a, s|
469
- a += s[:middleware] if s[:middleware]
470
- a
471
- end
472
- end
473
-
474
- # An array of API routes.
475
- def routes
476
- @routes ||= prepare_routes
477
- end
478
-
479
- def versions
480
- @versions ||= []
481
- end
482
-
483
- def cascade(value = nil)
484
- if value.nil?
485
- settings.key?(:cascade) ? !!settings[:cascade] : true
486
- else
487
- set(:cascade, value)
488
- end
489
- end
490
-
491
78
  protected
492
79
 
493
80
  def prepare_routes
@@ -526,12 +113,6 @@ module Grape
526
113
  e.options[:app].inherit_settings(other_stack) if e.options[:app].respond_to?(:inherit_settings, true)
527
114
  end
528
115
  end
529
-
530
- def inject_api_helpers_to_mod(mod, &block)
531
- mod.extend(Helpers)
532
- yield if block_given?
533
- mod.api_changed(self)
534
- end
535
116
  end
536
117
 
537
118
  def initialize
@@ -619,28 +200,5 @@ module Grape
619
200
  yield
620
201
  self.class.settings.pop
621
202
  end
622
-
623
- # This module extends user defined helpers
624
- # to provide some API-specific functionality
625
- module Helpers
626
- attr_accessor :api
627
- def params(name, &block)
628
- @named_params ||= {}
629
- @named_params.merge! name => block
630
- end
631
-
632
- def api_changed(new_api)
633
- @api = new_api
634
- process_named_params
635
- end
636
-
637
- protected
638
-
639
- def process_named_params
640
- if @named_params && @named_params.any?
641
- api.imbue(:named_params, @named_params)
642
- end
643
- end
644
- end
645
203
  end
646
204
  end