Типи параметрів REST. Перевірка та очищення

З версії 5.2 WordPress в ядро ​​вбудовано перевірку та очищення параметрів, що передаються в маршрути REST API (валідатор параметрів певних типів). Така перевірка ґрунтується на специфікації JSON Schema Version 4 . У цій статті будуть розглянуті основи JSON схеми, які використовуються в WordPress для перевірки та очищення (validate та sanitize).

Читайте пов’язане:

Наведені нижче типи параметрів вказуються під час реєстрації маршруту та його ендпоінтів у функції register_rest_route() .

Розглянемо приклад, у якому видно як і де вказуються параметри ендпоінта про які нижче йтиметься:

$endpoints = [
	[
		'methods' => 'GET',
		'callback' => [ $this, 'get_items' ],
		'permission_callback' => [ $this, 'get_items_permissions_check' ],
		'args' => [
			// string
			'context' => [
				'description' => __( 'Scope under which the request is made; determines fields present in response.' ),
				'type' => 'string',
				'sanitize_callback' => 'sanitize_key',
				'validate_callback' => 'rest_validate_request_arg',
			],
			// integer
			'per_page' => [
				'description' => __( 'Maximum number of items to be returned in result set.' ),
				'type' => 'integer',
				'default' => 10,
				'minimum' => 1,
				'maximum' => 100,
				'sanitize_callback' => 'absint',
				'validate_callback' => 'rest_validate_request_arg',
			],
			// array
			'author' => [
				'description' => __( 'Limit result set to posts assigned to specific authors.' ),
				'type' => 'array',
				'items' => [
					'type' => 'integer',
				],
				'default' => [],
			],
			// string enum
			'order' => [
				'description' => __( 'Order sort attribute ascending or descending.' ),
				'type' => 'string',
				'default' => 'desc',
				'enum' => [ 'asc', 'desc' ],
			],
			// string pattern
			'slug' => [
				'type' => 'string',
				'required' => true,
				'description' => __( 'WordPress.org plugin directory slug.' ),
				'pattern' => '[w-]+',
			],

		],
	]
];

register_rest_route( 'namespace', '/rest_base', $endpoints );




type

У JSON схемі доступні наступні сім примітивних типів :

  • string – строкове значення.
  • null – значення null.
  • number – Будь-яке число. Еквівалент float в PHP.
  • integer – ціле число. float не допускається.
  • boolean – значення true/false.
  • array – Список значень. Еквівалент масиву JavaScript. PHP відповідає масиву з числами в ключах або масиву без зазначених ключів.
  • object – Пари ключ => значение. Еквівалент об’єкта JavaScript. У PHP відповідає асоціативному масиву (масиву з ключами).

Примітивний тип вказується typeелементі масиву. Наприклад:

array(
	'type' => 'string',
);

JSON схема дозволяє вказати відразу кілька типів:

array(
	'type' => [ 'boolean', 'string' ],
);




Перетворення типів

REST API WordPress приймає дані у GET або POST запиті, тому дані потрібно перетворити. Наприклад, деякі строкові значення потрібно перетворити на їх реальні типи.

  • string – цей тип має пройти перевірку is_string() .
  • null – значення має бути реальним null. Це означає, що надсилання null значення в URL-адресі або у вигляді закодованого у формі URL тіла повідомлення неможливе, необхідно використовувати тіло запиту JSON.
  • number – Число або рядок, яка пройде перевірку is_numeric() . Значення буде перетворено на (float) .
  • integer – Цілі числа або рядки без дробової частини. Значення буде перетворено на (int) .
  • boolean – Логічні true / false. Числа або рядки 0, 1, '0', '1', 'false', 'true'. 0 це false . 1 це true .
  • array — Індексний масив, що відповідає wp_is_numeric_array() або рядок. Якщо передано рядок, то значення розділені комами стануть значеннями елементів масиву. Якщо ком у рядку немає, то значення стане першим елементом масиву. Наприклад: 'red, yellow'перетвориться на array( 'red', 'yellow' ), а 'blue'стане array( 'blue' ).
  • object — Масив, об’єкт stdClass , об’єкт, що використовується JsonSerializable або порожній рядок. Значення будуть перетворені на PHP масив.

При використанні кількох типів типи будуть оброблятися в зазначеному порядку. Це може вплинути на результат очищення. Наприклад для 'type' => [ 'boolean', 'string' ]надісланого значення ‘1’ перетворитися на логічне true . Однак, якщо змінити порядок, значення буде рядок '1'.

Специфікація JSON схеми дозволяє визначати схеми без поля type. Але в WordPress цей параметр повинен бути вказаний, інакше ви отримаєте _doing_it_wrong() .




string

Вказує на те, що у значенні запиту має бути рядок. Додатковими параметрами нижче можна визначити, який саме рядок повинен передаватися у значенні параметра.




minLength / maxLength

Використовується для обмеження допустимої довжини рядка (включно). Важливо, що багатобайтові символи вважаються одним символом, а межі включаються до підрахунку.

Наприклад, для наступної схеми ab, abc, abcdпройдуть перевірку, а a и abcdeні.

array(
	'type' => 'string',
	'minLength' => 2,
	'maxLength' => 4,
);




format

Якщо вказати цей аргумент, значення параметра переданого в REST будуть перевіряться на відповідність зазначеному формату.

Можливі варіанти параметра:

  • 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() .

Приклад використання параметра format:

array(
	'type' => 'string',
	'format' => 'date-time',
);

Важливо: значення параметра має відповідати вказаному формату завжди, тому воно не може бути порожнім рядком. Якщо потрібно вказати порожній рядок, потрібно додати тип null.

Наприклад, наступна схема дозволить вказати IP (127.0.0.1) або не вказувати значення параметра:

array(
	'type' => [ 'string', 'null' ],
	'format' => 'ip',
);

Код із ядра, який показує як конкретно працює цей параметр:

// Це behavior matches rest_validate_value_from_schema().
if ( isset( $args['format'] )
	&& ( ! isset( $args['type'] ) || 'string' === $args['type'] || ! in_array( $args['type'], $allowed_types, true ) )
) {
	switch ( $args['format'] ) {
		case 'hex-color':
			return (string) sanitize_hex_color ($ value);

		case 'date-time':
			return sanitize_text_field( $value );

		case 'email':
			// sanitize_email() validates, which would be unexpected.
			return sanitize_text_field( $value );

		case 'uri':
			return esc_url_raw ($ value);

		case 'ip':
			return sanitize_text_field( $value );

		case 'uuid':
			return sanitize_text_field( $value );
	}
}

Зверніть увагу, що формат обробляється не обов’язково тільки тоді, коли type = string. format буде застосовуватись якщо:

  • type = string .
  • type відрізняється від стандартного примітивного типу .
  • type не вказано (але у WP це заборонено).




pattern

Використовується для перевірки відповідності значення рядкового параметра вказаного регулярного виразу.

Наприклад, для наступної схеми, #123підходить, а #abcні:

array(
	'type' => 'string',
	'pattern' => '#[0-9]+',
);

Модифікатори регулярних виразів не підтримуються, тобто. не можна вказати /i, щоб не залежати від регістру.

RFC схеми JSON рекомендує обмежитися такими функціями регулярних виразів, щоб схема була сумісна з якомога більшою кількістю різних мов програмування:

  • Дозволено окремі символи Юнікод відповідні JSON специфікації [RFC4627].
  • Проста група та діапазон символів: [abc]і [a-z].
  • Проста група і діапазон символів, що виключають: [^abc], [^a-z].
  • Прості квантифікатори: *(нуль або більше), +(один або більше), ?(один або нічого), та їх «ліниві» версії: +?, *?, ??.
  • Квантифікатори діапазону: {x}(x разів), {x,y}(від x до y разів), {x,}(x і більше разів), та їх «ліниві» версії.
  • Анкори початку та кінця рядка: ^, $.
  • Прості групи (...)та чергування |.

Шаблон повинен бути сумісним із діалектом регулярних виразів ECMA 262.




null

Значення має бути реальним null. Це означає, що надсилання null значення в URL-адресі або у вигляді закодованого у формі URL тіла повідомлення неможливе, необхідно використовувати тіло запиту JSON.




boolean

Логічні true/false. Можна запит можна вказати числа або рядки:

  • true – 1, '1', 'true'.
  • false – 0, '0', 'false'.

Докладніше про те, як обробляється передане значення, дивіться в коді функції: rest_sanitize_boolean() .




number/integer

Числа мають тип number(будь-яке число, може бути дробовим) або integer(тільки цілі числа):

if ( 'integer' === $args['type'] ) {
	return (int) $value;
}

if ( 'number' === $args['type'] ) {
	return (float) $ value;
}

Також для чисел є додаткові параметри перевірки.




minimum / maximum

Обмежує діапазон допустимих чисел (включаючи числа). Наприклад, 2підійде під схему нижче, а 0й 4– ні:

array(
	'type' => 'integer',
	'minimum' => 1,
	'maximum' => 3,
);




exclusiveMinimum / exclusiveMaximum

Це додаткові параметри для minimum / maximum , які відключають «включну» перевірку. Тобто. значення НЕ може дорівнювати певному мінімуму або максимуму, а повинно бути більше або менше, але не дорівнює.

Наприклад, у наступному випадку прийнятним значенням буде тільки 2:

array(
	'type' => 'integer',
	'minimum' => 1,
	'exclusiveMinimum' => true,
	'maximum' => 3,
	'exclusiveMaximum' => true,
);




multipleOf

Стверджує кратність числа, тобто. отримане значення має націло ділитися на вказане в цьому параметрі число.

Наприклад, наступна схема прийматиме лише парні цілі числа:

array(
	'type' => 'integer',
	'multipleOf' => 2,
);

Також є підтримка десяткових дробів. Наприклад, наступна схема може бути використана для прийому відсотка з максимальним значенням одна десята:

array(
	'type' => 'number',
	'minimum' => 0,
	'maximum' => 100,
	'multipleOf' => 0.1,
);




array

Вказує, що має бути переданий масив. Дивіться: rest_sanitize_array() .




items

Встановлює формат кожного елемента у масиві. Для цього потрібно використовувати параметр items, в якому потрібно вказати схему JSON кожного елемента масиву.

Наприклад, наступна схема вимагає масив IP-адрес:

array(
	'type' => 'array',
	'items' => array(
		'type' => 'string',
		'format' => 'ip',
	),
);

Для такої схеми ці дані пройдуть перевірку:

[ "127.0.0.1", "255.255.255.255" ]

А ці ні:

[ "127.0.0.1", 5]

Схема itemsможе бути будь-якою, у тому числі і схемою вкладеного масиву:

array(
	'type' => 'array',
	'items' => array(
		'type' => 'array',
		'items' => array(
			'type' => 'string',
			'format' => 'hex-color',
		),
	),
);

Для такої схеми ці дані пройдуть перевірку:

[
  [ "#ff6d69", "#fecc50" ],
  [ "#0be7fb" ]
]

А ці не пройдуть:

[
  [ "#ff6d69", "#fecc50" ],
  "george"
]




minItems / maxItems

Використовується для обмеження мінімальної та максимальної кількості елементів масиву (включно).

Наприклад, наступна схема пропустить дані [ 'a' ]і [ 'a', 'b' ], але не пропустить
[]і [ 'a', 'b', 'c' ]:

array(
	'type' => 'array',
	'minItems' => 1,
	'maxItems' => 2,
	'items' => array(
		'type' => 'string',
	),
);




uniqueItems

Використовується, коли потрібно, щоб значення масиву були унікальні. Дивіться: rest_validate_array_contains_unique_items() .

Наприклад, наступна схема вважатиме правильними дані [ 'a', 'b' ]і не правильними [ 'a', 'a' ]:

array(
	'type' => 'array',
	'uniqueItems' => true,
	'items' => array(
		'type' => 'string',
	),
);
Важливо знати унікальність значень.
  • Значення різних типів сприймаються як унікальні. Наприклад, '1', 1і 1.0це різні значення.
  • При порівнянні масивів порядок елементів має значення . Наприклад, у такого масиву значення будуть вважатися унікальними:
    [
      ["a", "b"],
      [ "b", "a" ]
    ]
  • При порівнянні об’єктів порядок визначення властивостей НЕ має значення . Наприклад у такого масиву об’єкти будуть вважатися однаковими:
    [
      {
    	"a": 1,
    	"b": 2
      },
      {
    	"b": 2,
    	"a": 1
      }
    ]
  • Унікальність перевіряється рекурсивно для значень масивів в обох функціях: rest_sanitize_value_from_schema() . Потрібно це для того, щоб не було моментів, коли елементи можуть бути унікальними до очищення і однаковими після.

    Візьмемо для прикладу таку схему:

    array(
    	'type' => 'array',
    	'uniqueItems' => true,
    	'items' => array(
    		'type' => 'string',
    		'format' => 'uri',
    	),
    );

    Такий запит пройшов би перевірку, бо рядки різні:

    [ "https://site.com/hello world", "https://site.com/hello%20world" ]

    Однак після обробки функцією rest_sanitize_value_from_schema() повернула помилку. Тому вам завжди слід перевірити та очищати параметри.




object

Цей тип вимагає, щоб дані були об’єктом. Також потрібно вказати формат кожної властивості об’єкта у параметрі properties.

Див. rest_sanitize_object() .




properties

Обов’язкові характеристики об’єкта. До кожної властивості вказується своя схема.

Наприклад, наступна схема вимагає об’єкт, де властивість name є рядком, а color шістнадцятковим кольором.

array(
	'type' => 'object',
	'properties' => array(
		'name' => array(
			'type' => 'string',
		),
		'color' => array(
			'type' => 'string',
			'format' => 'hex-color',
		),
	),
);

Такі дані пройдуть перевірку:

{
  "name": "Primary",
  "color": "#ff6d69"
}

А такі не пройде:

{
  "name": "Primary",
  "color": "orange"
}
Обов’язкові властивості

За замовчуванням усі властивості, перелічені для об’єкта, є необов’язковими, тому, якщо якоїсь властивості не вистачатиме в об’єкті, перевірка все одно буде пройдена.

Є два способи зробити властивість обов’язковою.

Спосіб 1: додати поле requiredкожної властивості.

Це синтаксис 3 версії схеми JSON:

array(
	'type' => 'object',
	'properties' => array(
		'name' => array(
			'type' => 'string',
			'required' => true,
		),
		'color' => array(
			'type' => 'string',
			'format' => 'hex-color',
			'required' => true,
		),
	),
);

Спосіб 2: додати поле requiredдо загального масиву де перечистити обов’язкові властивості.

Це синтаксис 4 версії схеми JSON:

register_post_meta( 'post', 'fixed_in', array(
	'type' => 'object',
	'show_in_rest' => array(
		'single' => true,
		'schema' => array(
			'required' => array( 'revision', 'version' ),
			'type' => 'object',
			'properties' => array(
				'revision' => array(
					'type' => 'integer',
				),
				'version' => array(
					'type' => 'string',
				),
			),
		),
	),
)));

Тепер наступний запит не пройде перевірку:

{
	"title": "Check required properties",
	"content": "We should check that required properties are provided",
	"meta": {
		"fixed_in": {
			"revision": 47089
		}
	}
}

Якщо мета-поле fixed_in взагалі не вказати, жодної помилки не виникне. Об’єкт, визначальний перелік обов’язкових властивостей, не визначає сам об’єкт обов’язковим. Просто якщо об’єкт вказано, то обов’язкові властивості також мають бути вказані.

Синтаксис 4 версії не підтримується для схем ендпоінта верхнього рівня WP_REST_Controller::get_item_schema() .

Якщо вказано таку схему, користувач може надіслати успішний запит не вказуючи властивості title та content. Це відбувається тому, що документ схеми сам по собі не використовується для перевірки, а натомість перетворюється на список визначень параметрів.

array(
	'$schema' => 'http://json-schema.org/draft-04/schema#',
	'title' => 'my-endpoint',
	'type' => 'object',
	'required' => array( 'title', 'content' ),
	'properties' => array(
		'title' => array(
			'type' => 'string',
		),
		'content' => array(
			'type' => 'string',
		),
	),
);




additionalProperties

Визначає, чи може об’єкт містити додаткові властивості, не зазначені у схемі.

За замовчуванням схема JSON дозволяє вказувати властивості, які не вказані у схемі.

Отже, щоб таке не пройшло перевірку, необхідно вказати параметр additionalProperties = false , тобто. неописані у схемі (додаткові) властивості заборонені.

array(
	'type' => 'object',
	'additionalProperties' => false,
	'properties' => array(
		'name' => array(
			'type' => 'string',
		),
		'color' => array(
			'type' => 'string',
			'format' => 'hex-color',
		),
	),
);

Ключове слово AdditionalProperties саме може бути використане як схема властивостей об’єкта. Так невідомі властивості мають пройти зазначену перевірку.

Це може бути корисно, коли ви хочете прийняти список значень, кожне з яких може мати свій власний унікальний ключ неописаний у схемі, але значення повинні відповідати схемі. Наприклад:

array(
	'type' => 'object',
	'properties' => array(),
	'additionalProperties' => array(
		'type' => 'object',
		'properties' => array(
			'name' => array(
				'type' => 'string',
				'required' => true,
			),
			'color' => array(
				'type' => 'string',
				'format' => 'hex-color',
				'required' => true,
			),
		),
	),
);

Тепер такі дані пройдуть перевірку:

{
  "primary": {
	"name": "Primary",
	"color": "#ff6d69"
  },
  "secondary": {
	"name": "Secondary",
	"color": "#fecc50"
  }
}

А ось ці не пройдуть:

{
  "primary": {
	"name": "Primary",
	"color": "#ff6d69"
  },
  "secondary": "#fecc50"
}




patternProperties

Ключове слово patternProperties аналогічне до ключового слова additionalProperties , але дозволяє стверджувати, що властивість відповідає шаблону регулярних виразів. Ключове слово – це об’єкт, де кожна властивість є шаблоном регулярних виразів, а його значення – схемою JSON, що використовується для перевірки властивостей, що відповідають цьому шаблону.

Наприклад, ця схема вимагає, щоб кожне значення було шістнадцятковим кольором, а властивість повинна містити лише символи слова.

array(
  'type' => 'object',
  'patternProperties' => array(
	'^\w+

В результаті це пройде перевірку:

{
  "primary": "#ff6d69",
  "secondary": "#fecc50"
}

А це не пройде:

{
  "primary": "blue",
  "$secondary": "#fecc50"
}

При перевірці схеми patternProperties , якщо властивість не відповідає жодному з шаблонів, ця властивість буде дозволена і її вміст не перевірятиметься. Якщо така поведінка не підходить, вам потрібно заборонити невідомі (додаткові) властивості за допомогою параметра additionalProperties .




minProperties / maxProperties

Використовується для обмеження мінімальної та максимальної кількості властивостей об'єкта (включно). Це аналоги властивостей minItems і maxItems у масиву .

Це може бути корисно при описі схеми де дозволяються невідомі властивості об'єкта, але їх має бути обмежена кількість. Наприклад:

array(
  'type' => 'object',
  'additionalProperties' => array(
	'type' => 'string',
	'format' => 'hex-color',
  ),
  'minProperties' => 1,
  'maxProperties' => 2,
);

Ці дані пройдуть перевірку:

{
  "primary": "#52accc",
  "secondary": "#096484"
}

А ось ці ні:

{
  "primary": "#52accc",
  "secondary": "#096484",
  "tertiary": "#07526c"
}




enum

Дозволяє вказати список можливих значень параметра, що передається (коли у параметра обмежений список можливих значень).

Цей параметр не залежить від зазначеного типу і спрацьовуватиме з будь-яким типом, потрібно лише щоб отримане значення було у вказаному списку значень.

enum перевіряється тільки під час перевірки значення (validate не sanitize) у функції rest_validate_value_from_schema() .

Приклад використання параметра:

array(
	'description' => __( 'Order sort attribute ascending or descending.' ),
	'type' => 'string',
	'default' => 'asc',
	'enum' => array(
		'asc',
		'desc',
	),
);

Код з ядра показує як саме робиться перевірка:

if ( ! in_array( $value, $args['enum'], true ) ) {
	return new WP_Error( 'rest_invalid_param', sprintf( __( '%1$s не є одним з %2$s.' ), $param, implode( ', ', $args['enum'] ) ) ));
}




oneOf / anyOf

Збіг з однією або будь-якою з описаних схем. Дивіться: rest_find_one_matching_schema() .

Це розширені ключові слова, які дозволяють валідатор JSON схеми вибрати одну з багатьох схем для використання при перевірці значення.

  • anyOf дозволяє, щоб значення відповідало одній із зазначених схем або кільком схемам.
  • oneOf вимагає, щоб значення підходило лише під одну схему (не під дві і більше).

Наприклад, ця схема дозволяє відправляти масив “операцій” у кінцеву точку. Кожна операція може бути “crop”, або “rotation”.

array(
	'type' => 'array',
	'items' => array(
		'oneOf' => array(
			array(
				'title' => 'Crop',
				'type' => 'object',
				'properties' => array(
					'operation' => array(
						'type' => 'string',
						'enum' => array(
							'crop',
						),
					),
					'x' => array(
						'type' => 'integer',
					),
					'y' => array(
						'type' => 'integer',
					),
				),
			),
			array(
				'title' => 'Rotation',
				'type' => 'object',
				'properties' => array(
					'operation' => array(
						'type' => 'string',
						'enum' => array(
							'rotate',
						),
					),
					'degrees' => array(
						'type' => 'integer',
						'minimum' => 0,
						'maximum' => 360,
					),
				),
			),
		),
	),
);

REST API пройде циклом за кожною схемою, вказаною в масиві oneOf і перевірить відповідність. Якщо збігається лише одна схема, то перевірка буде успішною. Якщо підходять кілька схем, перевірка провалиться. Якщо схеми не збігаються, то валідатор спробує знайти найближчу схему, що збігається, і поверне відповідне повідомлення про помилку.

operations[0] is not a valid Rotation. Reason: operations[0][degrees] must be between 0 (inclusive) and 360 (inclusive)

Щоб генерувати зрозумілі повідомлення про помилки, рекомендується присвоїти кожній схемі в масиві oneOf або anyOf властивість title .




Як працює перевірка та очищення

У REST API визначено дві базові функції для роботи з JSON схемою:

  • WP_Error .
  • WP_Error , якщо значення не можна очистити.

Обидві функції приймають значення, яке потрібно перевірити/очистити, схему параметра та назву параметра (назва буде виводиться в повідомленні при помилці).

Використовувати ці функції потрібно в строгому порядку: спочатку перевіряти значення (validate) і потім його очищати (sanitize). Якщо не використовувати будь-яку з перевірок, дані ендпоінту можуть виявитися недостатньо захищені.

Реєстрація параметрів ендпоінту та перевірка/очищення

Розглянемо з прикладу як і відбувається. Допустимо ми реєструємо роути в контролері таким чином:

class WP_REST_Terms_Controller extends WP_REST_Controller {

	...

	public function register_routes() {

		register_rest_route( 'my/v1', '/myelem',
			array(
				array(
					'methods' => 'GET',
					'callback' => array( $this, 'get_items' ),
					'permission_callback' => array( $this, 'get_items_permissions_check' ),
					'args' => $this->get_collection_params(),
				),
				array(
					'methods' => 'POST, PUT',
					'callback' => array( $this, 'create_item' ),
					'permission_callback' => array( $this, 'create_item_permissions_check' ),
					'args' => $this->get_endpoint_args_for_item_schema( 'POST, PUT' ),
				),
				'schema' => array( $this, 'get_public_item_schema' ),
			)
		);

		...
	}

	...
}
Якщо параметри ендпоінта повністю відповідають схемі ресурсу

Для реєстрації можливих параметрів ендпоінту можна використовувати метод WP_REST_Controller::get_endpoint_args_for_item_schema() . У цьому випадку клбеки перевірки/валідації будуть автоматично додані.

Як це відбувається:

public function get_endpoint_args_for_item_schema( $method = WP_REST_Server::CREATABLE ) {
	return rest_get_endpoint_args_for_schema( $this->get_item_schema(), $method );
}

У функцію rest_get_endpoint_args_for_schema() передається схема $this->get_item_schema()і на її основі збирається список доступних параметрів, до даних яких додаються колбеки перевірки та очищення:

$endpoint_args[ $field_id ] = array(
	'validate_callback' => 'rest_validate_request_arg',
	'sanitize_callback' => 'rest_sanitize_request_arg',
);
Якщо параметри ендпоінту не відповідають схемі ресурсу

То колбеки очищення та валідації можна вказати вручну або не вказувати взагалі.

Якщо колбек очищення не вказаний у параметрі sanitize_callbackокремого параметра запиту, його автоматично додасть метод WP_REST_Server::dispatch() при обробці даних запиту.

Наприклад:

$query_params['author_email'] = array(
	'type' => 'string',
	'format' => 'email',
	'description' => 'Parameter Description.',
);

// Теж саме що
$query_params['author_email'] = array(
	'type' => 'string',
	'format' => 'email',
	'description' => 'Parameter Description.',
	'sanitize_callback' => 'rest_parse_request_arg',
);

Код з ядра, який показує як додається колбек очищення:

// Якщо arg має тип but no sanitize_callback attribute, default to rest_parse_request_arg.
if ( ! array_key_exists( 'sanitize_callback', $param_args ) && ! empty( $param_args['type'] ) ) {
	$param_args['sanitize_callback'] = 'rest_parse_request_arg';
}

Код rest_parse_request_arg() :

function rest_parse_request_arg( $value, $request, $param ) {
	$is_valid = rest_validate_request_arg( $value, $request, $param );

	if ( is_wp_error( $is_valid ) ) {
		return $is_valid;
	}

	$ value = rest_sanitize_request_arg ($ value, $ request, $ param);

	return $value;
}

Зверніть увагу, що перед очищенням значення робиться і перевірка. Тому немає необхідності вказувати аргумент validate_callback, коли для очищення використовується функція rest_parse_request_arg() .

Однак, якщо для очищення ви використовуєте інший колбек, який не робить перевірку, перевірку значення краще вказати окремо в аргументі validate_callback. Наприклад:

$query_params['page'] = array(
	'description' => __( 'Current page of the collection.' ),
	'type' => 'integer',
	'default' => 1,
	'sanitize_callback' => 'absint',
	'validate_callback' => 'rest_validate_request_arg',
	'minimum' => 1,
),

=> array(
‘type’ => ‘string’,
‘format’ => ‘hex-color’,
),
),
‘additionalProperties’ => false,
);В результаті це пройде перевірку:

А це не пройде:

При перевірці схеми patternProperties , якщо властивість не відповідає жодному з шаблонів, ця властивість буде дозволена і її вміст не перевірятиметься. Якщо така поведінка не підходить, вам потрібно заборонити невідомі (додаткові) властивості за допомогою параметра additionalProperties .




minProperties / maxProperties

Використовується для обмеження мінімальної та максимальної кількості властивостей об’єкта (включно). Це аналоги властивостей minItems і maxItems у масиву .

Це може бути корисно при описі схеми де дозволяються невідомі властивості об’єкта, але їх має бути обмежена кількість. Наприклад:

Ці дані пройдуть перевірку:

А ось ці ні:




enum

Дозволяє вказати список можливих значень параметра, що передається (коли у параметра обмежений список можливих значень).

Цей параметр не залежить від зазначеного типу і спрацьовуватиме з будь-яким типом, потрібно лише щоб отримане значення було у вказаному списку значень.

enum перевіряється тільки під час перевірки значення (validate не sanitize) у функції rest_validate_value_from_schema() .

Приклад використання параметра:

Код з ядра показує як саме робиться перевірка:




oneOf / anyOf

Збіг з однією або будь-якою з описаних схем. Дивіться: rest_find_one_matching_schema() .

Це розширені ключові слова, які дозволяють валідатор JSON схеми вибрати одну з багатьох схем для використання при перевірці значення.

  • anyOf дозволяє, щоб значення відповідало одній із зазначених схем або кільком схемам.
  • oneOf вимагає, щоб значення підходило лише під одну схему (не під дві і більше).

Наприклад, ця схема дозволяє відправляти масив “операцій” у кінцеву точку. Кожна операція може бути “crop”, або “rotation”.

REST API пройде циклом за кожною схемою, вказаною в масиві oneOf і перевірить відповідність. Якщо збігається лише одна схема, то перевірка буде успішною. Якщо підходять кілька схем, перевірка провалиться. Якщо схеми не збігаються, то валідатор спробує знайти найближчу схему, що збігається, і поверне відповідне повідомлення про помилку.

operations[0] is not a valid Rotation. Reason: operations[0][degrees] must be between 0 (inclusive) and 360 (inclusive)

Щоб генерувати зрозумілі повідомлення про помилки, рекомендується присвоїти кожній схемі в масиві oneOf або anyOf властивість title .




Як працює перевірка та очищення

У REST API визначено дві базові функції для роботи з JSON схемою:

  • WP_Error .
  • WP_Error , якщо значення не можна очистити.

Обидві функції приймають значення, яке потрібно перевірити/очистити, схему параметра та назву параметра (назва буде виводиться в повідомленні при помилці).

Використовувати ці функції потрібно в строгому порядку: спочатку перевіряти значення (validate) і потім його очищати (sanitize). Якщо не використовувати будь-яку з перевірок, дані ендпоінту можуть виявитися недостатньо захищені.

Реєстрація параметрів ендпоінту та перевірка/очищення

Розглянемо з прикладу як і відбувається. Допустимо ми реєструємо роути в контролері таким чином:

Якщо параметри ендпоінта повністю відповідають схемі ресурсу

Для реєстрації можливих параметрів ендпоінту можна використовувати метод WP_REST_Controller::get_endpoint_args_for_item_schema() . У цьому випадку клбеки перевірки/валідації будуть автоматично додані.

Як це відбувається:

У функцію rest_get_endpoint_args_for_schema() передається схема $this->get_item_schema()і на її основі збирається список доступних параметрів, до даних яких додаються колбеки перевірки та очищення:

Якщо параметри ендпоінту не відповідають схемі ресурсу

То колбеки очищення та валідації можна вказати вручну або не вказувати взагалі.

Якщо колбек очищення не вказаний у параметрі sanitize_callbackокремого параметра запиту, його автоматично додасть метод WP_REST_Server::dispatch() при обробці даних запиту.

Наприклад:

Код з ядра, який показує як додається колбек очищення:

Код rest_parse_request_arg() :

Зверніть увагу, що перед очищенням значення робиться і перевірка. Тому немає необхідності вказувати аргумент validate_callback, коли для очищення використовується функція rest_parse_request_arg() .

Однак, якщо для очищення ви використовуєте інший колбек, який не робить перевірку, перевірку значення краще вказати окремо в аргументі validate_callback. Наприклад:

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *