Page MenuHomePhabricator

Allow clients to POST JSONs in the body
Open, LowPublic

Description

Prior discussion on https://gerrit.wikimedia.org/r/c/mediawiki/core/+/388486 and T210107 suggests that we do this by adding a getJson() method to WebRequest, which would validate the Content-Type and decode the data with appropriate error handling (via Exceptions or StatusValue objects).

The alternative, trying to munge the JSON data into a format that could be returned by existing WebRequest methods like getVal(), seems fraught with edge cases and potential for existing callers to receive unexpected data types that could result in incorrect behavior and potential security issues.

Event Timeline

Change 388486 had a related patch set uploaded (by Dbarratt; owner: Mobrovac):
[mediawiki/core@master] WebRequest: Allow clients to POST JSONs in the body

https://gerrit.wikimedia.org/r/388486

Change 482419 had a related patch set uploaded (by Xqt; owner: Xqt):
[pywikibot/core@master] Revert "[bugfix] import MWSite in generate_family_file.py for tests"

https://gerrit.wikimedia.org/r/482419

Change 482419 merged by jenkins-bot:
[pywikibot/core@master] Revert "[bugfix] import MWSite in generate_family_file.py for tests"

https://gerrit.wikimedia.org/r/482419

The API's preferred way of sending parameters is via POST. Additionally, some Special pages expect the payload to be POSTed as well. Therefore, accept requests that have their data embedded as a JSON in the body.

https://gerrit.wikimedia.org/r/c/mediawiki/core/+/388486

That particular quote received some pushback in subsequent comments.

@Anomie wrote:

This is a non sequitur.

Why does the fact that various things accept POSTs using standard application/x-form-www-urlencoded or multipart/form-data mean that MediaWiki should recognize a non-standard application/json POST body?

@mobrovac wrote:

The sequitur here wants to imply that since various things accept POST parameters, let MW take them in the application/json form too.

@Anomie wrote:

Still doesn't follow. The same "argument" could be made for accepting XML, yaml, ASN.1, or Morse code.


A different approach than is taken in https://gerrit.wikimedia.org/r/c/mediawiki/core/+/388486/4 was later suggested:

@Tgr wrote:

Handling them the same way as normal POST data, I am not so sure. For one thing, do you really want to subject JSON bodies to all the hacks that are required for PHP superglobals (see e.g. the comment in getGPCVal())? For another, normal POST can only contain strings (or deep arrays of strings); JSON can contain null values. I'm not sure all application code expects that.

If the goal is to create new endpoints that take JSON data, I'd just add a new getJSON() method to WebRequest (that's also how other request frameworks tend to deal with it AFAIK; it would also get rid of the arbitrary limitation of the JSON having to be an array or object). If the goal is to enable JSON POSTs to existing endpoints, what is the use case for that? Is it more convenient for the clients, more efficient, etc?

[skip a bunch of discussion about potential uses not relevant here]

@Anomie later wrote:

And if it were going to be standardized, Gergő's suggestion of a getJson() method strikes me as the better way to do it, for the reasons he stated.

There was other discussion along those same lines in T210107: The Action API should allow input in JSON.

@Anomie thanks for capturing all of that, please feel free to update the title/description to something more appropriate. :)

Change 388486 abandoned by Mobrovac:
WebRequest: Allow clients to POST JSONs in the body

https://gerrit.wikimedia.org/r/388486

eprodromou subscribed.

So, this seems like a feature that sounds interesting. We do most of the input via JSON for the REST API.

It's also probably not a big priority for us in CPT. I'm putting it in the icebox, unless we get more motivation to work on it.