API:JSON Version 2
MediaWiki Version: | ≥ 1.25 |
format=json
leidet an einer Reihe von Mängeln, die die Verwendung stärker erschweren als nötig. Viele davon treten auf, da XML das ursprüngliche Ausgabeformat war und die zugrunde liegende Datenstruktur der API-Antworten darum herum entwickelt wurde.
Um dies zu verbessern, wurde nach einer Diskussion in MediaWiki 1.25 ein neues JSON-Antwortformat eingeführt.
Es ist kein Standard, du erhältst die Ergebnisse nur in dem neuen Format, wenn du formatversion=2
spezifizierst und es ist nur für die Formate json
und php
(und die menschenlesbaren Varianten jsonfm
und phpfm
) verfügbar.
Aufrechterhaltung der Rückwärtskompatibilität
- API result formatting changes for JSON (formatversion=2) aus der mediawiki-api-announce-Mailingliste
Wenn formatversion=2
nicht spezifiziert wird, sollten die Ergebnisse in der API-Antwort, die Clients erhalten, immer rückwärtskompatibel sein.
Es gibt jedoch zwei Vorbehalte:
- Module, die zuvor unformatierte boolesche Werte in JSON ausgegeben haben, können diese Eigenschaften nun mit der Konvention ausgeben, die (für Version 1) der Standard war: Leere Zeichenkette für true und fehlender Schlüssel für false. Clientcode, der diese booleschen Werte verarbeitet, wird wahrscheinlich abbrechen oder eine Warnung ausgeben, wenn nicht auf einen fehlenden Schlüssel geprüft wird. Diese Fälle sollten im Phabricator gemeldet werden, sodass das API-Modul repariert werden kann, bitte markiere sie mit #MediaWiki-API und der Markierung für die entsprechende Erweiterung.
format=xml
wird nun Namen von Markierungen und Attributen, die kein gültiges XML sind, verarbeiten, statt einfach ungültiges XML auszugeben.- Zuvor angekündigte grundlegende Änderungen, um die Formatierung von Eingabeparametern zu speichern, die kein Teil der allgemeinen Änderung der Ergebnisformatierung sind, aber zur gleichen Zeit angekündigt wurden.
API-Modul-Implementierer: Sicherstellung der Rückwärtskompatibilität
- XXX
Das allgemeine Thema ist, dass die ApiResult-Arrays nun mehr Metadaten enthalten, die der Code des API-Kerns nutzt, um eine rückwärtskompatible Umwandlung für Clients anzuwenden, die formatversion=2
nicht abfragen und optional umzuwandeln, sodass JSON-Ausgaben nicht den Beschränkungen von XML unterliegen. Gleichzeitig sind ApiResult
und ApiFormatXml
für Entwickler einfacher zu nutzen.
Um Rückwärtskompatibilität sicherzustellen – d.h. dass Clients, die formatversion=2
abfragen, nicht die gleichen Ergebnisse wie in vorherigen Versionen erhalten – müssen Entwickler von API-Modulen möglicherweise den Code aktualisieren.
- Unterschiedliche ApiResult-Methoden sind veraltet. Wenn deine Erweiterung in Gerrit entwickelt wird, sollte dies bereits für dich erledigt sein (mit Ausnahme von T95168, woran gearbeitet wird), jedoch muss bei neuem Code vermieden werden, veraltete Methoden zu nutzen.
- Du solltest die veralteten Methoden
getIsRawMode()
undsetRawMode()
nicht nutzen. Raw-Modus, genutzt, um anzugeben, dass ein Ergebnisdrucker Metadaten-Schlüssel wie_element
verwendet; nun müssen alle Drucker Daten aus dem "Raw-Modus" verarbeiten.
- Du solltest die veralteten Methoden
- Alle ApiResult-Methoden, die mit einem übergebenen Array (statt internen Daten) arbeiten, sind nun statisch und statische Versionen aller relevanten Methoden zur Manipulation von Daten und Metadaten sind verfügbar. Dies sollte die Notwendigkeit zur Übergabe von ApiResult-Instanzen reduzieren, um Metadaten setzen zu können.
- Eigenschaften, die mit einem Unterstrich beginnen, sind für API-Metadaten reserviert (angelehnt an die existierenden
_element
und_subelements
) und werden aus der Ausgabe entfernt. Du kannst mit ApiResult::setPreserveKeysList() angeben, dass eine Eigenschaft, die mit einem Unterstrich beginnt, keine Metadaten ist. - Du kannst PHP-Arrays mit "Array-Typen" markieren, um anzugeben, ob sie als Arrays oder Hashes ausgegeben werden sollen. Dies ist besonders hilfreich, um T12887 zu beheben.
- Die Eigenschaft
"*"
ist veraltet, stattdessen wird eine korrekt benannte Eigenschaft und spezielle Metadaten bevorzugt, um es für das XML-Format und die Rück-Umwandlung zu identifizieren. Nutze ApiResult::setContentValue() statt ApiResult::setContent() und alle Details werden für dich erledigt. - ApiFormatXml wird keine Ausnahme mehr ausgeben, wenn du vergisst, ApiResult::setIndexedTagName() anzurufen!
- ApiFormatXml wird nun Namen von Markierungen und Attributen, die kein gültiges XML sind, verarbeiten, statt Leerzeichen unumkehrbar zu verarbeiten und ungültiges XML für andere Dinge auszugeben.
- ApiResult wird nur hinzugefügte Daten validieren (z.B. wird eine Ausnahme ausgegeben, wenn Ressourcen oder unendliche Zahlen hinzugefügt werden) und Objekte automatisch konvertieren. Die ApiSerializable-Oberfläche kann genutzt werden, um die Objekt-Konvertierung zu kontrollieren, wenn __toString() oder cast-to-array unangemessen sind.
- Du kannst nun boolesche Werte zu ApiResult hinzufügen und die API wird sie in Antworten an "Version-1"-Clients in die alte Konvention für boolesche Ergebnisparameter (leere Zeichenkette für true und keine für false) umwandeln, um Rückwärtskompatibilität sicherzustellen. Wenn du jedoch gegen diese Konventionen verstößt, indem du einen booleschen
"someKey": true
oderfalse
zurückgibst, werden die Clients möglicherweise abbrechen! Wenn dein API-Modul dies tut, musst du die neue Metadaten-Eigenschaft ApiResult::META_BC_BOOLS nutzen, um die Konvertierung für "Version-1"-Clients zu verhindern. Du solltest den Code deines API-Moduls darauf prüfen, ob boolesche Werte in ApiResult gesetzt werden; auch darauf, ob externe Datenstrukturen wie JSON in ApiResult eingefügt werden, da du möglicherweisetrue
- oderfalse
-Werte zurückgibst, ohne es zu merken. - Modulausgaben wie
{"key":{"*":"value"}}
, um lange Zeichenketten in XML-Attributen zu vermeiden, können nun{"key":"value"}
ausgeben, während<container><key>value</key></container>
im XML-Format bei Nutzung von ApiResult::META_BC_SUBELEMENTS weiterhin unterstützt wird. Neuer Code sollte stattdessenApiResult::setSubelementsList()
nutzen. - Module, die Hashes wie
[{"name":"key1","*":"value1"},{"name":"key2","*":"value2"}]
ausgeben (da die Schlüssel für XML ungültig wären) können nun als{"key1":"value1","key2":"value2"}
in JSON ausgeben werden, während<container><item name="key1">value1</item><item name="key2">value2</item></container>
im XML-Format bei Nutzung von ApiResult:setArrayType() mit dem Array META_TYPE,'kvp'
oder'BCkvp'
weiterhin unterstützt wird.
Die meisten Änderungen an Erweiterungen, die für diese Änderungen erforderlich waren, befinden sich im Gerrit-Änderungssatz I7b372... und topic:api-cleanup-PS25.
Änderungen am XML-Format
format=xml
hat kein neues Ergebnisformat. Es gibt einige Änderungen an XML-Ergebnissen:
Änderungen gibt es hauptsächlich am Backend; die Datenausgabe Clients soll soweit möglich gleich bleiben. Clients sollten sich jedoch auf folgendes vorbereiten:
- Die Ergebnisstruktur stimmt möglicherweise nicht mit dem JSON-Format überein.
- Namen von Markierungen und Attributen können codiert werden, wenn sie XML-Anforderungen nicht erfüllen.
- Abhängig von der jeweiligen Abfrage kann sich die Ergebnisstruktur ändern. Wenn beispielsweise rvprop=content und rvdiffto=prev an prop=revisions übergeben werden, wäre zuvor der Diff des Ergebnisses weggelassen worden (bug 55371) (es sollte ein Fehler ausgegeben werden, dies ist jedoch ein anderer Fehler). Nun wird der Inhalt als Wert des Knotens <rev> ausgegeben, wenn
rvdiffto
nicht übergeben wird und als Wert eines Unterknotens <content> des Knotens <rev>, wenn er übergeben wird.
Beispielsweise wurde Bug 43221 behoben, indem die Namen von Attributen wie "4::foo" geändert wurden, um die XML-Einschränkungen zu erfüllen. In Zukunft soll dies behoben werden, indem entweder der Name codiert wird (z.B. "_4.3A..3A.foo") oder die Struktur der Ausgabe in reines XML-Format geändert wird (z.B. <attribute name="4::foo">
).
Auf Seiten des MediaWiki-Codes werden Entwickler folgende Änderungen sehen:
- Der XML-Formatierer wird nicht länger abbrechen, wenn ApiResult::setIndexedTagName() vergessen wird. Stattdessen wird so verfahren, wie wenn es mit etwas generischem angerufen worden wäre (z.B. ApiResult::setIndexedTagName( $array, '_v' )).
- Der XML-Formatierer wird nicht länger einen Fehler ausgeben, wenn ein Knoten sowohl Knoten-Inhalt (ApiResult::setContent()) als auch nicht-skalare Attribute enthält. Stattdessen wird der beabsichtige Knoteninhalt einfach in einen Unterknoten verschoben.
- Alles, was mit '*' hart codiert ist, sollte aktualisiert werden, um ApiResult::setContentValue() zu nutzen.
- Zusätzliche Metadaten sind verfügbar, um auf eine verbesserte XML-Ausgabe hinzuweisen.
Die Zukunft des "Version-1"-JSON-Ausgabeformats
In einer zukünftigen Veröffentlichung wird das alte format=json veraltet sein und eventuell entfernt werden.
Nutzung des neuen JSON-Ausgabeformats
Du kannst formatversion=2
in deinen Abfragen in MediaWiki 1.25 nutzen, beachte jedoch, dass das Ausgabeformat noch nicht ganz stabil ist und sich in MediaWiki 1.26 ändern kann.
[needs update]
Änderungen am JSON-Ausgabeformat
- API result formatting changes for JSON (formatversion=2) aus der mediawiki-api-announce-Mailingliste
Mit formatversion=2
können wir einige nützliche Änderungen vornehmen:
- Boolesche Werte als boolesches true statt als leere Zeichenkette zurückgeben. Wo dies angemessen ist,[note 1] boolesches false zurückgeben, statt den Parameter wegzulassen.
- Leere Objekte in JSON als {} statt als [] zurückgeben.
- action=querys "Seiten" ein Array sein lassen, statt eines Objektes mit Seiten-IDs als Schlüsseln, die schwierig zu iterieren sein können.
- Nützliche Eigenschaftennamen anbieten, anstatt '*'.
- Nutzlose Umwege entfernen, z.B.
{"text":"..."}
statt{"text":{"*":"..."}}
und{"key1":"value1","key2":"value2"}
statt[{"name":"key1","*":"value1"},{"name":"key2","*":"value2"}]
. - Die existierende Option
utf8
ist der Standard. Ein neuer Abfrageparameterascii
wurde für Clients eingeführt, bei denen alle Nicht-ASCII-Codepunkte mit Escape-Zeichen versehen werden müssen.
Wenn dir fehlende Möglichkeiten auffallen, um die oben genannten Änderungen in der existierenden formatversion=2
-Ausgabe vorzunehmen oder wenn es andere Änderungen gibt, die es erleichtern würden, die API-Ausgabe in JSON zu nutzen, lass es bitte die MediaWiki-API-Entwickler wissen! Phabricator wäre ideal (markiert mit #MediaWiki-Action-API und, sofern möglich, dem entsprechenden Tag der Erweiterung) oder antworte in der mediawiki-api-Mailingliste.
- ↑ Wenn die Eigenschaft normalerweise false ist, würde man es dadurch manchmal nur aufblähen.