Jump to content
MediaWiki

Stratégie d'implémentation

From mediawiki.org
This page is a translated version of the page API:Implementation Strategy and the translation is 100% complete.
Cette page fait partie de la documentation de l'API MediaWiki Action.
API MediaWiki Action
Fonctions de base
Authentification
Comptes et utilisateurs
Opérations sur les pages
Chercher
Outils pour les développeurs
Tutoriels
v · d · e

Ceci explique l'implémentation de la mécanique de l'API MediaWiki dans le noyau. Si vous voulez fournir une API dans votre code pour des clients consommateurs, voir API:Extensions .

Structure des fichiers et modules

  • api.php est le point d'entrée situé à la racine du wiki. Voir Point d'accès de l'API.
  • ApiEntryPoint est l'implémentation du point d'accès (factuée en Gerrit change 959047).
  • includes/api contiendra tous les fichiers liés à l'API, mais aucun d'eux ne pourra être un point d'entrée.
  • Toutes les classes de l'API sont dérivées de la classe abstraite commune ApiBase. La classe de base fournit des fonctionnalités communes telles que l'analyse des paramètres, le profilage et la gestion des erreurs.
  • ApiMain est la classe principale instanciée par ApiEntryPoint. Elle détermine quel est le module à exécuter en fonction du paramètre action=XXX. ApiMain crée également une instance de la classe ApiResult qui contient l'ensemble de données de sortie et les fonctions d'aide associées. Enfin, ApiMain instancie la classe de formatage qui génèrera les données de sortie pour le client à partir de ApiResult dans les formats XML ou JSON ou PHP ou autre.
  • Tout module dérivé de ApiBase recevra une référence à une instance de ApiMain pendant l'instanciation, de sorte qu'à l'exécution le module puisse accéder aux ressources partagées comme par exemple l'objet résultat.

Modules de requête

  • ApiQuery se comporte comme ApiMain dans le sens où il exécute les sous-modules. Chaque sous-module est dérivé de ApiQueryBase (sauf le ApiQuery lui-même, qui est un module de premier niveau). Pendant l'instanciation, les sous-modules reçoivent la référence de l'instance ApiQuery.
  • Tous les modules de requête d'extension doivent utiliser des préfixes à 3 lettres ou plus. Les modules du noyau utilisent des préfixes à 2 lettres.
  • Plan d'exécution de ApiQuery :
    1. Obtenir les paramètres de requête partagés list/prop/meta pour déterminer les sous-modules nécessaires.
    2. Créer un objet ApiPageSet et l'initialiser à partir des paramètres titles/pageids/revids. L'objet pageset contient la liste des pages ou des révisions avec lesquelles les modules de requête vont travailler.
    3. S'il est demandé, un module générateur est exécuté pour créer un autre ApiPageSet. Similaire aux flux redirigés (pipes) dans UNIX. Les pages données sont l'entrée du générateur qui produit un autre ensemble de pages à utiliser par tous les autres modules.
  • Conditions pour continuer la requête :
    • La requête SQL doit être entièrement ordonnée. En d'autres termes, la requête doit utiliser toutes les colonnes d'une clé unique soit comme des constantes dans la clause WHERE ou dans les clauses ORDER BY.
      • Dans MySQL, il s'agit d'un OU exclusif, au point où la requête de Foo et Bar doit trier en fonction du titre et non de l'espace de noms (celui-ci vaut toujours 0), Foo et Talk:Foo doivent trier par espace de noms mais pas par titre (le titre est constant et vaut Foo), et Foo et Talk:Bar doivent trier à la fois par espace de noms et par titre.
    • La requête SQL ne doit pas trier par fichier.
    • La valeur donnée à setContinueEnumParameter() doit inclure toutes les colonnes de la clause ORDER BY.
    • Lors d'une continuation, une condition composée unique doit être ajoutée à la clause WHERE. Si la requête contient ORDER BY column_0, column_1, column_2, cette condition doit ressembler à :
(column_0 > value_0 OR (column_0 = value_0 AND
 (column_1 > value_1 OR (column_1 = value_1 AND
 (column_2 >= value_2)
 ))
))

Bien sûr, échangez ">" et "<" si vos colonnes ORDER BY utilisent DESC. Veillez à éviter l'injection de SQL dans les valeurs.

Structures des données internes

  • L'API de requête a eu une structure très réussie d'une structure globale array() imbriquée qui a été transportée. Différents modules viendront ajouter des données en de nombreux points différents de ce tableau, jusqu'à ce qu'il soit rendu pour le client par l'une des imprimantes (modules de sortie). Pour l'API, nous suggérons de mettre ce tableau dans une classe avec des fonctions d'aide pour ajouter des feuilles aux nœuds individuels.

Rapporter les erreurs et les états

Pour l'instant, nous avons décidé d'inclure les informations d'erreur dans la même sortie structurée que les résultats standard (option numéro 2).

Pour le résultat, nous pouvons utiliser les codes d'erreur standard de HTTP, ou renvoyer toujours les données correctement formatées :

En utilisant le code HTTP
void header( string reason_phrase [, bool replace [, int http_response_code]] )

header() peut être utilisé pour définir l'état au retour de l'opération. Nous pouvons définir toutes les valeurs possibles de reason_phrase, donc pour le login en échec nous pouvons renvoyer code=403 et phrase="BadPassword", alors qu'en cas de succès nous renverrons simplement la réponse sans modifier l'entête.

Les pour : C'est une norme. Le client doit toujours traiter les erreurs HTTP, donc l'utilisation du code HTTP pour le résultat supprimerait toute gestion d'erreur séparée à réaliser par le client. Comme le client peut demander des données dans plusieurs formats, un paramètre de format non valide serait toujours correctement géré, car il s'agira simplement d'un autre code d'erreur HTTP.

Les contre : ...

Inclure des informations d'erreur dans une réponse appropriée

Cette méthode renverrait toujours un objet de réponse correctement formaté, mais l'état de l'erreur ou la description seront les seules valeurs à l'intérieur de cet objet. Ceci est similaire à la façon dont l'API Query actuelle renvoie les codes d'état.

Les pour : Les codes d'erreur HTTP sont utilisés uniquement pour les problèmes de réseau, mais pas pour les données (erreurs logiques). Nous ne sommes pas liés aux codes d'erreur HTTP existants.

Les contre : Si le paramètre de format des données n'est pas correctement spécifié, quel est le format des données en sortie ? L'application doit analyser l'objet pour connaître une erreur (performances ?). Le code de vérification d'erreur doit être présenté à la fois au niveau de la connexion et et au niveau de l'analyse des données.

Squelette de code

Il a été suggéré que cette page ou cette section soit fusionnée avec API:Extensions#ApiSampleApiExtension.php .(Discussion)
Module d'API simple
<?php
class Api<nom de module> extends ApiBase {
	public function __construct( $main, $action ) {
		parent::__construct( $main, $action );
	}
	public function execute() {
		
	}
	public function getAllowedParams() {
		return array(
			'<nom du paramètre>' => array(
				ApiBase::PARAM_TYPE => array( 'foo', 'bar', 'baz' ),
			),
		);
	}
	public function getParamDescription() {
		return array(
			'<nom du paramètre>' => '<description de paramètre>',
		);
	}
	public function getDescription() {
		return '<Description du module ici>';
	}
	public function getExamples() {
		return array(
			'api.php?action=<nom de module>&<nom du paramètre>=foo'
		);
	}
	public function getHelpUrls() {
		return '';
	}
}

AltStyle によって変換されたページ (->オリジナル) /