I'd like to propose that Rack::Requset#params support the nested hash
convention.
In Rails, a query string "post[title]=Hello" will be parsed as
{ "post" => { "title" => "Hello" } }. Rack::Request will parse it as
{ "post[title]" => "Hello" }.
AFAIK, Merb follows the same convention as well, and I'm really
curious what other frameworks are doing the same. If this the defacto
params parsing style I think Rack should support it too.
On Sat, Dec 27, 2008 at 4:24 PM, Josh Peek <j...@joshpeek.com> wrote:
> I'd like to propose that Rack::Requset#params support the nested hash > convention.
> In Rails, a query string "post[title]=Hello" will be parsed as > { "post" => { "title" => "Hello" } }. Rack::Request will parse it as > { "post[title]" => "Hello" }.
> AFAIK, Merb follows the same convention as well, and I'm really > curious what other frameworks are doing the same. If this the defacto > params parsing style I think Rack should support it too.
+1 here as well. Mack does the same thing too. I was thinking today that this should be put into Rack as well I say let's pick the best implementation of it and put it into Rack.
Should we also merge in date/time select parameter parsing too?
Also what do people think about string/symbol retrieval of params from the request parameters?
-------- Mark Bates
On Dec 27, 2008, at 7:32 PM, "Yehuda Katz" <wyc...@gmail.com> wrote:
> On Sat, Dec 27, 2008 at 4:24 PM, Josh Peek <j...@joshpeek.com> wrote:
> I'd like to propose that Rack::Requset#params support the nested hash > convention.
> In Rails, a query string "post[title]=Hello" will be parsed as > { "post" => { "title" => "Hello" } }. Rack::Request will parse it as > { "post[title]" => "Hello" }.
> AFAIK, Merb follows the same convention as well, and I'm really > curious what other frameworks are doing the same. If this the defacto > params parsing style I think Rack should support it too.
Josh Peek wrote: > I'd like to propose that Rack::Requset#params support the nested hash > convention.
> In Rails, a query string "post[title]=Hello" will be parsed as > { "post" => { "title" => "Hello" } }. Rack::Request will parse it as > { "post[title]" => "Hello" }.
Why shouldn't this be application-level behavior, or at least a Rack plugin, rather than default, built-in behavior?
While this happens to be common behavior in most Ruby Web frameworks (I believe Ramaze follows this as well) I'm leery of libs that make certain assumptions about data.
I'm not a huge fan of adding more and more features to Rack::Request. The setting up of hashes in the params makes sense but adds the complication of a param value being a String, an Array, or a Hash. I'd vote yea due to the convenience it provides. With an 'eh' on parsing issues.
Parameters retrievable via symbols and strings is a right out no to me. The issue of identity vs content. Also, how would you deal with environments running with $SAFE > 0? Or are you talking about stringifying all symbol key lookups, which creates additional overhead as well as defeating the general point of symbol keyed hashes.
On Sat, Dec 27, 2008 at 17:03, Mark Bates <m...@mackframework.com> wrote: > +1 here as well. Mack does the same thing too. I was thinking today that > this should be put into Rack as well I say let's pick the best > implementation of it and put it into Rack. > Should we also merge in date/time select parameter parsing too? > Also what do people think about string/symbol retrieval of params from the > request parameters?
> -------- > Mark Bates > On Dec 27, 2008, at 7:32 PM, "Yehuda Katz" <wyc...@gmail.com> wrote:
> +1 > -- Yehuda
> On Sat, Dec 27, 2008 at 4:24 PM, Josh Peek <j...@joshpeek.com> wrote:
>> I'd like to propose that Rack::Requset#params support the nested hash >> convention.
>> In Rails, a query string "post[title]=Hello" will be parsed as >> { "post" => { "title" => "Hello" } }. Rack::Request will parse it as >> { "post[title]" => "Hello" }.
>> AFAIK, Merb follows the same convention as well, and I'm really >> curious what other frameworks are doing the same. If this the defacto >> params parsing style I think Rack should support it too.
On Sun, Dec 28, 2008 at 11:53 AM, James Britt <james.br...@gmail.com> wrote:
> Josh Peek wrote:
>> I'd like to propose that Rack::Requset#params support the nested hash >> convention.
>> In Rails, a query string "post[title]=Hello" will be parsed as >> { "post" => { "title" => "Hello" } }. Rack::Request will parse it as >> { "post[title]" => "Hello" }.
> Why shouldn't this be application-level behavior, or at least a Rack plugin, > rather than default, built-in behavior?
> While this happens to be common behavior in most Ruby Web frameworks (I > believe Ramaze follows this as well) I'm leery of libs that make certain > assumptions about data.
Indeed, there are issues with parsing that might not reach a consent. (Ramaze/Innate) are actually reparsing Request#params with less than stellar results in performance and a few divergences from the normal (say PHP) behaviour. I think it would be good to take a look at the existing implementations, line them up and see which one is the fittest to make a suitable middleware anybody can use.
The problem with a middleware is that it cannot be lazy-loaded without hacks. I think this belongs in Rack::Request. We can call it robust_params or something to distinguish it from the simpler version. -- Yehuda
On Sat, Dec 27, 2008 at 7:36 PM, Michael Fellinger <m.fellin...@gmail.com>wrote:
> On Sun, Dec 28, 2008 at 11:53 AM, James Britt <james.br...@gmail.com> > wrote:
> > Josh Peek wrote:
> >> I'd like to propose that Rack::Requset#params support the nested hash > >> convention.
> >> In Rails, a query string "post[title]=Hello" will be parsed as > >> { "post" => { "title" => "Hello" } }. Rack::Request will parse it as > >> { "post[title]" => "Hello" }.
> > Why shouldn't this be application-level behavior, or at least a Rack > plugin, > > rather than default, built-in behavior?
> > While this happens to be common behavior in most Ruby Web frameworks (I > > believe Ramaze follows this as well) I'm leery of libs that make certain > > assumptions about data.
> Indeed, there are issues with parsing that might not reach a consent. > (Ramaze/Innate) are actually reparsing Request#params with less than > stellar results in performance and a few divergences from the normal > (say PHP) behaviour. > I think it would be good to take a look at the existing > implementations, line them up and see which one is the fittest to make > a suitable middleware anybody can use.
On Sun, Dec 28, 2008 at 12:47 PM, Yehuda Katz <wyc...@gmail.com> wrote: > The problem with a middleware is that it cannot be lazy-loaded without > hacks. I think this belongs in Rack::Request. We can call it robust_params > or something to distinguish it from the simpler version.
> On Sat, Dec 27, 2008 at 7:36 PM, Michael Fellinger <m.fellin...@gmail.com> > wrote:
>> On Sun, Dec 28, 2008 at 11:53 AM, James Britt <james.br...@gmail.com> >> wrote:
>> > Josh Peek wrote:
>> >> I'd like to propose that Rack::Requset#params support the nested hash >> >> convention.
>> >> In Rails, a query string "post[title]=Hello" will be parsed as >> >> { "post" => { "title" => "Hello" } }. Rack::Request will parse it as >> >> { "post[title]" => "Hello" }.
>> > Why shouldn't this be application-level behavior, or at least a Rack >> > plugin, >> > rather than default, built-in behavior?
>> > While this happens to be common behavior in most Ruby Web frameworks (I >> > believe Ramaze follows this as well) I'm leery of libs that make certain >> > assumptions about data.
>> Indeed, there are issues with parsing that might not reach a consent. >> (Ramaze/Innate) are actually reparsing Request#params with less than >> stellar results in performance and a few divergences from the normal >> (say PHP) behaviour. >> I think it would be good to take a look at the existing >> implementations, line them up and see which one is the fittest to make >> a suitable middleware anybody can use.
One of the traits that makes Rack so powerful is its minimalist simplicity. While having parameter parsing based on a hash convention might be valuable to some frameworks, it is extraneous for others. My vote would be to keep this in middleware for those who need it. If the parameter parsing technique is implemented in a module and then hooked into to a minimal call method in a piece of rack-contrib middleware, then authors of other middleware can choose to either note its upstream requirement in their documentation or, more ideally, apply the mixin in their own middleware. Further, there seems to be some concern about when things are loaded and processed upstream and how to vary behavior based on this downstream. In the parameter parsing scenario, MiddlewareB may question if ParamParsingMiddlewareA has been executed upstream, for example. HTTP solved this problem with the Via header and it may be helpful in thinking about similar solutions for Rack:
The above linked Via header shouldn't be used to declare middleware inside of Rack because it is intended to document things happening over the wire whereas Rack is of course self-contained. However, the specific question of "what is upstream" came up in CloudKit when the OpenID Filter needed to know whether to also send OAuth Discovery challenge headers along with its login page. A stack-scoped "cloudkit.via" entry was added to the environment and behaves in a similar manner to Via headers in HTTP.
In the case of Rack, each piece of middleware could drop a "pseudo via" entry into the environment, perhaps based on a canonical version of its gem name or main class name.
> On Sun, Dec 28, 2008 at 12:47 PM, Yehuda Katz <wyc...@gmail.com> wrote: > > The problem with a middleware is that it cannot be lazy-loaded without > > hacks. I think this belongs in Rack::Request. We can call it > robust_params > > or something to distinguish it from the simpler version.
> In rack core or contrib?
> > -- Yehuda
> > On Sat, Dec 27, 2008 at 7:36 PM, Michael Fellinger < > m.fellin...@gmail.com> > > wrote:
> >> On Sun, Dec 28, 2008 at 11:53 AM, James Britt <james.br...@gmail.com> > >> wrote:
> >> > Josh Peek wrote:
> >> >> I'd like to propose that Rack::Requset#params support the nested hash > >> >> convention.
> >> >> In Rails, a query string "post[title]=Hello" will be parsed as > >> >> { "post" => { "title" => "Hello" } }. Rack::Request will parse it as > >> >> { "post[title]" => "Hello" }.
> >> > Why shouldn't this be application-level behavior, or at least a Rack > >> > plugin, > >> > rather than default, built-in behavior?
> >> > While this happens to be common behavior in most Ruby Web frameworks > (I > >> > believe Ramaze follows this as well) I'm leery of libs that make > certain > >> > assumptions about data.
> >> Indeed, there are issues with parsing that might not reach a consent. > >> (Ramaze/Innate) are actually reparsing Request#params with less than > >> stellar results in performance and a few divergences from the normal > >> (say PHP) behaviour. > >> I think it would be good to take a look at the existing > >> implementations, line them up and see which one is the fittest to make > >> a suitable middleware anybody can use.
I think the specific issue of interest in this thread, though, is adding support for nested params parsing.
I'm in favor of it, though I don't have the evidence from any specific RFC mentioning this support for nesting (please provide if there exists).
I like to think of Rack as a culmination of experience and expertise for web development practices and implementations in the Ruby community... a bit lofty for the reality of it, but it's still a goal I have in my approach to Rack's implementation. Because of this, I think that Rack should be able to handle anything web standards provide for... including nested params which occurs frequently.
Making this behavior a part of the middleware may prove difficult to implement in Rack::Request since it must first discern if there is the middleware available and secondly it must then parse it. There are lots of problems, like whether to be specific or support all kinds of hooks for other middleware to change how request params are parsed (which I'm against).
Let's keep it simple by parsing nested params. If anything, we can see what the performance difference is... keeping in mind that it only occurs once now that we memoize the Rack::Request object.
On Sun, Dec 28, 2008 at 1:12 AM, Jon Crosby <jon.r.cro...@gmail.com> wrote: > One of the traits that makes Rack so powerful is its minimalist simplicity. > While having parameter parsing based on a hash convention might be valuable > to some frameworks, it is extraneous for others. My vote would be to keep > this in middleware for those who need it. If the parameter parsing technique > is implemented in a module and then hooked into to a minimal call method in > a piece of rack-contrib middleware, then authors of other middleware can > choose to either note its upstream requirement in their documentation or, > more ideally, apply the mixin in their own middleware. > Further, there seems to be some concern about when things are loaded and > processed upstream and how to vary behavior based on this downstream. In the > parameter parsing scenario, MiddlewareB may question if > ParamParsingMiddlewareA has been executed upstream, for example. HTTP solved > this problem with the Via header and it may be helpful in thinking about > similar solutions for Rack:
> The above linked Via header shouldn't be used to declare middleware inside > of Rack because it is intended to document things happening over the wire > whereas Rack is of course self-contained. However, the specific question of > "what is upstream" came up in CloudKit when the OpenID Filter needed to know > whether to also send OAuth Discovery challenge headers along with its login > page. A stack-scoped "cloudkit.via" entry was added to the environment and > behaves in a similar manner to Via headers in HTTP.
> In the case of Rack, each piece of middleware could drop a "pseudo via" > entry into the environment, perhaps based on a canonical version of its gem > name or main class name.
> On Sat, Dec 27, 2008 at 8:41 PM, Michael Fellinger <m.fellin...@gmail.com>wrote:
>> On Sun, Dec 28, 2008 at 12:47 PM, Yehuda Katz <wyc...@gmail.com> wrote: >> > The problem with a middleware is that it cannot be lazy-loaded without >> > hacks. I think this belongs in Rack::Request. We can call it >> robust_params >> > or something to distinguish it from the simpler version.
>> In rack core or contrib?
>> > -- Yehuda
>> > On Sat, Dec 27, 2008 at 7:36 PM, Michael Fellinger < >> m.fellin...@gmail.com> >> > wrote:
>> >> On Sun, Dec 28, 2008 at 11:53 AM, James Britt <james.br...@gmail.com> >> >> wrote:
>> >> > Josh Peek wrote:
>> >> >> I'd like to propose that Rack::Requset#params support the nested >> hash >> >> >> convention.
>> >> >> In Rails, a query string "post[title]=Hello" will be parsed as >> >> >> { "post" => { "title" => "Hello" } }. Rack::Request will parse it as >> >> >> { "post[title]" => "Hello" }.
>> >> > Why shouldn't this be application-level behavior, or at least a Rack >> >> > plugin, >> >> > rather than default, built-in behavior?
>> >> > While this happens to be common behavior in most Ruby Web frameworks >> (I >> >> > believe Ramaze follows this as well) I'm leery of libs that make >> certain >> >> > assumptions about data.
>> >> Indeed, there are issues with parsing that might not reach a consent. >> >> (Ramaze/Innate) are actually reparsing Request#params with less than >> >> stellar results in performance and a few divergences from the normal >> >> (say PHP) behaviour. >> >> I think it would be good to take a look at the existing >> >> implementations, line them up and see which one is the fittest to make >> >> a suitable middleware anybody can use.
# What was accidentally posted in the wrong thread. Honestly, the idea of a rack-contrib mixin with a #robust_params makes the most sense to me. Memoizing the superduper params hash in a different location in the env for later retrieval similar to the way params does.
On Sat, Dec 27, 2008 at 19:47, Yehuda Katz <wyc...@gmail.com> wrote: > The problem with a middleware is that it cannot be lazy-loaded without > hacks. I think this belongs in Rack::Request. We can call it robust_params > or something to distinguish it from the simpler version. > -- Yehuda
> On Sat, Dec 27, 2008 at 7:36 PM, Michael Fellinger <m.fellin...@gmail.com> > wrote:
>> On Sun, Dec 28, 2008 at 11:53 AM, James Britt <james.br...@gmail.com> >> wrote:
>> > Josh Peek wrote:
>> >> I'd like to propose that Rack::Requset#params support the nested hash >> >> convention.
>> >> In Rails, a query string "post[title]=Hello" will be parsed as >> >> { "post" => { "title" => "Hello" } }. Rack::Request will parse it as >> >> { "post[title]" => "Hello" }.
>> > Why shouldn't this be application-level behavior, or at least a Rack >> > plugin, >> > rather than default, built-in behavior?
>> > While this happens to be common behavior in most Ruby Web frameworks (I >> > believe Ramaze follows this as well) I'm leery of libs that make certain >> > assumptions about data.
>> Indeed, there are issues with parsing that might not reach a consent. >> (Ramaze/Innate) are actually reparsing Request#params with less than >> stellar results in performance and a few divergences from the normal >> (say PHP) behaviour. >> I think it would be good to take a look at the existing >> implementations, line them up and see which one is the fittest to make >> a suitable middleware anybody can use.
Josh Peek <j...@joshpeek.com> writes: > I'd like to propose that Rack::Requset#params support the nested hash > convention.
> In Rails, a query string "post[title]=Hello" will be parsed as > { "post" => { "title" => "Hello" } }. Rack::Request will parse it as > { "post[title]" => "Hello" }.
> AFAIK, Merb follows the same convention as well, and I'm really > curious what other frameworks are doing the same. If this the defacto > params parsing style I think Rack should support it too.
The feature seems sensible, but I would not want it to be the default behavior for #params. I'm fine with having a seperate method for it, or a method in Utils. And please specify exactly how it works! There are so many details there to take care of.
> I'm not a huge fan of adding more and more features to Rack::Request. > The setting up of hashes in the params makes sense but adds the > complication of a param value being a String, an Array, or a Hash. I'd > vote yea due to the convenience it provides. With an 'eh' on parsing > issues.
> Parameters retrievable via symbols and strings is a right out no to > me. The issue of identity vs content.
+1
Also, I wonder how often people need *nested* hashes...
I knew the issue would be controversial, and I agree it may not be best to include into Rack since it is a convention not part of any RFC.
I think we had issues trying to override the default behavior without having to do alot of work. Maybe this issue can be solved by a simple refactoring?
> I knew the issue would be controversial, and I agree it may not be > best to include into Rack since it is a convention not part of any > RFC.
> I think we had issues trying to override the default behavior without > having to do alot of work. Maybe this issue can be solved by a simple > refactoring?
What about sidestepping the issue by making Rack::Request call a callback to do params parsing with the default callback being the current implementation? Then any framework that wants its own parsing can provide its own callback for params parsing?
This keeps it simple, does not break backwardas compat and solves all of our issues with regards to how we want to do params parsing.
>> I knew the issue would be controversial, and I agree it may not be >> best to include into Rack since it is a convention not part of any >> RFC.
>> I think we had issues trying to override the default behavior without >> having to do alot of work. Maybe this issue can be solved by a simple >> refactoring?
> What about sidestepping the issue by making Rack::Request call a > callback to do params parsing with the default callback being the current > implementation? Then any framework that wants its own parsing can provide > its own callback for params parsing?
> This keeps it simple, does not break backwardas compat and solves > all of our issues with regards to how we want to do params parsing.
> Depending on how the callback is specified, it could be slower (for > instance, if a proc was specified).
The fastest callback form is using #send. Unfortunately that requires two objects to specify a callback. I've been considering wrapping up a gem for this, as I'm starting to use callbacks more and more.
Some examples of what kind of API you end up with using either can be found in:
Ezra, I think the original idea was that if nearly every framework is doing the same thing, shouldn't that be default. Callbacks would have the same problem, every framework writing the same implementation of the same thing. With that said, I completely understand the other side of the argument.
Here are my suggestions:
1.) A config parameter that let's the Rack app decide which type of parameter 'processing' it would like to use. 2.) An 'extended_params' method that returns the extra processed parameters. 3.) A piece of Rack middleware in Rack-contrib that does the pre- processing of the parameters, so it's only used if people put it in line.
#3 is my favorite. It allows people to pick and chose which implementation of parameter processing they want. If you use this middleware then the params method returns a nested Hash that Rails, Merb, and Mack users are already familiar with. If you don't use the middleware, then you get back a straight, non-nested Hash.
#2 I'm not that big a fan of because, as a framework guy, I would know to use that method, but people extending the framework wouldn't know that, so it's possible for them to use the wrong method and cause bugs. This method would most likely end up being aliased to params by the frameworks to avoid this confusion.
#1 is alright, but a bit hacky. It would work, but if you want to add a different type of processing then you would have to alter the original Rack source, and that's uncool.
What do people think about #3? I think it solves all the problems.
On Sun, Dec 28, 2008 at 2:43 PM, Mark Bates <m...@mackframework.com> wrote:
> Ezra, I think the original idea was that if nearly every framework is doing > the same thing, shouldn't that be default. Callbacks would have the same > problem, every framework writing the same implementation of the same thing. > With that said, I completely understand the other side of the argument.
> Here are my suggestions:
> 1.) A config parameter that let's the Rack app decide which type of > parameter 'processing' it would like to use. > 2.) An 'extended_params' method that returns the extra processed > parameters. > 3.) A piece of Rack middleware in Rack-contrib that does the pre-processing > of the parameters, so it's only used if people put it in line.
My previous post probably indicated this, but my vote is for #3 here with the added convenience of having this available as a mixin (and used that way in the middleware) too.
> #3 is my favorite. It allows people to pick and chose which implementation > of parameter processing they want. If you use this middleware then the > params method returns a nested Hash that Rails, Merb, and Mack users are > already familiar with. If you don't use the middleware, then you get back a > straight, non-nested Hash.
> #2 I'm not that big a fan of because, as a framework guy, I would know to > use that method, but people extending the framework wouldn't know that, so > it's possible for them to use the wrong method and cause bugs. This method > would most likely end up being aliased to params by the frameworks to avoid > this confusion.
> #1 is alright, but a bit hacky. It would work, but if you want to add a > different type of processing then you would have to alter the original Rack > source, and that's uncool.
> What do people think about #3? I think it solves all the problems.
As stated previously, my ideal resolution to this proposal would be a mesh of #2 and #3, a rack-contrib mixin for Rack::Request that would add an extended_params method rather than preprocessing. If only the preprocessing was done then there would probably be a follow up request for a method to be added to Rack::Request for faster access.
On Sun, Dec 28, 2008 at 14:43, Mark Bates <m...@mackframework.com> wrote:
> Ezra, I think the original idea was that if nearly every framework is doing > the same thing, shouldn't that be default. Callbacks would have the same > problem, every framework writing the same implementation of the same thing. > With that said, I completely understand the other side of the argument.
> Here are my suggestions:
> 1.) A config parameter that let's the Rack app decide which type of > parameter 'processing' it would like to use. > 2.) An 'extended_params' method that returns the extra processed parameters. > 3.) A piece of Rack middleware in Rack-contrib that does the pre-processing > of the parameters, so it's only used if people put it in line.
> #3 is my favorite. It allows people to pick and chose which implementation > of parameter processing they want. If you use this middleware then the > params method returns a nested Hash that Rails, Merb, and Mack users are > already familiar with. If you don't use the middleware, then you get back a > straight, non-nested Hash.
> #2 I'm not that big a fan of because, as a framework guy, I would know to > use that method, but people extending the framework wouldn't know that, so > it's possible for them to use the wrong method and cause bugs. This method > would most likely end up being aliased to params by the frameworks to avoid > this confusion.
> #1 is alright, but a bit hacky. It would work, but if you want to add a > different type of processing then you would have to alter the original Rack > source, and that's uncool.
> What do people think about #3? I think it solves all the problems.
Mark Bates <m...@mackframework.com> writes: > Here are my suggestions:
> 1.) A config parameter that let's the Rack app decide which type of > parameter 'processing' it would like to use. > 2.) An 'extended_params' method that returns the extra processed > parameters. > 3.) A piece of Rack middleware in Rack-contrib that does the pre- > processing of the parameters, so it's only used if people put it in > line.
>> 1.) A config parameter that let's the Rack app decide which type of >> parameter 'processing' it would like to use. >> 2.) An 'extended_params' method that returns the extra processed >> parameters. >> 3.) A piece of Rack middleware in Rack-contrib that does the pre- >> processing of the parameters, so it's only used if people put it in >> line.
> Does 3.) imply the parameters always are parsed?
> -- > Christian Neukirchen <chneukirc...@gmail.com> http:// > chneukirchen.org
>>> 1.) A config parameter that let's the Rack app decide which type of >>> parameter 'processing' it would like to use. >>> 2.) An 'extended_params' method that returns the extra processed >>> parameters. >>> 3.) A piece of Rack middleware in Rack-contrib that does the pre- >>> processing of the parameters, so it's only used if people put it in >>> line.
>> Does 3.) imply the parameters always are parsed?