API:Intern anrufen

From mediawiki.org
This page is a translated version of the page API:Calling internally and the translation is 100% complete.

Die API kann intern aus PHP ohne eine HTTP-Abfrage angerufen werden.

Die Anwendungslogik sollte dies jedoch vermeiden und direkt auf die PHP-Klassen zugreifen, die fĂŒr die entsprechende Funktion verantwortlich sind, statt ĂŒber das API-Framework zu gehen.

Interne API-Anrufe sollten grundsĂ€tzlich nur fĂŒr Testzwecke und schnelles Prototyping genutzt werden.

Aus dem Code einer Testsuite

Um die API aus Tests anzurufen, ist es am einfachsten, deine Test-Klasse aus ApiTestCase (statt MediaWikiTestCase) weiter zu nutzen. Du kannst dann ApiTestCase::doApiRequest() wie folgt nutzen.

$result = $this->doApiRequest( [
	'action'     => 'edit',
	'title'      => 'Test_page',
	'appendtext' => 'Testing editing.',
	'token'      => $user->getEditToken(),
] );

Tests der API sollten wie hier gezeigt erfolgen, manchmal möchtest du jedoch die Nutzung der API testen, um etwas fĂŒr andere Tests aufzusetzen, die keine API-Tests sind. In diesem Fall möchtest du möglicherweise nicht ApiTestCase nutzen.

In diesem Fall muss die Abfrage genauer konstruiert werden, da das Bearbeitungstoken fĂŒr die Sitzung gespeichert werden muss. Die globale $wgRequest ist dann eine FauxRequest, die bereits durch die Test-Umgebung konfiguriert wurde.

global $wgRequest;
$user = parent::getTestSysop()->getUser();
$this->assertTrue($user->isRegistered());
$apiParams = [
	'action'     => 'edit',
	'title'      => 'Test_page',
	'appendtext' => 'Testing editing.',
	'token'      => $user->getEditToken(),
];
$apiRequest = new FauxRequest( $apiParams, true, $wgRequest->getSessionArray() );
$context = new DerivativeContext( new RequestContext() );
$context->setRequest( $apiRequest );
$context->setUser( $user );
$api = new ApiMain( $context, true );
$result = $api->execute();


Aus dem Anwendungscode

Das interne Anrufen der API ist hĂ€ufig ein Zeichen dafĂŒr, dass bestimmte Funktionen in eine Backend-Klasse aufgenommen werden sollten, die sowohl aus deinem Code und dem API-Modul genutzt werden kann. In neuem Produktionscode wird hiervon abgeraten und es wird als technisches Problem betrachtet. Siehe Architecture guidelines#Separation of concerns — UI and business logic. Trotzdem gibt es manche FĂ€lle, in denen diese Technik akzeptabel ist: Einheiten- und Funktionstests.
Wenn dein Code vordefinierte Bearbeitungen vornimmt und Benutzereingaben nicht bereinigt werden und den Missbrauchsfilter passieren mĂŒssen, etc., ziehe in ErwĂ€gung statt einer API-Abfrage WikiPage ::doUserEditContent() zu nutzen.

Manchmal möchte anderer PHP-Code Datenzugriff und Aggregationsfunktionen der Action-API nutzen. Statt eine HTTP-Netzwerk-Abfrage an den gleichen Server zu stellen, kannst du einen Anruf in PHP machen.

Die Schritte sind:

1) Wenn du dies in Zusammenhang mit einer existierenden Abfrage eines Benutzers ausfĂŒhrst, bereite die Abfrage-Parameter mit der DerivativeRequest-Klasse vor.

  • Der erste Parameter des Konstruktors ist die Abfrage, von der abgeleitet werden soll.
  • Der zweite Parameter des Konstruktors ist ein Array von API-Parametern, der identisch mit denen ist, die beim Stellen der Abfrage ĂŒber das Netz genutzt werden wĂŒrden.
  • Der dritte Parameter des Konstruktors ist optional, spezifiziere true, um den API-Anruf als POST zu behandeln, wenn das API-Modul, das du aufrufst, POST-Abfragen verlangt.

Dieser Beispielcode behandelt die 'allpages'-Listenabfrage ab dem Buchstaben 'M'. Dies ist eine Beispielabfrage, die keinen Benutzer oder POST erfordert.

$params = new DerivativeRequest(
	$this->getRequest(), // Fallback upon $wgRequest if you can't access context.
	array(
		'action' => 'query',
		'list' => 'allpages',
		'apnamespace' => 0,
		'aplimit' => 10, 
		'apprefix' => 'M'
	)
);

Wenn du ein Bearbeitungstoken als API-Parameter angeben musst, um Bearbeitungen oder andere Änderungen auszufĂŒhren, kannst du das Bearbeitungstoken wie folgt erhalten:

$user = $this->getUser(); // Or User::newFromName, etc.
$token = $user->getEditToken();

2) Erstelle eine ApiMain-Instanz. FĂŒhre dann die API-Abfrage aus. Da der Parameter ein DerivativeRequest-Objekt ist, wird ApiMain keine Formatierungen ausgeben oder Fehler behandeln. Ein Parameterfehler oder jeder andere interne Fehler wird eine Ausnahme verursachen, die im anrufenden Code gefunden werden kann.

$api = new ApiMain( $params );
$api->execute();

Wichtig: Wenn du Seiten erstellen oder bearbeiten möchtest, musst du true als zweiten Parameter bei der Erstellung von ApiMain object ĂŒbergeben:

$api = new ApiMain( $params, true ); // default is false
$api->execute();

3) Erhalte das daraus resultierende Daten-Array.

$data = $api->getResult()->getResultData();

Hier ist ein vollstĂ€ndiges Beispiel aus Erweiterung:WikiLove (Stand r112758). Es fĂŒgt Text zu einer Seite hinzu, weshalb es in einer HTTP-Abfrage eines angemeldeten Benutzers ausgefĂŒhrt werden muss.

	$api = new ApiMain(
		new DerivativeRequest(
			$this->getRequest(), // Fallback upon $wgRequest if you can't access context
			array(
				'action'     => 'edit',
				'title'      => $talk->getFullText(),
				'appendtext' => ( $talk->exists() 
				                  ? "\n\n" 
				                  : '' ) .
					wfMsgForContent( 'newsectionheaderdefaultlevel', 
						$params['subject'] )
						"\n\n" . $params['text'],
				'token'      => $params['token'],
				'summary'    => wfMsgForContent( 'wikilove-summary',
					$wgParser->stripSectionName( $params['subject'] ) ),
				'notminor'   => true
			),
			true // treat this as a POST
		),
		true // Enable write.
	);

	$api->execute();

FauxRequest

Das Beispiel oben erstellt ein DerivativeRequest RequestContext . Dieser "ĂŒbernimmt" einiges aus der ursprĂŒnglichen Abfrage, wie IP und Abfrage-Header, die gesetzt werden, wenn MediaWiki eine Aktion im Namen eines Benutzers ausfĂŒhrt, typischerweise bei der Behandlung einer Web-Anfrage. Wenn es keinen Kontext zur Abfrage eines Benutzers gibt, beispielsweise beim Aufrufen der Action-API aus einem Systemprozess, oder du eine komplett getrennte interne Abfrage ausfĂŒhren möchtest, kannst du stattdessen FauxRequest nutzen.

FauxRequest fĂŒr Schreibbefehle zu nutzen, ohne den Abfrage-Kontext zu ĂŒbergeben, erzeugt Fehler T36838.

Umgang mit Fehlern

Wenn ungĂŒltige Parameter ĂŒbergeben werden, kann die Action-API ein UsageException ausgeben. Wenn es deinem Code möglich ist, einen ungĂŒltigen Parameter zu senden, solltest du die API vielleicht aus einem Try/Catch-Block anrufen


Siehe auch