API:JSON version 2/zh

中有多个缺点，让它比需求中更难以使用. 其中很多问题的出现，是因为API响应的基本数据结构使用XML作为原始输出格式，并以此为基础设计而成.

为解决这类问题，经过讨论，MediaWiki 1.25新增了一种新的JSON响应格式. 此项不是默认项. 你需要设置成 才能获取到这种新格式的结果，并且此项仅在 和 格式（以及方便人类阅读的 和 变体）下才生效.



向后-{zh-cn:兼容;zh-tw:相容;}-维护

 *  XXX from mediawiki-api-announce mailing 

在没有指定 时，客户端收到的API响应结果应当都可以做到向后兼容. 但请注意：


 * Modules that were previously outputting raw booleans in JSON may now output those properties using the convention that has always been the standard (for version 1): empty-string for true and absent key for false. Client code that acts on these booleans will likely break or warn if it doesn't test for an absent key. Instances of this should be reported in Phabricator so the API module can 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,  and   are easier for developers to use.

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


 * Several ApiResult methods have been deprecated. If your extension is maintained in, these should have already been taken care of for you (except for T95168 where work is ongoing), but new code will need to avoid the deprecated methods.
 * You should not use the deprecated methods  and  . Raw mode used to indicate that a result printer wanted metadata keys such as  ; now all printers need to handle "raw mode" data.
 * 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 available. This should reduce the need for passing ApiResult instances around just to be able to set metadata.
 * Properties that begin with an underscore are reserved for API metadata (following the lead of existing  and  ), and are stripped from output. You can indicate that a property beginning with an underscore is not metadata using ApiResult::setPreserveKeysList.
 * You can tag PHP arrays 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.
 * 如果没有调用ApiResult::setIndexedTagName，ApiFormatXml就不会再抛出异常！
 * 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.
 * You can now add actual booleans to ApiResult, and the API will automatically convert them in responses to "version 1" clients to the old convention for boolean result parameters (empty-string for true and absent for false) for backwards compatibility. However, this means that if you were violating this convention by returning a boolean  or , then existing clients will probably break! If your API module does this then you need to use the new ApiResult::META_BC_BOOLS metadata property to prevent this conversion for "version 1" clients. You should check your API module code for setting boolean values in ApiResult; also if you insert external data structures such as JSON into ApiResult, you may be returning   or   values without realizing it.
 * 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  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 ApiResult:setArrayType with array META_TYPE   or.

Most of the changes to extensions that this change necessitated are in gerrit change set I7b372... and topic:api-cleanup-PS25.



XML格式的改动
没有新的结果格式. XML格式会有下列改动：


 * 来自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:
 * 结果结构可能不再和JSON格式一致.
 * 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 &lt;rev> node when  is not supplied and as the value of a &lt;content> subnode of the &lt;rev> 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.



今后的“第1版本”JSON响应格式
在今后的一些版本更新中，旧的format=json可能标为不赞成使用，并可能最终被移除.



如何使用新的JSON结果格式
你可以在中请求时使用 ，但注意这种输出格式还不完全稳定，在MediaWiki 1.26中还可能被修改.



JSON输出格式的改动

 *  XXX from mediawiki-api-announce mailing 

在 中，我们做出了下列更改：


 * 布尔值输出为true，而不是空字符串. 在需要时 ，返回布尔值false而不是省略该属性.
 * 返回的空JSON对象改成了{}，而不是[].
 * action=query中的“pages”改为数组，而不是之前那种很难循环迭代的用页面编号作关键字的对象.
 * 提供有用的属性名称，而不是'*'.
 * 清理无用的迂回嵌套，例如 改成了 ， 改成了.
 * 默认使用 选项. 加入新的请求参数 ，方便需要避免所有非ASCII编码的客户端.

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-Action-API, and the appropriate extension's tag if applicable), or reply on the mediawiki-api mailing list.