WordPress API Geliştiricinizin Kullanmadığı Savaşta Test Edilmiş Beş Teknik
Yayınlanan: 2022-03-11En azından müşterilerinizin gözünde bir WordPress geliştiricisi olarak durumunuzu yükseltmenin en iyi yollarından biri, API'leri kullanma konusunda yetenekli olmaktır. İşte WordPress API uygulaması için yaygın bir senaryo: Müşteriniz, örneğin bir e-posta aboneliği widget'ı gibi sitelerine bir widget eklemenizi istiyor. Üçüncü taraf e-posta hizmetlerinden bazı kodlar alırsınız (belki bu bir komut dosyası etiketi veya bir iframe
) bu kodu sayfaya yapıştırır ve müşterinize "Anladım!" yanıtını verirsiniz.
Ne yazık ki, biraz daha talepkar bir müşteriyle uğraşıyorsunuz ve onlar aşağıdaki kusurları fark ediyor:
- Widget, sitenin geri kalanı gibi, sans-serif yazı tipine sahip olsa da, tam olarak doğru değil. Widget, yüklediğiniz özel yazı tipi yerine Helvetica kullanıyor.
- Widget'ın abonelik formu, yeni bir sayfa yüklemesini tetikler; bu, bir makalenin yarısına yerleştirildiğinde kesintiye neden olabilir.
- Widget'ın sayfanın geri kalanından sonra yüklenmesi fazladan bir zaman alıyor gibi görünüyor, bu da sarsıcı ve ucuz hissettiriyor.
- İstemci, abonelerin, abone oldukları gönderiye dayalı olarak meta verilerle etiketlenmesini ister ve pencere öğesi, bu işlevselliğe uzaktan benzeyen hiçbir şey sunmaz.
- İstemci, artık iki panoyu (wp-admin ve e-posta hizmeti için yönetici alanı) yönetmek zorunda kalmasını can sıkıcı buluyor.
Bu noktada, iki şeyden biri makul bir şekilde gerçekleşebilir. Bu öğeleri “olması güzel” ilan edebilir ve müşterinize 80/20 çözümünün faydaları konusunda güvence verebilir veya bu talepleri yerine getirebilirsiniz. Kişisel deneyimime göre, bu tür istekleri yerine getirmenin, yani üçüncü taraf hizmetlerinde ustalık göstermenin, müşteriyi bir tür WordPress sihirbazı olduğunuza ikna etmenin güvenilir bir yolu olduğunu buldum. Ayrıca, genellikle yapmak eğlencelidir.
Son on yılda, WordPress'i muhtemelen 50 farklı API'ye karşı API tüketimi için bir platform olarak kullandım. En yaygın API'lerden bazıları MailChimp, Google Analytics, Google Haritalar, CloudFlare ve Bitbucket olmuştur. Peki ya daha fazlasını yapmanız gerekiyorsa, ya özel bir çözüme ihtiyacınız olursa?
WordPress API İstemcisi Nasıl Geliştirilir
Bu makalede, işleri olabildiğince agnostik tutmak için elimden gelenin en iyisini yapmaya çalışarak, genel bir "e-posta hizmeti" API'sine karşı geliştireceğim. Ancak, bir JSON REST API ile uğraştığımızı varsaymanın makul olduğunu düşünüyorum. Bu makaledeki teknik noktalardan keyif almanıza yardımcı olabilecek bazı arka plan konuları şunlardır:
- WordPress HTTP işlev ailesi
- JSON
- DİNLENMEK
Kendinizi bu konulara çok az aşina buluyorsanız ve daha derine inmekle ilgileniyorsanız, hemen durun ve mükemmel Postacı uygulamasını indirin. API'ler ile kod yazmadan iletişim kurmanızı sağlar.
Ancak, bunlara hiç aşina değilseniz, yine de okumaya devam edin. Bir dereceye kadar WordPress deneyimine sahip teknik bir izleyici bu makaleden en iyi şekilde yararlanacaktır, ancak her bir tekniğin değerini daha az teknik bir şekilde açıklamaya özen göstereceğim. Teknik bilgisi olmayan bir okuyucu, bu makaleyi, sponsorluk yapmadan önce her noktanın yatırım getirisini değerlendirebilecek ve teslim edildikten sonra uygulamanın kalitesini değerlendirebilecek şekilde bırakacaktır.
Not: Hızlı bir tazeleme kursuna ihtiyacınız varsa, WordPress REST API kılavuzumuza göz atabilirsiniz.
Daha fazla giriş yapmadan, birlikte çalıştığım çoğu API, proje ve ekipte kendimi takdir ettiğim bir avuç farklı tekniği sizinle paylaşmama izin verin.
Geçici Olaylar: Ne Zaman Tutmalı, Ne Zaman Katlamalı
Açılış paragrafımda, müşterinin iki yönetici alanını bir araya getirmeyi can sıkıcı bulduğunu belirttim: wp-admin ve e-posta hizmetleri için kontrol paneli. Bunu çözmenin iyi bir yolu, onlara en son abone etkinliklerinin bir özetini göstermeleri için wp-admin'de bir pano widget'ı sağlamak olacaktır.
Ancak bu, uzak API'ye (e-posta hizmeti tarafından sağlanan API) birden fazla HTTP isteği gerektirebilir ve bu da uzun sayfa yüklemelerine neden olabilir. Bu performans sorununun çözümü, API çağrılarını geçici olarak saklamaktır. Bu Codex makalesi, kesinlikle okumanız gereken harika bir açıklama sunuyor, ancak bunu şöyle özetleyeceğim:
- Uzak API'den verileri alın.
-
set_transient()
kullanarak performans, hız limitleri ve bu özel uygulamada güncel olmayan verilerin görüntülenmesindeki hata payı hakkındaki kendi kararınıza dayalı olarak seçtiğiniz bir sona erme süresiyle saklayın. - Durum ne olursa olsun, verileri işleyerek, bir değer döndürerek iş mantığınızla ilerleyin.
- Bir sonraki sayfa yüklemesi gibi verilere yeniden ihtiyaç duyduğunuzda, API'den almanız gerektiğine karar vermeden önce
get_transient()
kullanarak geçici önbellekte kontrol edin.
Bunun yararlı ve geçerli bir temel olduğunu düşünüyorum, ancak bir an için REST fiilleri hakkında düşünürseniz bir adım daha ileri gidebilirsiniz. En yaygın beş yöntemden (GET, POST, PATCH, PUT, DELETE) yalnızca biri geçici önbelleğinize aittir. Hangisi olduğunu tahmin edebilir misin? GET. Eklentilerimde, neredeyse her zaman söz konusu uzak API'ye yapılan çağrıları soyutlamaya adanmış bir PHP sınıfım var ve bu sınıfın örneğini oluştururken bir argüman HTTP yöntemidir. Bu bir GET çağrısı değilse, o zaman herhangi bir önbelleğe alma katmanını hiç çağırmayacağım.
Ayrıca, bu bir GET çağrısı değilse, uzak verileri bir şekilde, belki de bir e-posta abonesi ekleyerek, düzenleyerek veya kaldırarak değiştirmek için bazı eylemlerde bulunmamın nedeni var. Bu, söz konusu kaynak için mevcut önbelleği delete_transient()
yoluyla geçersiz kılmak için iyi bir zaman olabilir.
Bir WordPress e-posta aboneliği API'si örneğimize geri dönmek için, bunun pratikte nasıl çalışacağı aşağıda açıklanmıştır:
- Son aboneleri göstermek için bir pano widget'ı, bir GET isteği aracılığıyla
/subscribers
için API uç noktasını arayacaktır. Bu bir GET isteği olduğu için geçici önbelleğimde saklanıyor. - E-posta listesine abone olmak için bir kenar çubuğu gereci, bir POST isteği aracılığıyla
/subscribers
için API uç noktasını arayacaktır. Bu bir POST isteği olduğu için, yalnızca geçici önbelleğimden kaçınmakla kalmayacak, aynı zamanda gösterge panosu pencere aracının bu yeni aboneyi yansıtması için geçici önbelleğimin ilgili bölümünü silmem için beni kışkırtacak. - Geçici olayları adlandırırken, genellikle onları aradığım uzak API URL'sinden sonra tam anlamıyla adlandırarak düzenlerim. Bu, silinecek doğru geçici olayı belirlemenin kullanışlı bir yoludur. Argüman alan bir uç noktaysa, bunları bir dizgede birleştirir ve geçici isme de eklerim.
Bir müşteri veya daha az teknik bir paydaş olarak, uygulama uzak bir hizmetten veri çekerken, geçici önbelleğe almayı veya en azından bununla ilgili bir tartışmayı özel olarak talep ediyor olmalısınız. Geçici olayların nasıl çalıştığına dair bir fikir edinmek için mükemmel Query Monitor eklentisine aşina olmalısınız. Hangi verilerin geçici olarak, ne sıklıkta ve ne kadar süreyle saklandığına göz atmanız için bir arayüz sağlayacaktır.
Bazen Geçici Olaylar Yeterince İyi Değildir
Bazı premium WordPress barındırma hizmetleri aslında üretimde geçici olayları kullanmanıza izin vermez. Geçici API'yi kullanma girişiminizi durduracak ve bunun yerine bu bilgiyi nesne önbelleği aracılığıyla depolayacak, belki de bir MU eklentisi veya başka bir komut dosyası biçiminde çalışan kodları vardır. WP-Engine, en yaygın konfigürasyonunda bunun en iyi örneğidir.
Yalnızca veri depoluyor ve alıyorsanız, aslında bununla ilgilenmeniz gerekmez ve bunun olduğunu asla fark etmeyebilirsiniz. *_transient()
işlevleri ailesinin tamamı, geçici önbellek yerine nesne önbelleğini kullanmak için filtrelenmiş olarak size aynı sonucu sağlayacaktır. Sorunlarla karşılaşabileceğiniz yer, geçici olayları silmeye çalıştığınız zamandır. İşte neden.
API entegrasyonunuz kendi ayarlar sayfasını hak edecek kadar karmaşıksa, yönetici kullanıcının eklentiniz için tüm geçici önbelleği temizlemesine izin vermek için bir kullanıcı arayüzü eklemek isteyebilirsiniz. Bu düğmenin en yaygın kullanımı, istemci doğrudan uzak hizmetteki bazı verileri değiştirdiğinde ve WordPress'te depoladığımız önbelleği geçersiz kılmak istediğinde olur. Bu düğme, istemci hesap kimlik bilgilerini, API anahtarlarını değiştirirse veya yalnızca hata ayıklama için yalnızca "fabrika ayarlarına sıfırlama" düğmesi olarak da kullanışlı olabilir.
delete_transient()
için her birini tanımlama umudunuz olacak şekilde tüm geçici anahtarlarınızı adlandıracak kadar akıllı olsanız bile, en iyi durum senaryosu muhtemelen WordPress'te her zaman kaçınmaya çalıştığım ham SQL'i içerir:
<?php // Purge all the transients associated with our plugin. function purge() { global $wpdb; $prefix = esc_sql( $this -> get_transient_prefix() ); $options = $wpdb -> options; $t = esc_sql( "_transient_timeout_$prefix%" ); $sql = $wpdb -> prepare ( " SELECT option_name FROM $options WHERE option_name LIKE '%s' ", $t ); $transients = $wpdb -> get_col( $sql ); // For each transient... foreach( $transients as $transient ) { // Strip away the WordPress prefix in order to arrive at the transient key. $key = str_replace( '_transient_timeout_', '', $transient ); // Now that we have the key, use WordPress core to the delete the transient. delete_transient( $key ); } } ?>
Uygun değil, verimli değil. Bunun yerine, bu durum nesne önbelleğe almayı gerektirir, çünkü nesne önbelleğe alma, önbelleğe alınmış değerleri birlikte gruplandırmanın uygun bir yolunu sunar . Bu şekilde, eklentinizle ilgili tüm önbelleğe alınmış değerleri boşaltmanız gerektiğinde, bu, wp_cache_delete( $key, $group )
tek satırlık basit bir çağrıdır.
Tüm bunları şu şekilde özetleyebilirim: Henüz o veriler için önbelleği yönetme konusunda uzman değilseniz, API'leri tüketme konusunda uzman olamazsınız.

Bir müşteri olarak, dikkat edilmesi gereken en önemli şey, hazırlama ve üretim ortamları arasındaki anormal önbellek davranışıdır. Başka bir deyişle, aşamalandırmada yeni bir iş grubunu test etmek her zaman iyi bir uygulama olsa da, önbelleğe alma, üretimde de eşit özenle test edilmesi gereken bir şeydir.
Remote API, PHP Sınıf Hiyerarşinizi Bilgilendirmenize Yardımcı Olabilir
Eklentim için çeşitli PHP sınıflarını düzenlerken, genellikle API uç noktalarının tanımlanma şeklini taklit etmeyi yararlı buluyorum; örneğin, aşağıdaki uç noktaların ortak noktası nedir?
- https://api.example-email-service.com/v1/subscribers.json
- https://api.example-email-service.com/v1/lists.json
- https://api.example-email-service.com/v1/campaigns.json
Hepsi, bir GET isteğinin sonucunu kastettiğim, her sonucun bir dizinin üyesi olduğu sıfırdan çoğa sonuç döndüren koleksiyonları döndürür. Bu oldukça açık gelebilir, ancak PHP kodumda aşağıdaki sınıf yapısı için yararlı bir bilgi istemi olduğunu düşünüyorum:
-
class.collection.php
, soyut bir sınıf -
class.subscribers.php
,Collection
adlı soyut sınıfı genişletir. -
class.lists.php
,Collection
adlı soyut sınıfı genişletir. -
class.campaigns.php
,Collection
adlı soyut sınıfı genişletir.
Soyut sınıf, tek argümanı olarak bir dizi sorgu parametresini alır: sayfalandırma, sıralama sütunu, sıralama düzeni ve arama filtreleri gibi şeyler. Uzak API'yi çağırmak, hataları ele almak ve belki de sonuçları bir HTML <select>
menüsüne veya bir jQueryUI Otomatik Öneriye dönüştürmek gibi yaygın görevler için yöntemlere sahip olacaktır. Soyut sınıfı somutlaştıran sınıflar oldukça kısa olabilir, belki de *.json
API uç noktası URL'sinde kullanılacak dizeyi belirtmekten biraz daha fazlasını yapıyor olabilir.
Benzer şekilde, aşağıdaki uç noktaların ortak noktası nedir?
- https://api.example-email-service.com/v1/subscribers/104abyh4.json
- https://api.example-email-service.com/v1/lists/837dy1h2.json
- https://api.example-email-service.com/v1/campaigns/9i8udr43.json
Hepsi bir öğe döndürür, bununla tam olarak bir koleksiyonun belirli, benzersiz bir üyesini kastediyorum: belirli bir e-posta abonesi, bir e-posta listesi veya bir e-posta kampanyası gibi şeyler. Bu nedenle, PHP kodumda aşağıdaki yapıyı kullanmayı seviyorum:
-
class.item.php
, soyut bir sınıf -
class.subscriber.php
soyut sınıf olanItem
genişletir. -
class.list.php
soyut sınıfı,Item
genişletir. -
class.campaign.php
, soyut sınıf olanItem
genişletir.
Soyut sınıf, talep edilen belirli öğeyi tanımlamak için tek argümanı olarak bir dize alacaktır. Bir kez daha, somutlaştırılan sınıflar oldukça kısa olabilir, belki de */duy736td.json
içinde kullanılacak dizeyi belirtmekten biraz daha fazlasını yapıyor olabilir.
Sınıf mirasını yapılandırmak için birçok yaklaşım vardır, ancak yukarıda ana hatlarıyla belirttiğimden farklı bir yaklaşım benimseseniz bile, uzak API'nin yapısının uygulamanızın yapısını bilgilendirmeye yardımcı olma ihtimalinin yüksek olduğuna bahse girerim.
Bir istemci olarak, zayıf mimarinin yaygın bir belirtisi, kendinizi bir uygulamada aynı değişikliği tekrar tekrar istemek zorunda kalmanızdır. Örneğin, raporların sayfa başına 10 yerine 100 sonuç döndürmesini isterseniz ve bu isteği abone raporları, kampanya raporları, abonelikten çıkma raporları vb. için tekrarlamanız gerekiyorsa, zayıf sınıf mimarisini algılıyor olabilirsiniz. Bu durumda, ekibinize yeniden düzenleme döngüsünden fayda sağlayıp sağlamayacaklarını sormaya değer: Hedefin, ürünün davranışını değiştirmek değil, davranışı değiştirmeyi kolaylaştırmak için temel kodu iyileştirmek olduğu bir çalışma grubu ürünün gelecekte.
WP_Error
için Mükemmel Kullanım Örneği
WP_Error
işlev ailesini düzgün şekilde kullanmaya başlamamın gerekenden daha uzun sürdüğünü kabul etmekten utanıyorum. Programlı olarak ilgilenmeye değecek hataların asla olmayacağını varsayarak ya da duruma göre ele almaya çalışarak yolumu kodlama eğilimindeydim. Uzak API'lerle çalışmak, bu zihniyeti bir lazer ışını gibi keser, çünkü WP_Error
kullanımı için son derece kullanışlı ve güçlü bir kullanım örneği sunar.
Daha önce, amacı uzak API'ye HTTP istekleri yapmak olan bir PHP sınıfım olduğundan bahsettiğimi hatırlayın. Tüm genel bilgileri, tüm veri işlemeyi, tüm ikincil kaygıları geri çektiğinizde, bu sınıf, API'den bir HTTP yanıt nesnesi almak için gerçekten wp_remote_request()
i çağırmaya başlar. Uygun bir şekilde, wp_remote_request()
, çağrı herhangi bir nedenle yürütülmezse, bunun yerine bir WP_Error
döndürür, ancak çağrı uygun olmayan türden bir HTTP yanıtı döndürmeyi başarırsa ne olur?
Örnek olarak, /lists.json
uç noktasına bir çağrı yapmış olabiliriz, ancak bu hesapta henüz herhangi bir liste oluşturulmamıştır. Bu, geçerli bir HTTP yanıtı döndürür, ancak durum kodu 400 olur. Bu, kendi başına tam olarak ölümcül bir hata olmasa da, bu API çağrısını bir açılır menüye dönüştürmek isteyen bazı ön uç kodlarının perspektifinden bakıldığında, 400 bir aynı zamanda bir WSOD olun! Bu nedenle, wp_remote_request()
sonucunun bazı ek ayrıştırmalarını yapmayı yararlı buluyorum, sonuçta potansiyel olarak bir WP_Error
döndürüyor:
<?php function call() { $response = wp_remote_request( $this -> url, $this -> args ); $code = wp_remote_retrieve_response_code( $response ); $first_digit = $code[0]; $good_responses = array( 2, 3 ); if( ! in_array( $first_digit, $good_responses ) { $body = wp_remote_retrieve_body( $response ); $out = new WP_Error( $code, $body ); } else { $out = $response; } return $out; } ?>
Bu model, çağıran sınıfımızı çağıran kodu basitleştirmeye yardımcı olabilir, çünkü çıktımıza devam etmeden önce is_wp_error()
'a güvenle güvenebileceğimizi biliyoruz.
Bir müşteri olarak, ara sıra kötü niyetli bir kullanıcı, kafası karışmış bir kullanıcı ve sabırsız bir kullanıcı rolünü oynamalısınız. Uygulamayı, kullanılması amaçlanmayan şekillerde kullanın. Geliştiricilerinizin yapmanızı istemediği şeyleri yapın. Ne olduğunu not edin. Yararlı hata mesajları alıyor musunuz? Hiç hata mesajı alıyor musunuz? Değilse, daha iyi hata işleme konusunda bir çalışma grubuna sponsor olmaya değer olabilir.
ob_get_clean()
'ın Güzel Hata Ayıklama Gücü
Hemen hemen her sitenin diğer sitelerin API'lerini kullandığı ve kendi API'si aracılığıyla tüketildiği modern programlanabilir web, kod için inanılmaz derecede güçlü bir arena haline geldi. Ancak onu oldukça yavaşlatan da tam olarak bu kalitedir.
Uzak HTTP isteklerinin belirli bir sayfa yüklemesinin en çok zaman alan kısımları olması yaygındır. Bu nedenle, API güdümlü birçok bileşen ya Ajax ya da cron aracılığıyla yürütülür. Örneğin, bir e-posta aboneleri listesinde arama yapmak için bir otomatik öneri, sayfa yüklenirken 100.000 abonenin tamamını DOM'ye yüklemek yerine, muhtemelen her tuş vuruşunda uzak veri kaynağına istek üzerine ping atmalıdır. Bu bir seçenek değilse, belki de büyük bir sorgu gecelik bir cron görevinde senkronize edilebilir, böylece sonuçlar uzak API yerine yerel bir aynadan alınabilir.
Bu yaklaşımla ilgili sorun, hata ayıklamanın zor olabilmesidir. Basitçe WP_DEBUG
ve hata mesajlarının tarayıcı pencerenize gelmesine izin vermek yerine, tarayıcı ağ konsoluna bakmakta veya bir cron görevi (umarım?) yürütülüyormuş gibi bir günlük dosyasını izlemekte mahsur kalırsınız. Bunu rahatsız edici buluyorum.
Bu durumu iyileştirmenin bir yolu, error_log()
dikkatli ve stratejik çağrılar yapmaktır. Ancak, günlüğe kaydetmeyle ilgili yaygın bir sorun, büyük veya yoğun uygulamalarda, hata günlüklerinin izleme veya ayrıştırma için yararlı olamayacak kadar çok büyümesi veya çok hızlı büyümesidir. Bu nedenle, gerçek uygulama mantığımızla yaptığımız gibi , günlüğe kaydettiklerimiz konusunda seçici olmalıyız. Bazı nadir cron görevlerinde yalnızca aralıklı olarak meydana geliyor gibi görünen bazı egzotik uç durum hatasını günlüğe kaydetmeye zaman ayırmanız, yalnızca belirli bir dizi üyesini günlüğe kaydetmeyi başaramadığınız için hatanın gerçek doğasının sizi bir kez daha gözden kaçırdığını anlamak için zaman ayırmanız üzücü. , diyelim ki, rahatsız edici değer.
Bu nedenle felsefem şöyle oldu, her zaman kayıt tutmam ama yaptığım zaman her şeyi kaydederim . Başka bir deyişle, özellikle endişe verici bir işlevi belirledikten sonra, onu mümkün olduğunca geniş bir ağ ile kaydedeceğim:
<?php function debug( $bug ) { ob_start(); var_dump( $bug ); $out = ob_get_clean(); error_log( $out ); } ?>
Bu, var_dump()
' hata günlüğü dosyasındaki tüm buggy değerini tek bir girişe dönüştürmek anlamına gelir.
Bir istemci olarak, uygulamanız için toplam dosya belleği kullanımını düzenli aralıklarla kontrol etmeye değer. Barındırma hesabınızdaki depolama sınırlarına aniden karşı geldiğinizi fark ederseniz, bunun suçlusu bir hata günlüğünün çılgına dönmesi ihtimali yüksektir. Geliştiricileriniz, daha iyi günlüğe kaydetmeye odaklanan bir çalışma döngüsünden yararlanacak ve müşterileriniz de yararlanacak!
Tam olarak Clickbait Değil, Ama Yapacak
Lütfen bu makalenin liste yapısını affedin. Bu kalıplar çok genel olduğu için bu noktaları daha birleştirici bir makale temasına zorlayamadım: Herhangi bir JSON REST uç noktası ve herhangi bir WordPress çıktısı için geçerlidirler .
Uzak API'nin ne olduğuna veya WordPress içinde ne için kullandığımıza bakılmaksızın, tekrar tekrar meydana geldiğini gördüğüm kalıplardır. Tüm bu ilkeleri, çalışmamı büyük ölçüde hızlandıran bir eklenti kazan plakasında toplayacak kadar ileri gittim. Her proje için sakladığınız benzer puanlarınız var mı? Lütfen onları paylaşın, böylece onları çalıp ortak bilgilerime ekleyeyim!