API:JSON version 2

suffers from a number of shortcomings that make it more difficult to use than necessary. Many of these are inherited from the underlying data structure being designed for the XML format.

To address this, after discussion MediaWiki 1.25 introduces a new JSON response format. It is not the default, you only get results in the new format if you specify, and it's only for the   and   formats (and their human-readable   and   variants).

Maintaining backwards compatibility

 *  XXX from mediawiki-api-announce mailing

Without specifying, things should be backwards-compatible. But there are some caveats:


 * Modules that were previously outputting raw booleans in JSON may now have those properties being output using the standard convention: empty-string for true and absent for false. Instances of this should be reported in Phabricator to be fixed, please tag with #MediaWiki-API and the tag for the relevant extension.
 * will now reversibly mangle tag and attribute names that are not valid XML, instead of just outputting invalid XML.
 * Previously-announced breaking changes to log entry parameter formatting, that are not actually part of this general result formatting change but were made at about the same time.

API module implementers: ensuring backwards compatibility

 *  XXX

The general theme is that the ApiResult arrays now have more metadata, which the API core code uses to apply a backwards-compatible transformation for clients that don't request, and optional transformation so JSON output needn't be limited by restrictions of XML. At the same time, ApiResult and ApiFormatXml are improved be easier for developers to use.

To ensure backwards compatibility – clients that don't request  get the same results as in previous releases – developers may need to update code.


 * Several ApiResult methods have been deprecated. If your extension is maintained in Gerrit, these should have already been taken care of for you (with the exception of T95168 where work is ongoing), but new code will need to avoid the deprecated methods.
 * All ApiResult methods that operate on a passed-in array (rather than internal data) are now static, and static versions of all relevant data- and metadata-manipulation methods are provided. This should reduce the need for passing ApiResult instances around just to be able to set metadata.
 * Properties with names beginning with underscores are reserved for API metadata (following the lead of existing "_element" and "_subelements"), and will be stripped from output. Such properties may be marked as non-metadata using ApiResult::setPreserveKeysList, if necessary.
 * PHP-arrays can now be tagged with "array types" to indicate whether they should be output as arrays or hashes. This is particularly useful to fix T12887.
 * The "*" property is deprecated in favor of a properly-named property and special metadata to identify it for XML format and for back-transformation. Use ApiResult::setContentValue instead of ApiResult::setContent and all the details are handled for you.
 * ApiFormatXml will no longer throw an exception if you forget to call ApiResult::setIndexedTagName!
 * ApiFormatXml will now reversibly mangle tag and attribute names that are not valid XML, instead of irreversibly mangling spaces and outputting invalid XML for other stuff.
 * ApiResult will now validate data added (e.g. adding resources or non-finite floats will throw an exception) and auto-convert objects. The ApiSerializable interface can be used to control object conversion, if __toString or cast-to-array is inappropriate.
 * Actual booleans should now be added to ApiResult, and will be automatically converted to the old convention (empty-string for true and absent for false) when needed for backwards compatibility. Code that was violating the old convention will need to use the new ApiResult::META_BC_BOOLS metadata property to prevent this conversion.
 * Modules outputting as  to avoid large strings in XML attributes can now output as   while still maintaining   in XML format, using ApiResult::META_BC_SUBELEMENTS. New code should use ApiResult::setSubelementsList instead.
 * Modules outputting hashes as  (due to the keys being invalid for XML) can now output as   in JSON while maintaining   in XML format, using array types "kvp" or "BCkvp".

Most of the changes to extensions that this change necessitated are in gerrit change set I7b372....

Changes to XML format
does not have a new results format. There are some changes to XML results:


 * From API/Architecture_work/Planning

Changes here will mostly be on the back-end; the actual data output to clients is intended to remain the same wherever possible. However, clients should be prepared for the following:
 * Result structure may no longer match the JSON format.
 * Tag and attribute names may be encoded when not conforming to XML requirements.
 * Result structure may change depending on the specific query. For example, passing both rvprop=content and rvdiffto=prev to prop=revisions would previously omit the diff from the result (bug 55371) (it should be throwing an error, but that's another bug). Now this will return the content as the value of the node when  is not supplied and as the value of a subnode of the node when it is.

For example, bug 43221 was fixed by changing the names of attributes such as "4::foo" to fit XML's restrictions. In the future, this would be fixed by either encoding the name (e.g. "_4.3A..3A.foo") or by changing the structure of output in only the XML format (e.g. ).

On the MediaWiki code side, developers will see the following changes:
 * The XML formatter will no longer die if ApiResult::setIndexedTagName is forgotten. Instead, it will act as if that were called with something generic (e.g. ApiResult::setIndexedTagName( $array, '_v' )).
 * The XML formatter will no longer (be supposed to) raise an error when a node has both node content (ApiResult::setContent) and non-scalar attributes. Instead, it will simply shove the intended node content into a subnode.
 * Anything that's hard-coding '*' should be updated to use ApiResult::setContentValue.
 * Additional metadata is available to hint at improved XML output.

The future of "version 1" JSON response format
In some future release the old format=json will be deprecated, and may eventually be removed.

Using the new JSON results format
You can use  in your requests in MediaWiki 1.25, but do note that the output formatting isn't entirely stable yet and might change in MediaWiki 1.26.

Changes to JSON output format

 *  XXX from mediawiki-api-announce mailing

With, we can make some useful changes:
 * Return booleans as boolean true instead of empty-string. Where appropriate, return boolean false instead of omitting the property.
 * Return empty objects in JSON as {}, rather than [].
 * Have action=query's "pages" be an array, instead of an object with page ids as keys that can be difficult to iterate.
 * Provide useful property names instead of '*'.
 * Eliminate useless indirection, e.g.  instead of   and   instead of.
 * The existing  option is the default. A new   request parameter has been introduced for clients who need all non-ASCII codepoints escaped.

If you see missed opportunities to make the above changes in existing output, or if there are other changes that would make API output easier to use in JSON, please let MediaWiki API developers know! Phabricator would be ideal (tag with #MediaWiki-API, and the appropriate extension's tag if applicable), or reply on the mediawiki-api mailing list.