Бесплатно В корзину

В наше неспокойное время любой разработчик или владелец сайта может столкнуться с необходимостью разработки 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 под таким соусом будет кому то полезно.

5
Условия поддержки: на форуме в рамках текущего функционала
Контактные данные: support@codeseller.ru
Авторство: Товар опубликован его непосредственным автором
Форум поддержки : При возникновении проблемы, создайте соответствующую тему на форуме поддержки товара
Бесплатно В корзину
Помните! Данный продукт защищён авторским правом, его нарушение влечёт за собой административную и уголовную ответственность.

Автор публикации

не в сети 6 часов

Андрей CS

12K
Комментарии: 2747Публикации: 482Регистрация: 30-11--0001Продаж/Покупок: 46586/181