В наше неспокойное время любой разработчик или владелец сайта может столкнуться с необходимостью разработки API, которое позволяло бы сайту взаимодействовать с внешним миром, каким то приложением или другим сайтом. В первую очередь, рассматривается возможность предоставления сайтом определенных данных по стандартизированному запросу из вне. Данное дополнение представляет собой инструмент разработчика, способный создать такое API за счет уже существующих возможностей плагина WP-Recall.
У многих уже на слуху возможности развиваемого WordPress своего API под эту задачу - REST API и если вы знакомы с его возможностями, то увидите, что задачи решаемые API от WordPress и API предлагаемые этим дополнением схожи, поэтому важно понять чем возможности данного дополнения отличаются от API предлагаемого самим WordPress.
Основная проблема REST API WordPress, которую я увидел - отсутствие гибкости. API WordPress заточен исключительно под работу с ядром и его таблицами в базе данных , кастомные таблицы сторонних плагинов - не поддерживаются.
Данное дополнение позволяет строить на своем сайте API для работы с любыми таблицами в вашей базе данных. Такое API можно будет легко расширять новыми таблицами или наоборот, при необходимости сужать его возможности, отключая выбранные таблицы.
RCL REST API - инициативный проект, который позволяет настроить взаимодействие внешних приложений и других серверов с сервером вашего сайта посредством GET запросов. Самое главное - запросы подчинены единому стандарту построения, усвоив этот стандарт, разработчик сможет быстро получать нужные данные из любых таблиц, подключенных к API.
Результат запросов возвращается в виде JSON-строки.
RCL REST API имеет ряд преимуществ перед API WordPress:
- простота и бОльшая гибкость использования - RCL REST API позволяет легко работать как со стандартными таблицами WordPress, так и с произвольными
- возможность за один запрос обращаться к нескольким таблицам - там где API WordPress необходимо послать два и более запросов для получения нужных данных, RCL REST API потребуется сделать лишь один
- кеширование результатов выборки - один и тот же запрос полученный в течении часа будет отдавать уже выбранные ранее и закешированные данные
Для того, чтобы понять, каким образом работает RCL REST API необходимо разобраться в его основе, тогда станет понятно, по какому принципу и стандарту и как в дальнейшем будут строиться запросы к базе данных сервера. Основу здесь составляет мощный класс плагина для построения запросов - Rcl_Query. Данный класс уже подробно описан в заметке. Кроме того, что этот класс удобно использовать любому разработчику в построении запросов к таблицам своих плагинов и дополнений, именно он задает стандарт для работы RCL REST API и понимание его работы совершенно обязательно для дальнейшего рассмотрения принципа работы всего RCL REST API.
Дальнейшее описание будет идти с учетом, что читатель уже знаком с принципом работы класса Rcl_Query и умеет строить с помощью него запросы к таблице в базе данных.
Подключение таблицы к API
Рассмотрим принцип работы RCL REST API на примере "сферического коня в вакууме" - произвольной таблицы custom_table со следующей структурой:
col_id ANYTYPE NOT NULL col_user ANYTYPE NOT NULL col_value ANYTYPE NOT NULL col_date ANYTYPE NOT NULL col_status ANYTYPE NOT NULL
После того, как таблица была создана, подключим ее к классу Rcl_Query, чтобы в дальнейшем легко строить запросы на выборку данных из нее:
class CustomQuery extends Rcl_Query { function __construct() { $table = array( 'name' => 'custom_table', 'as' => 'custom', 'cols' => array( 'col_id', 'col_user', 'col_value', 'col_date', 'col_status' ) ); parent::__construct($table); } }
Теперь, опираясь на стандарт построения запросов внутри класса Rcl_Query, мы можем получать данные из этой таблицы, например:
$Query = new CustomQuery(); return $Query->get_results(array( 'col_user__in' => array(10,25), 'col_value' => 'any', 'fields' => array( 'col_id', 'col_date' ), 'number' => 5, 'orderby' => 'col_date', 'order' => 'ASC' ));
Приведенный пример приведен лишь для демонстрации построения запроса к нашей таблице на основе указанного массива аргументов.
Допустим, мы решили дать возможность формировать к указанной таблице запросы на получение данных из вне, в мобильное приложение или на сторонний сервер. Для этого нам потребуется подключить нашу таблицу к RCL REST API. Сделать это просто, достаточно указать псевдоним таблицы и наименование зарегистрированного класса для работы с ней внутри фильтра "rcl_rest_tables":
add_filter('rcl_rest_tables','add_rest_api_custom_table'); function add_rest_api_custom_table($tables){ $tables['custom-table'] = 'CustomQuery'; return $tables; }
На этом действия необходимые для подключения произвольной таблицы к RCL REST API закончены.
Общий принцип построения запросов
Наше API может принимать внешние запросы на получение данных из этой таблицы и отдавать в ответ выбранные данные в виде JSON-строки.
Запрос строиться по следующему шаблону:
http://domen.com/rcl_api/%action%/%tablename%/?%dataquery%
%action% - действие, которое хотим выполнить, например get - выборка данных,
%tablename% - псевдоним таблицы к которой отправляем запрос,
%dataquery% - аргументы запроса
Обратимся к нашей таблице без указания аргументов запроса:
http://domen.com/rcl_api/get/custom-table/
Ответ будет в формате JSON со следующей структурой:
{ "result":[], "dataquery":{ "args":[], "query":{ "table":{ "name":"custom_table", "as":"custom", "cols":[ "col_id", "col_user", "col_value", "col_date", "col_status" ] }, "select":["custom.*"], "where":[], "join":[], "offset":0, "number":30, "orderby":"custom.col_id", "order":"DESC" } } }
Этот ответ содержит два основных массива: result, где будет находится результат выборки и dataquery, в котором можно отслеживать переданные аргументы, текущую структуру таблицы и параметры сформированного query-запроса для контроля правильности его построения. Массив result на текущий момент пуст, так как не были переданы параметры запроса.
Сделаем запрос на получение некоторых данных передав аргументы для указания выборки:
http://domen.com/rcl_api/get/custom-table/?col_user=10&col_value=any&number=5&orderby=col_date&order=ASC
В полученном ответе мы увидим, что массив result теперь содержит результат выборки из таблицы, а аргументы выборки были перечислены и учтены в массиве dataquery. Останется лишь принять и обработать данные из массива result на стороне внешнего приложения для формирования и вывода контента.
Работа со стандартными таблицами
Ранее уже упоминалось, что RCL REST API может строить запросы к стандартным таблицам WordPress, данное дополнение подключает эти таблицы автоматически и сразу после активации дополнения можно будет строить запросы к таблицам WordPress, зарегистрированными со следующими псевдонимами:
- posts
- postmeta
- users
- usermeta
- comments
- commentmeta
Выше мы рассмотрели теоретические основы подключения произвольной таблицы к RCL REST API, предлагаю далее продолжить рассмотрение с привлечением более знакомой таблицы WordPress - wp_posts.
В данному случае, важно помнить, что RCL REST API к стандартным таблицам WP также строит запросы через класс Rcl_Query, а не WP_Query, это следует учитывать при построении своих запросов.
Сделаем базовый запрос к таблице wp_posts для получения текущей схемы таблицы:
http://domen.com/rcl_api/get/posts/
Получим 5 последних записей типа post с любым статусом:
http://domen.com/rcl_api/get/posts/?post_type=post&number=5
Передаваемые аргументы соответствуют массиву:
array( 'post_type' => 'post', 'number' => 5 );
Получим 10 опубликованных записей типа task пользователя с ID 1:
http://domen.com/rcl_api/get/posts/?post_type=task&post_status=publish&post_author=25&number=10
Передаваемые аргументы соответствуют массиву:
array( 'post_type' => 'task', 'post_status' => 'publish', 'post_author' => 25, 'number' => 10 );
Тот же запрос, но получим только заголовки и контент:
http://domen.com/rcl_api/get/posts/?post_type=task&post_status=publish&post_author=25&fields[]=post_title&fields[]=post_content&number=5
Передаваемые аргументы соответствуют массиву:
array( 'post_type' => 'task', 'post_status' => 'publish', 'post_author' => 25, 'fields' => array( 'post_title', 'post_content' ) 'number' => 10 );
Как можно заметить, чем сложнее запрос тем длиннее получается URL-строка запроса. Составлять ее вручную можно, но не очень удобно, а при сложных запросах, с множеством вложенных массивов, почти невозможно, поэтому составление URL-строки с нужным набором аргументов лучше назначить специальным функциям. Например, для отправки запроса с внешнего WordPress сайта можно использовать функцию wp_remote_get, через нее последний запрос можно отправить так:
$response = wp_remote_get('http://domen.com/rcl_api/get/posts/',array( 'body' => array( 'post_type' => 'task', 'post_status' => 'publish', 'post_author' => 25, 'fields' => array( 'post_title', 'post_content' ) 'number' => 10 ) ));
Множественный запрос
Мы рассмотрели порядок формирования запросов через RCL REST API к отдельным таблицам, но на практике нам может потребоваться получать данные из нескольких таблиц одновременно, например, получить не связанные между собой данные публикаций и пользователей. Для этого мы можем сформировать два отдельных запроса, но RCL REST API позволяет объединять несколько запросов в один, давайте рассмотрим пример такой реализации.
Аргументы множественного запроса следует отправлять по адресу:
http://domen.com/rcl_api/get/multiple/
А сам массив передаваемых аргументов следует строить по шаблону:
array( array( 'table' => 'tablename1', 'args' => array( //массив аргументов //запроса к таблице tablename1 ) ), array( 'table' => 'tablename2', 'args' => array( //массив аргументов //запроса к таблице tablename2 ) ), ... )
Например, в данному запросе мы запрашиваем данные из двух таблиц:
$response = wp_remote_get('http://domen.com/rcl_api/get/multiple/',array( 'body' => array( array( 'table' => 'posts', 'args' => array( 'post_type' => 'post', 'post_author__in' => array(10,25), 'post_status' => 'publish', 'number' => 5 ) ), array( 'table' => 'users', 'args' => array( 'ID' => 1, 'fields' => array( 'display_name', 'user_registered' ) ) ) ) ));
Возвращенный массив result с результатами выборки тоже будет содержать два массива, первый - с данными из таблицы posts, второй - из таблицы users. Для удобства каждому массиву аргументов можно вручную назначить произвольный ключ, по которому затем было бы удобно искать нужный массив результатов внутри массива result, например:
$response = wp_remote_get('http://domen.com/rcl_api/get/multiple/',array( 'body' => array( 'posts-data' => array( 'table' => 'posts', 'args' => array( //тут аргументы запроса ) ), 'users-data' => array( 'table' => 'users', 'args' => array( //тут аргументы запроса ) ) ) ));
Тогда результат выборки из таблицы posts можно будет получить через $response['result']['posts-data'], а из таблицы users через $response['result']['users-data'].
Советы разработчику
Каждый разработчик решивший открыть свой сервер для запросов из внешнего мира должен контролировать использование возможностей API.
Во-первых, следует определиться с перечнем таблиц к которым можно будет отправлять запросы. Сделать это можно либо через уже упоминавшийся ранее фильтр 'rcl_rest_tables', либо вручную, открыв файл index.php дополнения и исключив таблицы или вписав новые в массив:
$tables = apply_filters('rcl_rest_tables', array( 'posts' => 'WPPosts', 'postmeta' => 'WPPostmeta', 'comments' => 'WPComments', 'commentmeta' => 'WPCommentmeta', 'users' => 'WPUsers', 'usermeta' => 'WPUsermeta' ));
Во-вторых, следует озаботиться порядком доступа к API. Если вы не собираетесь отдавать запрашиваемые данные всем кто пришлет запрос на их получение, то имеет смысл ввести ограничения на доступ по IP. Сделать это можно используя экшн 'rcl_rest_pre_request', внутри него можно проверить IP текущего запроса и если он не входит в число разрешенных к доступу, то прерывать выполнение скрипта через die; или exit;
В заключении
Не стоит рассматривать RCL REST API как какой то "велосипед" призванный заменить собой API WordPress, это лишь использование уже существующих широких возможностей плагина WP-Recall, обернутых в другую оболочку.
Возможности RCL REST API, на данный момент, не раскрыты полностью, имеют определенные ограничения и предлагают лишь базовый функционал. Пока можно строить запросы лишь на получение данных, запись новых значений в БД или их обновление не реализованы. Нет каких то настроек и изменение API предполагает работу с его кодом. Но я надеюсь, что применение RCL REST API в реальных проектах, а также замечания от заинтересованных разработчиков помогут развить возможности API, а применение возможностей плагина WP-Recall под таким соусом будет кому то полезно.
Я как раз недавно пытался выводить посты используя API WP и все ок, использовал и разбирался по примерам найденным. Появилась мысль как раз о упомянутом Андреем в статье мобильном приложении, новости/статьи и комменты к ним.
Если я установлю, сутки станут 36 часов? Не хватает 24 🙂
Буду разбираться и спасибо как всегда за столь современные функции и своевременные.
ну работа с таблицей posts была приведена лишь для более наглядного и знакомого для многих примера, а вообще данное API было создано для работы с многочисленными таблицами плагина и его дополнений, а значит с абсолютно любыми таблицами, а API WP такого не может.
Я не про пример в статье имел ввиду, просто я как раз начал разбираться на примере вывода статей используя WP. Но там достаточно все прямолинейно что ли, вывел и все. дальше уже вроде как и нельзя добавить те же обсуждения по простому так сказать. Получается какие то монстры судя потому что я видел.
Но теперь есть гораздо более гибкое решение сделанное тобой, с которым буду далее уже разбираться и в контексте использования для мобильного приложения. Тема приложения актуальна сейчас как никогда, да и мне интересна)
Ну, если возникнут проблемы или вопросы, то как обычно, ждем на форуме, тема актуальна и описание опыта использования будет полезно для других
После активации дополнения, обязательно пересохранить настройки постоянных ссылок!
Я вот давно читал про весь этот REST и толком не понял. Что в нем такого реально крутого, ведь как я понимаю все то же самое можно реализовать через функции и jquery. Это типо просто "удобнее"?
А еще я кучу раз гуглил реальные примеры того что сделали люди на REST API и ничего не нашел, все только пишут "Боже это революционно", но существует это API уже не первый год, а рабочих и интересных применений так и не находится.
видимо ты просто не понял предназначение такого API, использовать его можно только при необходимости, например, для вывода публикаций или комментариев с сайта в мобильное приложение, люди просто берут и делают, показывать что получилось им может и не к чему.
Ну попробуй, а мы оценим)
Ну вот я только это и находил: мобильные приложения и еще люди пишут что можно "Свою" админку wordpress сделать.
Но если мне нужно в мобильном приложении выводить посты, то ведь я могу сделать, например, в корне сайта файл mobile.php где буду через GET/POST принимать кол-во постов, категорию, метки и возвращать посты, разве нет?
Единственное на REST API получается я могу сделать приложение, которое будет работать с любым сайтом, т.к. REST API стандартизировано везде, но опять же я хз, пока не видел живых примеров где применяют REST API
Можешь, но преимущество API в стандартизированном подходе, понятном любому другому разработчику, да и зачем пилить свой велосипед, если уже есть готовое API, которые ты можешь просто брать и использовать.
Примеры есть и крутые, вообще целиком версии сайтов типо washington post и еще масса из крутых. Но пока я для себя вижу только в мобильном сегменте, вот там это удобно. Насколько я себе это вижу, упрощается в принципе само приложение.
Кстати вот как то мне скинули рабочий пример для андроид simplifiedcoding.net/wordpress-to-android-app-tutorial
Конечно можно в принципе идти и по пути развития для своего сайта PWA приложения для сайта, но что то пока не вижу в них прогресса как гугл не пиарил, серьезного применения пока не вижу. Но конечно проще PWA, да и не нужны оф магазины приложений.
Для мобильных приложений - раз
Для создания своего Api на базе ВП - два
Про приложения то и говорить нечего - все и так понятно. А вот для своего API - например твой сайт второй IMDB и имеет большую базу рейтинга. Чтобы поделиться с окружающим миром rest-api - один из вариантов формата отдачи. Можно конечно как кинопоиск сделать и что-то отдавать через xml.
Можно через него сделать свой сервис. Dusqus например. js-ом обращаешься к серверу на ВП - и отдаешь json комментариев. Кто-то скажет - "вот ты извращенец. Такое на ВП делать". Просто навскидку придумал варианты использования.
По поводу своей админки- зачем для своего же сайта использовать rest? Он больше для кроссдоменного использования ну или удаленного.
Но меня напрягает что по запросу wp rest api example ничего нет, только базовые уроки как с ним работать. Хотя находятся записи еще 2015 года где пишут "Рест апи набирает огромную популярность бла бла бла" - неужели с тех пор никто никаких приложений на нем не сделал? Почему в интернете нет реальных примеров использования, а только возгласы что это нереально круто, которым уже несколько лет?
Я выше ссылочку дал на готовый пример и ребята говорят рабочий, за исключения медяшки туда не добавлены.
https://premium.wpmudev.org/blog/using-wordpress-rest-api/ параграф Companies Using The REST API Right Now
Почему об этом мало кто пишет и рассказывает? Рассказывают. Но это бизнес - в частности мобильные приложения - и плодить конкурентов никто не хочет. Поэтому информация закрыта.
А читать надо про rest api в отрыве от wordpress - тогда случаи реального применения увидишь. Надо забыть про фронтенд и рассматривать просто как способ получения данных из бд
Можно много чего придумать, например, я могу подключить на этом сайте таблицу с данными созданных рекламных кампаний и создать дополнение, которые при установке на стороннем сайте будет дергать эти данные с моего сервака через REST API и крутить рекламу товаров уже там. Все ограничено фантазией.
Но ты мог это и без REST API сделать. Вообщем я хз, меня больше интересуют развлекательные сайты и я не могу придумать применение этого апи для них (не конкретной твоей версии а в целом rest api)
Посмотрим что ты выпустишь или кто-то другой с этим АПИ, может до меня тогда что-то дойдет и я пойму всю его прелесть )
Здравствуйте. Актуально ли ещё дополнение в нынешних реалиях. Я имею в виду что плагин перешёл на Rcl_Query2.
Если да то возможны ли составные запросы?
Например получить данные записей только определеной категории или с определённым мета полем одним запросом.
Добрый день, к сожалению, никак не развивал данное дополнение со времен первой версии Rcl_Query, хотя она и поддерживается до сих пор и на ее основе можно строить запросы внутри этого дополнения, поэтому можно попробовать строить запросы с включением массива join_query по старому варианту.
Спасибо.