register_rest_route()
Регистрирует маршрут REST API и его эндпоинты (конечные точки). Говоря проще регистрирует URL по которому будет срабатывать указанная PHP функция.
Функцию нужно вызывать на хуке rest_api_init.
C версии WP 5.5.0 параметр permission_callback
стал обязательным! Если его не указать, то вы получите следующее уведомление в debug.log:
PHP Notice: register_rest_route was called incorrectly. В регистрации маршрута REST API для /foo
отсутствует обязательный аргумент permission_callback
. Для публичных маршрутов REST API, используйте __return_true
в качестве коллбэк функции.
Подробнее читайте здесь: https://developer.wordpress.org/rest-api/extending-the-rest-api/routes-and-endpoints/#permissions-callback.
Читайте также: Учебник по WordPress REST API.
Хуков нет.
Возвращает
true|false
. True в случае успеха и false при ошибке.
Шаблон использования
add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/my_slug/(?P<param_name>.+)', array( 'methods' => 'GET', // метод запроса: GET, POST ... 'callback' => 'function_name', // функция обработки запроса. Должна вернуть ответ на запрос 'permission_callback' => 'function_name', // функция проверки доступа к маршруту. Должна вернуть true/false // описание передаваемых параметров 'args' => array( 'param_name' => array( 'default' => null, // значение параметра по умолчанию 'required' => null, // является ли параметр обязательным. Может быть только true 'validate_callback' => 'function_name', // функция проверки значения параметра. Должна вернуть true/false 'sanitize_callback' => 'function_name', // функция очистки значения параметра. Должна вернуть очищенное значение ), 'param_name2' => array( ... ) ... ), ) ); } );
Использование
register_rest_route( $namespace, $route, $args, $override );
- $namespace(строка) (обязательный)
- Первая часть маршрута (URL), которая идет после REST префикса (/wp-json/). Должна быть уникальной, обычно тут используется уникальное название вашего плагина или темы, например
myplugin/v1
. Подробнее смотрите пространства имен в REST. - $route(строка) (обязательный)
- Вторая часть маршрута (URL). Поддерживает регулярные выражения, к примеру
/author/(?P<id>\d+)
. - $args(массив)
Массив параметров для конечной точки.
С помощью этих параметров можно тонко настроить обработку запроса конечной точки.Если нужно создать несколько конечных точек, то массив должен содержать вложенные массивы, в которых описывается каждая конечная точка.
Массив для одной конечной точки по умолчанию выглядит так:
$args = [ 'methods' => 'GET', 'callback' => null, 'permission_callback' => null, 'args' => array(), ];
Пример как можно указать несколько конечных точек (методов):
$args = [ // common args 'args' => [ 'id' => [ 'description' => __( 'Unique identifier for the term.' ), 'type' => 'integer', ], ], // GET [ 'methods' => 'GET', 'callback' => null, 'permission_callback' => null, 'args' => [], ], // POST [ 'methods' => 'POST', 'callback' => null, 'permission_callback' => null, 'args' => [], ], ]
Описание всех возможных аргументов смотрите ниже.
Созданный тут массив, как есть попадают в свойство объекта WP_REST_Server::$endpoints.
- $override(логический)
Определяет нужно ли переписать данные, если такой маршрут уже существует:
- true - переопределить
- false - объединить с помощью функции array_merge().
По умолчанию: false
Аргументы параметра $args
- methods(строка/массив)
Определяет по какому методу запроса, будет доступна конечная точка: GET (по умолчанию), POST, PUT, PATCH, DELETE. Несколько методов можно указать строкой через запятую или массивом.
Можно использовать предопределенные константы класса WP_REST_Server:
WP_REST_Server::READABLE // GET WP_REST_Server::CREATABLE // POST WP_REST_Server::EDITABLE // POST, PUT, PATCH WP_REST_Server::DELETABLE // DELETE WP_REST_Server::ALLMETHODS // GET, POST, PUT, PATCH, DELETE
- callback(коллбэк функция)
Здесь указывается имя функции, которая будет срабатывать при переходе (запросе) на URL (rest маршрут). В функции нужно сформировать и вернуть данные. Возвращаемые данные будут преобразованы в json формат и выведены на экран.
В этом параметре, например, можно использовать свою функцию или любую другую, которая возвращает результат, например get_posts().
Функция указанная в этом параметре в качестве параметра получает объект класса WP_REST_Request, в нём содержатся параметры запроса и благодаря им можно сформировать точный ответ. К примеру, если просто вызвать get_posts(), то она вернет результат согласно её дефолтным настройкам, но если её обернуть в свою функцию и передать в вызов get_posts() полученный параметр ID автора, то можно отфильтровать посты по автору (смотрите первый пример).
Так как в функцию передаётся объект класса WP_REST_Request, то нам доступны методы для получения различной информации:
// Регистрирует маршрут add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array( 'methods' => 'GET', 'callback' => 'my_rest_api_func', ) ); } ); // Обратимся по адресу http://wp-test.ru/wp-json/myplugin/v1/author/1 function my_rest_api_func( WP_REST_Request $request ) { // Можно получить доступ к параметрам через прямой доступ к массиву объекта: $param = $request['id']; // 1 // Или с помощью метода: $param = $request->get_param( 'id' ); // 1 // Массив из всех параметров $parameters = $request->get_params(); // Array([id] => 1) // При необходимости также доступны отдельные параметры параметров: $parameters = $request->get_url_params(); // Array([id] => 1) $parameters = $request->get_query_params(); // Array() // Если запросить http://wp-test.ru/wp-json/myplugin/v1/author/1?post=1 $parameters = $request->get_query_params(); // Array( [post] => 1 ) $parameters = $request->get_body_params(); // Array() $parameters = $request->get_json_params(); // null - не было запроса с заголовком Content-type: application/json $parameters = $request->get_default_params(); // Array() // Данные о загрузках не объединены, но могут быть доступны отдельно: $parameters = $request->get_file_params(); // варианты возврата данных return new WP_REST_Response( true, 200 ); return new WP_Error( 'no_author', 'Invalid author', array( 'status' => 404 ) ); return 'строка'; return array( 'foo'=>'bar' ); // получим объект WP_REST_Response $response = rest_ensure_response( array( 'foo'=>'bar' ) ); $response->set_status( 401 ); $response->set_headers( [ 'X_REAL_IP' => '54.15.124.126', ] ); return $response; }
- permission_callback(коллбэк функция) (обязательный)
Позволяет проверить права пользователя, который запрашивает маршрут. Доступ будет разрешен, если вернуть true, и запрещен, если false.
С версии WordPress 5.5 данную функцию нужно указывать обязательно!
Пример, как разрешить доступ всем пользователям:
register_rest_route( 'myplugin/v1', '/awesome-route', array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_awesome_func', 'permission_callback' => '__return_true' ) );
Пример, как проверить возможности пользователя:
register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_awesome_func', 'permission_callback' => 'my_awesome_permission_callback' ) ); function my_awesome_permission_callback ( WP_REST_Request $request ) { return current_user_can( 'edit_others_posts' ); }
Пусть функция my_awesome_func() возвращает посты указанного пользователя. Если пользователь имеет право изменять чужие посты (к примеру, редактор), то нужные данные вернуться. Если же таких прав у текущего пользователя нет, то вернется ошибка:
{ "code": "rest_forbidden", "message": "Извините, вам не разрешено выполнять данное действие.", "data": { "status": 401 } }
Такая же ошибка вернётся, если не передать nonce, подробнее читайте в разделе Авторизация в WP REST API.
- show_in_index(true/false)
- Нужно ли показывать роут в схеме всех роутов.
- args(массив)
Возможные параметры эндпоинта. Каждый элемент массива описывает один параметр. Ключ элемента это название параметра запроса, а значение это вложенный массив описывающий этот параметр.
Некоторые данные параметра автоматически попадают в схему маршрута (например description, type, required ...). См. rest_get_allowed_schema_keywords().
Возможные аргументы массива:
description default required sanitize_callback validate_callback // проверка и очистка type string minLength / maxLength pattern format null boolean number / integer minimum / maximum exclusiveMinimum / exclusiveMaximum multipleOf array items minItems / maxItems uniqueItems object properties additionalProperties patternProperties minProperties / maxProperties enum oneOf / anyOf
Типы данных REST. Проверка и очистка — тут смотрите полный список возможных параметров и их описание.
-
default(разное) (попадает в схему)
Значение по умолчанию для аргумента, если он не указан.register_rest_route( 'myplugin/v1', '/author/(?P<key>\d+)', array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_awesome_func', 'args' => array( 'key' => array( 'default' => 1 ), ), ) );
-
required(true/false) (попадает в схему)
Если в значении указать true и указанный параметр не будет определен (не будет указан в запроса), то будет возвращена ошибка.Параметр в запросе не должен быть указан вообще, чтобы сработала эта настройка, т.е. если он указан, но в значении его пусто, то считается что он указан с пустым значением.
required не имеет смысла, если установлен параметр default, поскольку аргумент всегда будет иметь значение.
register_rest_route( 'myplugin/v1', '/author/(?P<key>\d+)', array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_awesome_func', 'args' => array( 'key' => array( 'required' => false // или true - обязательный параметр ), ), ) );
-
validate_callback(строка/callback)
Функция проверки данных. Функция должна возвращать true, если проверка прошла, и false в противном случае.Функция также может вернуть объект WP_Error, тогда сообщение будет добавлено в объект ответа. Например, если вернуть такой объект:
new WP_Error( 'err', 'Must match `^[a-zA-Z0-9:_-]+$` regex.' )
То в ответе получим:
{ "code": "rest_invalid_param", "message": "Неверный параметр: name", "data": { "status": 400, "params": { "name": "Must match `^[a-zA-Z0-9:_-]+$` regex." }, "details": { "name": { "code": "err", "message": "Must match `^[a-zA-Z0-9:_-]+$` regex.", "data": null } } } }
Пусть функция my_awesome_func() возвращает список постов указанного автора, тогда:
register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', [ 'methods' => 'GET', 'callback' => 'my_awesome_func', 'args' => [ 'id' => [ 'validate_callback' => function( $param, $request, $key ) { return is_numeric( $param ); }, ], ], ] );
Запросим записи автора с ID = 1 по адресу (предполагаем, что записи есть):
http://wp-test.ru/wp-json/myplugin/v1/author/1
Вернется массив с записями. Но если обратится по адресу:
http://wp-test.ru/wp-json/myplugin/v1/author/vasya
То вернется ошибка:
{ "code": "rest_no_route", "message": "Подходящий маршрут для URL и метода запроса не найден", "data": { "status": 404 } }
Потому что параметр id не прошёл проверку функций is_numeric(), так как значение vasya не является числом.
Казалось бы, почему просто не указать функцию is_numeric() вот так:
register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_awesome_func', 'args' => array( 'id' => array( 'validate_callback' => 'is_numeric' ), ), ) );
Но, как можно заметить из примера выше, в указанную функцию будут переданы три параметра $param, $request, $key и, если всех их передать функции is_numeric() - будет ошибка уровня
warning
.[29-May-2018 12:07:54 UTC] PHP Warning: is_numeric() expects exactly 1 parameter, 3 given in \sites\example.com\wp-includes\rest-api\class-wp-rest-request.php on line 858
Есть тикет, по этой теме.
-
sanitize_callback(строка/callback)
Функция очистки данных. Аналогична validate_callback, только вместо true/false нужно возвратить очищенное входящее значение. Или можно вернуть WP_Error объект.register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array( 'methods' => WP_REST_Server::READABLE, 'callback' => 'my_awesome_func', 'args' => array( 'id' => array( 'sanitize_callback' => function ( $param, $request, $key ) { return (int) $param; } ), ), ) );
-
type(строка) (попадает в схему)
Тип значения параметра. Возможные значения:array
,object
,string
,number
,integer
,boolean
,null
. Если указан другой тип, то в ответ выдаст ошибку 400. Подробнее про этот параметр. -
minimum / maximum(число) (используется в схеме)
Минимальное или Максимальное значение параметра. Только для type = integer. -
format(строка) (используется в схеме)
Дополнительный формат строки. Значения будут проверятся на соответствие указанному формату. Подробнее.date-time
— дата в формате RFC3339. см. rest_parse_date()uri
— uri в соответствии с esc_url_raw().email
— См. is_email().ip
— v4 или v6 ip адрес. См. rest_is_ip_address()uuid
— uuid код любой версии. См. wp_is_uuid()hex-color
— 3 или 6 символов hex цвета в префиксом#
. См. rest_parse_hex_color().
-
enum(массив) (используется в схеме)
Список возможных значения параметра (когда у параметра ограниченный список возможных значений).
Примеры
#1 Получение записей указанного автора
В WordPress для этой цели есть дефолтные методы, но давайте для примера создадим свой простой вариант:
// Регистрирует маршрут add_action( 'rest_api_init', function () { register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array( 'methods' => 'GET', 'callback' => 'my_awesome_func', 'permission_callback' => '__return_true' ) ); } ); // Обрабатывает запрос function my_awesome_func( WP_REST_Request $request ) { $posts = get_posts( array( 'author' => (int) $request['id'], ) ); if ( empty( $posts ) ) return new WP_Error( 'no_author_posts', 'Записей не найдено', array( 'status' => 404 ) ); return $posts; }
Теперь получим записи автора с ID = 1 с помощью GET запроса по адресу:
http://wp-test.ru/wp-json/myplugin/v1/author/1
Получим ответ в формате json, если записи нашлись:
[ { "ID": 280, "post_author": "1", "post_date": "2018-04-10 21:06:29", "post_date_gmt": "2018-04-10 18:06:29", "post_content": "Привет! Эта статья должна стать исключением.\r\n\r\n[smr_slider id='1']", "post_title": "Ещё статья", "post_excerpt": "", "post_status": "publish", "comment_status": "open", "ping_status": "open", "post_password": "", "post_name": "eshhyo-statya", "to_ping": "", "pinged": "", "post_modified": "2018-05-25 11:34:03", "post_modified_gmt": "2018-05-25 08:34:03", "post_content_filtered": "", "post_parent": 0, "guid": "http://wp-test.ru/?p=280", "menu_order": 0, "post_type": "post", "post_mime_type": "", "comment_count": "0", "filter": "raw" }, { "ID": 273, ... } ... ]
Получим ответ в формате json, если записей у автора нет:
{ "code": "no_author_posts", "message": "Записей не найдено", "data": { "status": 404 } }
Можно доработать функцию, чтобы получать только нужные нам значения:
// Обрабатываем запрос function my_awesome_func( WP_REST_Request $request ) { // Получим записи указанного автора $posts = get_posts( array( 'author' => (int) $request['id'], ) ); if( empty( $posts ) ) return new WP_Error( 'no_author_posts', 'Записей не найдено', array( 'status' => 404 ) ); // Создадим свои данные для возврата $posts = array_map( function ( $post ) { $post_data['title'] = esc_html( $post->post_title ); $post_data['url'] = esc_url( get_the_permalink( $post ) ); $post_data['comments'] = (int) $post->comment_count; $post_data['likes'] = (int) get_post_meta( $post->ID, 'likes', true ); return $post_data; }, $posts ); return $posts; }
Если записи есть, получим ответ:
[ { "title": "Ещё статья", "url": "http://wp-test.ru/eshhyo-statya", "comments": 3, "likes": 11 }, { "title": "Моя статья", ... }, ... ]
#2 Еще примеры
Смотрите в Учебнике REST API в разделе Создание маршрутов. Там например, вы найдете, пример создания маршрутов на основе Класса контроллера (ООП).
Список изменений
С версии 4.4.0 | Введена. |
С версии 5.1.0 | Added a _doing_it_wrong() notice when not called on or after the rest_api_init |
С версии 5.5.0 | Added a _doing_it_wrong() notice when the required permission_callback argument is not set. |