WordPress как на ладони
WordPress темы и плагины за 250 рублей wordpress jino

register_rest_route() WP 4.4.0

Регистрирует конечную точку REST API - URL по которому будет срабатывать нужная функция.

Функцию нужно вызывать на хуке rest_api_init.

Во время REST запроса функции авторизации вроде is_user_logged_in() по умолчанию не работают. подробнее читайте здесь.

Хуков нет.

Возвращает

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 префикса. Должна быть уникальной, обычно тут используется уникальное название вашего плагина или темы, например myplugin/v1.
$route(строка) (обязательный)
Вторая часть URL. Поддерживает регулярные выражения, к примеру /author/(?P<id>\d+).
$args(массив)

Массив параметров для конечной точки. Массив может содержать вложенные массивы для нескольких методов. По умолчанию пустой массив, который превращается в дефолтный:

array(
	'methods'  => 'GET',
	'callback' => null,
	'args'     => array(),
);

Описание всех параметров смотрите ниже.

$override(логический)

Определяет нужно ли переписать данные, если маршрут уже существует:

  • true - переопределить
  • false - объединить с помощью функции array_merge().

По умолчанию: false

Аргументы параметра $args

С помощью передачи параметров в массиве $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' );
}
permission_callback

Позволяет проверить права пользователя, который запрашивает маршрут. Доступ будет разрешен, если вернуть true, и запрещен, если false.

register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array(
	'methods'             => WP_REST_Server::READABLE,
	'callback'            => 'my_awesome_func',
	'permission_callback' => function ( WP_REST_Request $request ) {
		return current_user_can( 'edit_others_posts' );
	}
) );

Пусть функция my_awesome_func() возвращает посты указанного пользователя. Если пользователь имеет право изменять чужие посты (к примеру, редактор), то нужные данные вернуться. Если же таких прав у текущего пользователя нет, то вернется ошибка:

{
	"code": "rest_forbidden",
	"message": "Извините, вам не разрешено выполнять данное действие.",
		"data": {
		"status": 401
	}
}
args

Дополнительные параметры, позволяющие упростить работу с входящими данными. $args представляет собой массив, со следующими возможными параметрами:

  • 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 и указанный параметр не будет определен (не будет указан в запроса), то будет возвращена ошибка.

    Параметр в запросе не должен быть указан вообще, чтобы сработала эта настройка, т.е. если он указан, но в значении его пусто, то считается что он указан с пустым значением.

    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
    Функция проверки данных. Функция должна возвращать true, если проверка прошла, и false в противном случае.

    Пусть функция my_awesome_func() возвращает список постов указанного автора, тогда:

    register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array(
    	'methods' => 'GET',
    	'callback' => 'my_awesome_func',
    	'args' => array(
    		'id' => array(
    			'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 D:\server72\sites\wp-test.ru\wp-includes\rest-api\class-wp-rest-request.php on line 858

    Есть тикет, призывающий это исправить, но пока дело стоит на месте.

  • sanitize_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;
    			}
    		),
    	),
    ) );
    

Примеры

#1 Получение записей указанного автора

В WordPress для этой цели есть дефолтные методы, но если вам нужно получить похожий, но собественный вариант - этот код поможет.

// Регистрирует маршрут
add_action( 'rest_api_init', function () {
	register_rest_route( 'myplugin/v1', '/author/(?P<id>\d+)', array(
		'methods'  => 'GET',
		'callback' => 'my_awesome_func',
	) );
} );

// Обрабатывает запрос
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', 'Invalid author', 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",
	"message": "Invalid author",
	"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', 'Invalid author', 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": "Моя статья",
		...
	},
	...
]

Код register rest route: wp-includes/rest-api.php VER 4.9.6

<?php
function register_rest_route( $namespace, $route, $args = array(), $override = false ) {
	if ( empty( $namespace ) ) {
		/*
		 * Non-namespaced routes are not allowed, with the exception of the main
		 * and namespace indexes. If you really need to register a
		 * non-namespaced route, call `WP_REST_Server::register_route` directly.
		 */
		_doing_it_wrong( 'register_rest_route', __( 'Routes must be namespaced with plugin or theme name and version.' ), '4.4.0' );
		return false;
	} else if ( empty( $route ) ) {
		_doing_it_wrong( 'register_rest_route', __( 'Route must be specified.' ), '4.4.0' );
		return false;
	}

	if ( isset( $args['args'] ) ) {
		$common_args = $args['args'];
		unset( $args['args'] );
	} else {
		$common_args = array();
	}

	if ( isset( $args['callback'] ) ) {
		// Upgrade a single set to multiple.
		$args = array( $args );
	}

	$defaults = array(
		'methods'         => 'GET',
		'callback'        => null,
		'args'            => array(),
	);
	foreach ( $args as $key => &$arg_group ) {
		if ( ! is_numeric( $key ) ) {
			// Route option, skip here.
			continue;
		}

		$arg_group = array_merge( $defaults, $arg_group );
		$arg_group['args'] = array_merge( $common_args, $arg_group['args'] );
	}

	$full_route = '/' . trim( $namespace, '/' ) . '/' . trim( $route, '/' );
	rest_get_server()->register_route( $namespace, $full_route, $args, $override );
	return true;
}

Cвязанные функции

Из метки: REST API

campusboy 2798youtube.com/c/wpplus
Активный пользователь wp-kama.ru. WordPress-разработчик. Разработка сайтов и лендингов. Доработка существующих проектов. Сопровождение ресурсов.
Комментариев нет
    Здравствуйте, !     Войти . Зарегистрироваться