Skip to content

Commit

Permalink
Extended ParamBulder to be included in an entire API or namespace.
Browse files Browse the repository at this point in the history
  • Loading branch information
dblock committed Apr 14, 2017
1 parent 1bd1a21 commit fb4b60f
Show file tree
Hide file tree
Showing 16 changed files with 385 additions and 210 deletions.
25 changes: 19 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
- [Param](#param)
- [Describing Methods](#describing-methods)
- [Parameters](#parameters)
- [Params Class](#params-class)
- [Declared](#declared)
- [Include Missing](#include-missing)
- [Parameter Validation and Coercion](#parameter-validation-and-coercion)
Expand Down Expand Up @@ -501,9 +502,19 @@ Route string parameters will have precedence.

By default parameters are available as `ActiveSupport::HashWithIndifferentAccess`. This can be changed to, for example, Ruby `Hash` or `Hashie::Mash` for the entire API.

[TODO]
```ruby
class API < Grape::API
include Grape::Extensions::Hashie::Mash::ParamBuilder

params do
optional :color, type: String
end
get do
params.color # instead of params[:color]
end
```

The class can be overridden on individual parameter blocks using `build_with` as follows.
The class can also be overridden on individual parameter blocks using `build_with` as follows.

```ruby
params do
Expand All @@ -514,6 +525,8 @@ end

In the example above, `params["color"]` will return `nil` since `params` is a plain `Hash`.

Available parameter builders are `Grape::Extensions::Hash::ParamBuilder`, `Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder` and `Grape::Extensions::Hashie::Mash::ParamBuilder`.

### Declared

Grape allows you to access only the parameters that have been declared by your `params` block. It filters out the params that have been passed, but are not allowed. Consider the following API endpoint:
Expand All @@ -526,7 +539,7 @@ post 'users/signup' do
end
````

If we do not specify any params, `declared` will return an empty `ActiveSupport::HashWithIndifferentAccess` hash.
If you do not specify any parameters, `declared` will return an empty hash.

**Request**

Expand All @@ -543,8 +556,8 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d

````

Once we add parameters requirements, grape will start returning only the declared params[:
]
Once we add parameters requirements, grape will start returning only the declared parameters.

````ruby
format :json

Expand Down Expand Up @@ -579,7 +592,7 @@ curl -X POST -H "Content-Type: application/json" localhost:9292/users/signup -d
}
````

The returned hash is a `ActiveSupport::HashWithIndifferentAccess` hash.
The returned hash is an `ActiveSupport::HashWithIndifferentAccess`.

The `#declared` method is not available to `before` filters, as those are evaluated prior to parameter coercion.

Expand Down
30 changes: 27 additions & 3 deletions UPGRADING.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,33 @@ Upgrading Grape

#### Changes in Parameter Class

The default class for `params` has changed from `Hashie::Mash` to `ActiveSupport::HashWithIndifferentAccess` and the `hashie` dependency has been removed. To restore the behavior of prior versions, add `hashie` to your `Gemfile` and use `TODO`.
The default class for `params` has changed from `Hashie::Mash` to `ActiveSupport::HashWithIndifferentAccess` and the `hashie` dependency has been removed. This means that by default you can no longer access parameters by method name.

[TODO]
```
class API < Grape::API
params do
optional :color, type: String
end
get do
params[:color] # use params[:color] instead of params.color
end
end
```

To restore the behavior of prior versions, add `hashie` to your `Gemfile` and `include Grape::Extensions::Hashie::Mash::ParamBuilder` in your API.

```
class API < Grape::API
include Grape::Extensions::Hashie::Mash::ParamBuilder
params do
optional :color, type: String
end
get do
# params.color works
end
end
```

This behavior can also be overridden on individual parameter blocks using `build_with`.

Expand All @@ -26,7 +50,7 @@ def request
end
```

See [#1594](https://github.com/ruby-grape/grape/pull/1594) for more information.
See [#1610](https://github.com/ruby-grape/grape/pull/1610) for more information.

### Upgrading to >= 0.19.1

Expand Down
39 changes: 22 additions & 17 deletions lib/grape.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
I18n.load_path << File.expand_path('../grape/locale/en.yml', __FILE__)

module Grape
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload

eager_autoload do
autoload :API
Expand All @@ -47,14 +47,14 @@ module Grape
end

module Http
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
eager_autoload do
autoload :Headers
end
end

module Exceptions
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Base
autoload :Validation
autoload :ValidationArrayErrors
Expand All @@ -78,22 +78,27 @@ module Exceptions
end

module Extensions
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload

autoload :DeepMergeableHash
autoload :DeepSymbolizeHash
autoload :Hash
autoload :HashWithIndifferentAccess

module ActiveSupport
extend ::ActiveSupport::Autoload

autoload :HashWithIndifferentAccess
end

module Hashie
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload

autoload :Mash
end
end

module Middleware
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Base
autoload :Versioner
autoload :Formatter
Expand All @@ -102,15 +107,15 @@ module Middleware
autoload :Stack

module Auth
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Base
autoload :DSL
autoload :StrategyInfo
autoload :Strategies
end

module Versioner
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Path
autoload :Header
autoload :Param
Expand All @@ -119,7 +124,7 @@ module Versioner
end

module Util
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :InheritableValues
autoload :StackableValues
autoload :ReverseStackableValues
Expand All @@ -129,29 +134,29 @@ module Util
end

module ErrorFormatter
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Base
autoload :Json
autoload :Txt
autoload :Xml
end

module Formatter
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Json
autoload :SerializableHash
autoload :Txt
autoload :Xml
end

module Parser
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Json
autoload :Xml
end

module DSL
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
eager_autoload do
autoload :API
autoload :Callbacks
Expand All @@ -170,17 +175,17 @@ module DSL
end

class API
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Helpers
end

module Presenters
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :Presenter
end

module ServeFile
extend ActiveSupport::Autoload
extend ::ActiveSupport::Autoload
autoload :FileResponse
autoload :FileBody
autoload :SendfileResponse
Expand Down
7 changes: 4 additions & 3 deletions lib/grape/dsl/parameters.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ module Parameters
# Set the module used to build the request.params.
#
# @param build_with the ParamBuilder module to use when building request.params
# Available builders are;
# * Grape::Extensions::HashWithIndifferentAccess::ParamBuilder (default)
# Available builders are:
#
# * Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder (default)
# * Grape::Extensions::Hash::ParamBuilder
# * Grape::Extensions::Hashie::Mash::ParamBuilder
#
Expand All @@ -30,7 +31,7 @@ module Parameters
# end
# end
def build_with(build_with = nil)
@api.namespace_inheritable(:build_with, build_with)
@api.namespace_inheritable(:build_params_with, build_with)
end

# Include reusable params rules among current.
Expand Down
2 changes: 1 addition & 1 deletion lib/grape/endpoint.rb
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ def equals?(e)
def run
ActiveSupport::Notifications.instrument('endpoint_run.grape', endpoint: self, env: env) do
@header = {}
@request = Grape::Request.new(env, build_params_with: namespace_inheritable(:build_with))
@request = Grape::Request.new(env, build_params_with: namespace_inheritable(:build_params_with))
@params = @request.params
@headers = @request.headers

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module Grape
module Extensions
module ActiveSupport
module HashWithIndifferentAccess
extend ::ActiveSupport::Concern

included do
namespace_inheritable(:build_params_with, Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder)
end

def params_builder
Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
end

module ParamBuilder
def build_params
params = ::ActiveSupport::HashWithIndifferentAccess[rack_params]
params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS]
params
end
end
end
end
end
end
6 changes: 6 additions & 0 deletions lib/grape/extensions/hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ module Grape
module Extensions
module Hash
module ParamBuilder
extend ::ActiveSupport::Concern

included do
namespace_inheritable(:build_params_with, Grape::Extensions::Hash::ParamBuilder)
end

def build_params
params = Grape::Extensions::DeepMergeableHash[rack_params]
params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS]
Expand Down
17 changes: 0 additions & 17 deletions lib/grape/extensions/hash_with_indifferent_access.rb

This file was deleted.

14 changes: 10 additions & 4 deletions lib/grape/extensions/hashie/mash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@ module Grape
module Extensions
module Hashie
module Mash
def params_builder
Grape::Extensions::Hashie::Mash::ParamBuilder
end

module ParamBuilder
extend ::ActiveSupport::Concern

included do
namespace_inheritable(:build_params_with, Grape::Extensions::Hashie::Mash::ParamBuilder)
end

def params_builder
Grape::Extensions::Hashie::Mash::ParamBuilder
end

def build_params
params = ::Hashie::Mash.new(rack_params)
params.deep_merge!(grape_routing_args) if env[Grape::Env::GRAPE_ROUTING_ARGS]
Expand Down
2 changes: 1 addition & 1 deletion lib/grape/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Request < Rack::Request
alias rack_params params

def initialize(env, options = {})
extend options[:build_params_with] || Grape::Extensions::HashWithIndifferentAccess::ParamBuilder
extend options[:build_params_with] || Grape::Extensions::ActiveSupport::HashWithIndifferentAccess::ParamBuilder
super(env)
end

Expand Down
2 changes: 1 addition & 1 deletion lib/grape/validations/types/custom_type_coercer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def infer_type_check(type)
# Enforce symbolized keys for complex types
# by wrapping the coercion method such that
# any Hash objects in the immediate heirarchy
# have their keys recursively symbolized
# have their keys recursively symbolized.
# This helps common libs such as JSON to work easily.
#
# @param type see #new
Expand Down
Loading

0 comments on commit fb4b60f

Please sign in to comment.