Deprecate/Remove ActionController::ParamsWrapper

I have a small inconvenience with existing legacy app, that works as an API. It has enabled (by default) params wrapper for JSON format.

It creates some noise in logs when a root key of params is different than the name of a controller, as it duplicates it.

It cannot be easily removed now, since I’m not sure if anybody integrated with this “feature” and omits root key param (that is automatically added when missing).

I’m not sure what are the real use cases and benefits of using it.

Maybe we could deprecate it, or at least don’t generate enabled wrapper for JSON format in new apps?

Is there anyone who uses this feature and could share his usecase?

I use it. It allows you to submit { name: “something” } via a JSON API and have that translated into what the view provides as { todo: { name: “something” } }. Very useful when you don’t want your JSON API to submit needless root elements.

Are you using the same controller for HTML and JSON responses? Since we have strong params, model attributes can be nicely grouped with or without root key.

I didn’t try it, but HTML attributes could be passed flat as well to be consistent with JSON format.

In that case, you wouldn’t need such tricks with params wrapping.

Yes, same controllers. That’s the case this was invented for.

Wojciech seems to be asking why the params structure in the actual HTTP request is different between JSON and HTML, and I think I can answer that.

Basically, the difference is that with an HTML request, the URL params and the “form” params are merged. Hence the need to keep the two separate via a root key. But with JSON, presumably only the real params are submitted as JSON, so they’re already separate, and there’s then no need for the submitting JS to know anything about the root key.

Is that a correct summary?

Unless I’m misreading it the JSON API (http://jsonapi.org/format/), currently being worked on by Katz and others, specifies that submitted resources should look like this:

POST /photos Content-Type: application/vnd.api+json Accept: application/vnd.api+json { “data”: { “type”: “photos”, “title”: “Ember Hamster”, “src”: "http://example.com/images/productivity.png " } }

Since this is an industry-wide effort to move towards a common structure for all client-server communication across an endpoint, I think Rails should follow suit and move in this direction.

I disagree that “there’s no need for the submitting JS to know anything about the root key” — there are lots of use cases for the submitting JS to include additional things (like a token) or some other kind of non-resource oriented meta data. Root keys help keep things clean, I would say not using them is a code smell/borderline antipattern.

-Jason

I disagree that “there’s no need for the submitting JS to know anything about the root key”

I should clarify that I wasn’t expressing an opinion either way, but rather summarizing what it seemed DHH was saying.

To me it sounds like there are three points of view here:

WW: Developers should never wrap params, dirty root is fine, prefer to deprecate the wrap_parameters feature (rebutted by DHH below)

DHH: Wrap parameters is useful to normalize between the common JSON style of not using a root and the common CGI style of using a root.

JFB: People should always write their JSON to use a root per an emerging standard. (Possibly with the corollary that if everybody does it this way, you don’t need to wrap parameters anymore and could then either change the default of wrap_parameters or deprecate it?)

In my experience, the current behavior of wrap parameters works well for the reason DHH mentioned, in addition to automatically normalizing rootless JSON with XML posts, if you need to support XML (rootless XML documents not being a thing).

Anti- or not, a lot of client side libraries prefer the no-root-in-the-JSON pattern at the moment, so I feel like it’d be pretty early to move in that direction by changing the default of wrap_parameters to false, if that was the implication of Jason’s post. I would love for there to be a consensus on root nodes in JSON, but at this point the deploy base of non-rooted JSON is probably vastly larger than rooted JSON (I have no statistics on this, just a sense from third party JSON APIs I’ve been consuming lately). The fact that it is configurable but leans toward supporting non-rooted JSON seems like the right answer to me, for now.

-john

A closer reading of the linked json:api page indicates that what they’re talking about isn’t the same as what I was calling a “rooted JSON” object, as evidenced by the fact that there are both “data” and “error” keys at the root level (neither corresponding to the resource name being sent). It seems to me that json:api endpoints are a higher-level contract than rails controllers would be expected to provide out of the box.

-john