Един от най-добрите начини да повишите статуса си на Разработчик на WordPress , поне в очите на вашите клиенти, е да станете квалифицирани в консумацията на API. Ето един често срещан сценарий за внедряване на WordPress API: Вашият клиент ви моли да добавите приспособление към техния сайт - да речем например приспособление за абонамент за имейл. Грабвате някакъв код от тяхната услуга за електронна поща на трета страна - може би това е етикет на скрипт или iframe
- поставяте го на страницата и отговаряте на клиента си: „Разбрах!“
За съжаление, имате работа с малко по-взискателен клиент и той забелязва следните несъвършенства:
На този етап разумно може да се случи едно от двете неща. Можете да обявите тези елементи за „приятни за притежание“ и да успокоите клиента си за достойнствата на 80/20 разтвор , или можете да изпълните тези заявки. В моя личен опит установих, че предоставянето на такива заявки - тоест демонстриране на майсторство на услуги на трети страни - е надежден начин да убедите клиента, че сте от типа съветник на WordPress. Освен това често е забавно да се прави.
През последното десетилетие използвах WordPress като платформа за консумация на API срещу вероятно 50 различни API. Някои от най-често срещаните API са MailChimp, Google Analytics, Google Maps, CloudFlare и Bitbucket. Но какво, ако трябва да направите повече, какво, ако имате нужда от персонализирано решение?
В тази статия ще се разработя срещу общ API за „услуга за електронна поща“, опитвайки се да поддържам нещата възможно най-агностични. Смятам обаче, че е разумно да предположим, че си имаме работа с JSON REST API. Ето някои основни теми, които могат да ви помогнат да се насладите на техническите моменти в тази статия:
Ако откриете, че сте малко запознати с тези теми и се интересувате от задълбочаване, направете пауза точно сега и изтеглете отличното Пощальон приложение. Тя ви позволява да комуникирате с API, без да пишете код.
Ако обаче изобщо не сте запознати с тях, продължете да четете все пак. Техническа аудитория с известна степен на WordPress опит ще извлече максимума от тази статия, но аз ще се погрижа да обясня стойност на всяка техника по по-малко технически начин. Нетехническият читател ще остави тази статия в състояние да оцени възвръщаемостта на инвестициите на всяка точка, преди да я спонсорира, и да прецени качеството на изпълнение, след като бъде доставено.
Забележка: В случай, че имате нужда от бърз опреснителен курс, можете да разгледате нашия Ръководство за API на WordPress REST .
Без допълнителни преамбюли, позволете ми да споделя с вас шепа различни техники, които оценявам в повечето API, проекти и екипи, с които работя.
В моя начален параграф забелязах, че на клиента му е досадно да прехвърля две администраторски области: wp-admin и таблото за управление на имейл услугата си. Един добър начин да се реши това би бил да им се предостави приспособление за табло в wp-admin, за да се покаже обобщение на скорошната им абонатна активност.
Но отново, това може да изисква множество HTTP заявки към отдалечения API (API, предоставен от услугата за електронна поща), което води до дълги зареждания на страници. Решението на този проблем с производителността е да съхранявате API повикванията като преходни процеси. Това Член на Кодекс предоставя чудесно обяснение, което определено трябва да прочетете, но аз ще го обобщя по този начин:
set_transient()
с избрано от вас време на изтичане въз основа на вашата собствена преценка за производителността, ограниченията на скоростта и границите за грешка при показване на остарели данни в това конкретно приложение.get_transient()
преди да заключите, че трябва да го получите от API.Смятам, че това е полезна и жизнеспособна основа, но можете да направите още една крачка напред, ако помислите за момент за REST глаголи. От петте най-често срещани метода (GET, POST, PATCH, PUT, DELETE), само един от тях принадлежи във вашия преходен кеш. Можете ли да познаете кой? Това е GET. В моите плъгини почти винаги имам PHP клас, посветен на абстрахиране на извиквания към въпросния отдалечен API, и аргумент при инстанцирането на този клас е HTTP методът. Ако това не е GET повикване, тогава изобщо няма да извиквам кеширащ слой.
Освен това, ако това не е GET повикване, тогава има основание да предприема някакви действия за промяна на отдалечените данни по някакъв начин, може би чрез добавяне, редактиране или премахване на абонат на имейл. Това може да е подходящ момент за обезсилване на съществуващия кеш за този ресурс чрез delete_transient()
.
За да се върнем към нашия пример за приложен програмен интерфейс (API) за абонамент за WordPress, ето как това би действало на практика:
/subscribers
чрез GET заявка. Тъй като това е GET заявка, тя се съхранява в моя преходен кеш./subscribers
чрез POST заявка. Тъй като това е заявка POST, не само ще избегне преходния ми кеш, но и ще ме провокира да изтрия съответната част от преходния ми кеш, така че приспособлението на таблото да отразява този нов абонат.Като клиент или друг по-малко технически участник трябва да поискате специално преходно кеширане - или поне дискусия за него - всеки път, когато приложението изтегля данни от отдалечена услуга. Трябва да се запознаете с отличното Монитор на заявки плъгин, за да получите представа за това как работят преходните процеси. Той ще ви даде интерфейс за преглед на това кои данни се съхраняват като преходни, колко често и за колко време.
Някои първокласни хостинг услуги на WordPress всъщност не ви позволяват да използвате преходни процеси в производството. Те имат стартиран код, може би под формата на MU плъгин или някакъв друг скрипт, който ще пресече опита ви да използвате API за преходни процеси и съхранява тази информация чрез кеш обект вместо. WP-двигател , в най-често срещаната си конфигурация, е отличен пример за това.
Ако просто съхранявате и извличате данни, всъщност не е нужно да се грижите за това и може дори никога да не забележите, че се случва. Цялото семейство на *_transient()
Функциите ще ви осигурят същия краен резултат, просто филтриран, за да използвате кеша на обекта вместо преходния кеш. Възможно е обаче да срещнете проблеми при опит за изтриване на преходни процеси. Ето защо.
Ако вашата интеграция на API е достатъчно сложна, за да заслужи собствената си страница с настройки, може да искате да включите потребителски интерфейс, който да позволи на потребителя на администратор да изчистете целия преходен кеш за вашата приставка . Най-често се използва този бутон, когато клиентът промени някои данни директно в отдалечената услуга и иска да обезсили кеша, който съхраняваме в WordPress. Този бутон може също да ви бъде полезен, ако клиентът промени идентификационните данни на акаунта, API ключовете или просто като бутон за „възстановяване на фабричните настройки“ за отстраняване на грешки.
Дори да сте били достатъчно умни, за да поставите пространство на имена на всичките си преходни ключове, така че да имате надежда да идентифицирате всеки от тях за delete_transient()
, най-добрият сценарий вероятно все още включва суров SQL, който винаги се опитвам да избегна в WordPress :
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 ); } } ?>
Не е удобно, не е ефективно. Вместо това тази ситуация изисква кеширане на обекти защото кеширането на обекти ни дава удобен начин да групираме кешираните стойности заедно . По този начин, когато трябва да изпразните всички кеширани стойности, свързани с вашата приставка, това е просто еднолинейно повикване към wp_cache_delete( $key, $group )
Бих обобщил всичко това, като казах: Не можете да бъдете експерт в консумацията на API, ако все още не сте експерт в управлението на кеша за тези данни.
Като клиент ключовото нещо, което трябва да внимавате, е отклонено поведение на кеша между промените и производствените среди. С други думи, въпреки че тестването на нова партида работа в постановка винаги е добра практика, кеширането е нещо, което също трябва да се тества в производството с еднакво внимание.
Когато излагам различните PHP класове за моя плъгин, често ми се струва полезно да имитирам начина, по който се определят крайните точки на API - например какво общо имат следните крайни точки?
Всички те се връщат колекции , като имам предвид резултата от GET заявка, връщащ нула към много резултати, където всеки резултат е член на масив. Това може да звучи доста очевидно, но намирам, че това е полезно подсказване за следната структура на класа в моя PHP код:
class.collection.php
, абстрактен класclass.subscribers.php
разширява абстрактния клас, Collection
.class.lists.php
разширява абстрактния клас, Collection
.class.campaigns.php
разширява абстрактния клас, Collection
.Абстрактният клас ще вземе като единствен аргумент масив от параметри на заявката: неща като разбиране на страницата, колона за сортиране, ред на сортиране и филтри за търсене. Той ще има методи за често срещани задачи като извикване на отдалечен API, обработка на грешки и може би преобразуване на резултатите в HTML меню или jQueryUI AutoSuggest. Класовете, които създават екземпляр на абстрактния клас, може да са доста кратки, може би да правят малко повече от посочване на низа, който да се използва в *.json
URL адрес на крайната точка на API.
По същия начин, какво е общото между следните крайни точки?
Всички те връщат вещ , като имам предвид точно един конкретен, уникален член на колекция: неща като един конкретен абонат на имейл, един имейл списък или една имейл кампания. Затова обичам да използвам следната структура в моя PHP код:
class.item.php
, абстрактен класclass.subscriber.php
разширява абстрактния клас, Item
.class.list.php
разширява абстрактния клас, Item
.class.campaign.php
разширява абстрактния клас, Item
.Абстрактният клас би приел като единствен аргумент низ, който да идентифицира конкретния елемент, който се иска. Още веднъж, инстанцираните класове може да са доста кратки, може би да направят малко повече от посочване на низа, който да се използва в */duy736td.json
Има много подходи за структуриране на наследяване на класове, но дори и да възприемете различен подход към това, което посочих по-горе, обзалагам се, че има голям шанс структурата на отдалечения API да помогне за информирането на структурата на вашето приложение.
Като клиент, често срещан симптом на лоша архитектура е, когато се наложи да поискате една и съща промяна отново и отново в едно приложение. Например, ако поискате отчетите да връщат 100 резултата на страница вместо 10 и трябва да продължите да повтаряте тази заявка за отчети за абонати, отчети за кампании, отчети за отписване и т.н., може да откриете лоша архитектура на класа. В тази ситуация си струва да попитате вашия екип дали биха се възползвали от цикъл на рефакторинг: Работа, при която целта не е да се промени поведението на продукта, а по-скоро да се подобри основният код, така че да стане по-лесно да се промени поведението на продукта в бъдеще.
WP_Error
Неудобно ми е да призная, че ми отне години по-дълго, отколкото би трябвало, за да започна правилно да използвам WP_Error
семейство от функции в моя код. Склонен съм просто да кодирам пътя си, или предполагайки, че никога няма да има грешки, които си струва да се грижим програмно, или да ги обработвам за всеки отделен случай. Работата с отдалечени приложни програмни интерфейси (API) пресича този манталитет като лазерен лъч, тъй като представлява изключително удобен и мощен случай за използване WP_Error
Спомнете си по-рано, че споменах, че често имам PHP клас, чиято цел е да отправя HTTP заявки към отдалечения API. Когато отлепите целия шаблон, всички манипулации с данни, всички вторични проблеми, този клас наистина се свежда до извикване wp_remote_request()
така че да получите HTTP обект на отговор от API. Удобно, wp_remote_request()
вместо това ще върне WP_Error
ако повикването не успее да се изпълни по някаква причина, но какво ще стане, ако повикването успее да върне HTTP отговор от неблагоприятен тип?
Като пример, може би сме се обадили на /lists.json
крайна точка, но този конкретен акаунт все още няма създадени списъци. Това би върнало валиден HTTP отговор, но със код на състоянието 400. Макар че това не е точно фатална грешка сама по себе си, от гледна точка на някакъв преден код, който иска да превърне това API повикване в падащо меню, 400 може както и да бъде a WSOD ! Ето защо намирам за полезно да направя допълнителен анализ на резултата от wp_remote_request()
, потенциално връщане на WP_Error
след всичко:
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; } ?>
Този модел може да помогне за опростяване на кода, който извиква нашия клас повикващи, защото знаем, че можем безопасно да разчитаме на is_wp_error()
преди да продължите с нашия изход.
Като клиент трябва понякога да играете ролята на злонамерен потребител, объркан потребител и нетърпелив потребител. Използвайте приложението по начини, по които не е предназначено да се използва. Правете нещата, които вашите разработчици не искат да правите. Обърнете внимание на това, което се случва. Получавате ли полезни съобщения за грешка? Получавате ли изобщо съобщения за грешка? Ако не, може да си струва да спонсорирате трудова работа за по-добро обработване на грешки.
ob_get_clean()
Съвременната програмируема мрежа, където почти всеки сайт използва API на други сайтове и се консумира чрез собствен API, се превърна в невероятно мощна арена за код. Но точно това качество може да го направи и доста бавно.
Обичайно е отдалечените HTTP заявки да бъдат най-трудоемките части от дадено зареждане на страница. Поради тази причина много управлявани от API компоненти се изпълняват или чрез Ajax, или cron. Например, автосугест за търсене в списък с абонати на имейли вероятно трябва да пинг на отдалечения източник на данни при поискване, при всяко натискане на клавиш, вместо да зарежда всички 100 000 абонати в DOM, докато страницата се зарежда. Ако това не е опция, може би голяма заявка може да се синхронизира за нощна cron задача, така че резултатите да могат да бъдат изтеглени от локално огледало, а не от отдалечен API.
Проблемът с този подход е, че може да бъде трудно за отстраняване на грешки. Вместо просто да включите WP_DEBUG
и оставяйки съобщенията за грешки да се търкалят в прозореца на браузъра ви, вие сте останали да търсите в мрежовата конзола на браузъра или да запишете регистрационен файл като cron задача (надявам се?), която се изпълнява. Намирам това за неудобно.
Един от начините за подобряване на тази ситуация е да се отправят внимателни и стратегически призиви error_log()
. Но отново, често срещан проблем при регистрирането е, че при големи или заети приложения регистрационните файлове за грешки могат да станат твърде големи или да нараснат твърде бързо, за да бъдат полезни за наблюдение или анализиране. Следователно трябва да бъдем избирателни с това, което регистрираме, влагайки точно толкова мисли в това, както правим с нашата действителна логика на приложението . Жалко е, че отделихте време, за да регистрирате някаква екзотична грешка в случай на ръб, която изглежда се появява периодично при някаква рядка cron задача, само за да осъзнаете, че истинската същност на грешката ви е избегнала отново, защото не сте успели да влезете в определен член на масива , да речем, на обидната стойност.
Затова моята философия стана, Не винаги влизам, но когато го правя, записвам всичко . С други думи, след идентифициране на особено тревожна функция, ще я регистрирам с възможно най-широка мрежа:
var_dump()
Това се равнява на
|_+_|‘въвеждане на цялата стойност на бъги в един запис във файла с грешки.
Като клиент си струва периодично да проверявате общото използване на файловата памет за вашето приложение. Ако забележите, че внезапно се изправяте срещу ограниченията за съхранение в хостинг акаунта си, има голяма вероятност да е виновен дневникът на грешките. Вашите разработчици ще се възползват от работен цикъл, фокусиран върху по-добро регистриране - и вашите клиенти също!
Моля да простите структурата на списъка на тази статия. Не можах да принудя тези точки към по-обединяваща тема на статията, защото тези модели са много общи: Те се прилагат за всяка крайна точка на JSON REST и за всеки изход на WordPress .
Те са моделите, които виждам да се случват отново и отново, независимо от това какъв е отдалеченият API или за какво го използваме в WordPress. Стигнах дотам, че събрах всички тези видове принципи в един шаблон, който значително ускорява работата ми. Имате ли подобни точки, които запазвате за всеки проект? Моля, споделете ги, за да мога да ги открадна и да ги добавя към моя шаблон!
Свързани: Как да подходим към модерното разработване на WordPress (част 1)Удобен начин за използване на WordPress за публикуване на API. Този API може да се използва от други сайтове на WordPress, други сайтове, които не са WordPress, или дори самият сайт за публикуване. Това е популярен подход за използване на WordPress като „безглава“ CMS или дори само за дребни слушатели на Ajax.
API ключовете са често срещан начин за управление на удостоверяването. API на WordPress е съвместим с няколко метода за удостоверяване. Един от тях е WordPress REST API OAuth плъгин, който дава на потребителите интерфейс за управление на API ключове.
WP-JSON може да се разглежда като събрат на RSS изгледа на WordPress заедно с нормалния му изглед отпред. Това е друг начин за извеждане на данни на WordPress, въпреки че повечето читатели не биха искали да използват WordPress в този формат. По-скоро целта му е да се консумира от клиенти на API.