Jump to content

API:Uygulama Stratejisi

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

Bu, MediaWiki API makinesinin temelde uygulanmasını açıklar. Kodunuzda istemcilerin kullanması için bir API sağlamak istiyorsanız, API:Uzantılar sayfasını okuyun.

Dosya/Modül Yapısı

  • api.php, viki kökünde bulunan giriş noktasıdır. API:Anasayfa#Uç nokta bölümüne bakın.
  • includes/api, API ile ilgili tüm dosyaları içerecek, ancak hiçbirinin giriş noktası olarak kullanılmasına izin verilmeyecektir.
  • Tüm API sınıfları ortak bir soyut sınıf ApiBase üzerinden türetilmiştir. Temel sınıf, parametre ayrıştırma, profil oluşturma ve hata işleme gibi ortak işlevler sağlar.
  • ApiMain, api.php tarafından başlatılan ana sınıftır. action=XXX parametresine göre hangi modülün çalıştırılacağını belirler. ApiMain ayrıca, çıkışı verisi dizisini ve ilgili yardımcı işlevleri içeren ApiResult sınıfının bir örneğini oluşturur. Son olarak, ApiMain, veriyi ApiResult üzerinden XML/JSON/PHP veya başka bir biçimde istemciye çıkaracak biçimlendirme sınıfını başlatır.
  • ApiBase üzerinden türetilen herhangi bir modül, örnekleme sırasında ApiMain bir örneğine bir kaynak alır, böylece modül yürütme sırasında sonuç nesnesi gibi paylaşılan kaynakları alabilir.

Sorgu modülleri

  • ApiQuery, alt modülleri yürüttüğü için ApiMain ile benzer davranır. Her bir alt modül, ApiQueryBase üzerinden türetilir (üst düzey bir modül olan ApiQuery kendisi hariç). Örnekleme sırasında, alt modüller ApiQuery örneğine bir kaynak alır.
  • Tüm uzantı sorgu modülleri 3 veya daha fazla harfli önek kullanmalıdır. Çekirdek modüller 2 harfli ön ek kullanır.
  • ApiQuery yürütme planı:
    1. Gerekli alt modülleri belirlemek için paylaşılan list/prop/meta sorgu parametrelerini alın.
    2. Bir ApiPageSet nesnesi oluşturun ve onu titles/pageids/revids parametrelerinden doldurun. pageset nesnesi, sorgu modüllerinin birlikte çalışacağı sayfaların veya revizyonların listesini içerir.
    3. İstenirse, başka bir PageSet oluşturmak için bir oluşturucu modülü çalıştırılır. UNIX'teki boru akışlarına benzer. Verilen sayfalar, diğer tüm modüllerin üzerinde çalışması için başka bir sayfa kümesi üreten oluşturucu girdisidir.
  • Sorgu devam ettirme gereksinimleri:
    • SQL sorgusu tamamen sıralanmalıdır. Başka bir deyişle, sorgu, WHERE yan tümcesinde veya ORDER BY yan tümcelerinde sabitler olarak bazı benzersiz anahtarların tüm sütunlarını kullanıyor olmalıdır.
      • MySQL'de bu bir özel veya, Foo ve Bar sorgulamalarının başlığa göre sıralanması gerektiği, ancak ad alanına göre sıralanmaması gereken (ad alanı 0 sabittir), Foo ve Talk:Foo ad alanına göre sıralanmalı ancak başlığa göre sıralanmamalıdır (başlık sabit "Foo") ve Foo ve Talk:Bar hem ad alanına hem de başlığa göre sıralanmalıdır.
    • SQL sorgusu dosya sıralaması yapmamalıdır.
    • setContinueEnumParameter() ile verilen değer, ORDER BY yan tümcesindeki tüm sütunları içermelidir.
    • Devam ederken, WHERE cümlesine tek bir bileşik koşul eklenmelidir. Sorguda ORDER BY column_0, column_1, column_2 varsa, bu koşul aşağıdaki gibi görünmelidir:
(column_0 > value_0 OR (column_0 = value_0 AND
 (column_1 > value_1 OR (column_1 = value_1 AND
  (column_2 >= value_2)
 ))
))

Tabii ki, ORDER BY sütunlarınız DESC kullanıyorsa "<" için ">" değiştirin. Değerlerde SQL enjeksiyonundan kaçındığınızdan emin olun.

Dahili veri yapıları

  • Sorgu API'si, çok başarılı bir küresel iç içe geçmiş array() yapısına sahipti. Çeşitli modüller, son olarak, yazıcılardan biri (çıkış modülleri) tarafından istemci için işlenene kadar, bu dizinin birçok farklı noktasına veri parçaları ekleyecektir. API için, bu diziyi tek tek yaprak düğümleri eklemek üzere yardımcı işlevlere sahip bir sınıf olarak sarmalamanızı öneririz.

Hata/durum raporlama

Şimdilik hata bilgilerini normal sonuç olarak aynı yapılandırılmış çıkışının içine dahil etmeye karar verdik (seçenek #2).

Sonuç olarak, standart HTTP hata kodlarını kullanabiliriz veya her zaman uygun şekilde biçimlendirilmiş bir veri döndürebiliriz:

HTTP kodunu kullanma
void header( string reason_phrase [, bool replace [, int http_response_code]] )

header(), işlemin döndürme durumunu ayarlamak için kullanılabilir. reason_phrase tüm olası değerlerini tanımlayabiliriz, bu nedenle başarısız oturum açma için code=403 ve phrase="BadPassword" döndürebiliriz, oysa herhangi bir başarı için başlığı değiştirmeden basitçe yanıtı döndürürdük.

Artılar: Bu bir standart. İstemci her zaman HTTP hatalarıyla uğraşmak zorundadır, bu nedenle sonuç için HTTP kodunu kullanmak, istemcinin gerçekleştirmesi gereken ayrı bir hata işlemeyi ortadan kaldırır. İstemci birden fazla biçimde veri talep edebileceğinden, geçersiz bir format parametresi yine de düzgün bir şekilde ele alınacaktır, çünkü bu yalnızca başka bir http hata kodu olacaktır.

Eksiler: ...

Hata bilgilerini uygun bir yanıtın içine ekleyin

Bu yöntem her zaman uygun şekilde biçimlendirilmiş bir yanıt nesnesi döndürür, ancak hata durumu/açıklaması bu nesnenin içindeki tek değerler olacaktır. Bu, mevcut Sorgu API'nin durum kodlarını döndürme şekline benzer.

Artılar: HTTP hata kodları, veriler (mantıksal hatalar) için değil, yalnızca ağ oluşturma sorunları için kullanılır. Mevcut HTTP hata kodlarına bağlı değiliz.

Eksiler: Veri format parametresi doğru şekilde belirtilmezse, çıkış verilerinin biçimi nedir? Uygulama, bir hatayı bilmesi için nesneyi ayrıştırmalıdır (perf?). Hata kontrol kodunun hem bağlantı hem de veri ayrıştırma seviyelerinde olması gerekir.

Basmakalıp kodu

Basit API modülü
<?php

class Api<modül adı> extends ApiBase {
	public function __construct( $main, $action ) {
		parent::__construct( $main, $action );
	}

	public function execute() {
		
	}

	public function getAllowedParams() {
		return array(
			'<parametre adı>' => array(
				ApiBase::PARAM_TYPE => array( 'foo', 'bar', 'baz' ),
			),
		);
	}

	public function getParamDescription() {
		return array(
			'<parametre adı>' => '<parametre açıklaması>',
		);
	}

	public function getDescription() {
		return '<Modül açıklaması burada>';
	}

	public function getExamples() {
		return array(
			'api.php?action=<modül adı>&<parametre adı>=foo'
		);
	}

	public function getHelpUrls() {
		return '';
	}
}