Типи параметрів 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 схемою:
Обидві функції приймають значення, яке потрібно перевірити/очистити, схему параметра та назву параметра (назва буде виводиться в повідомленні при помилці).
Використовувати ці функції потрібно в строгому порядку: спочатку перевіряти значення (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 схемою:
Обидві функції приймають значення, яке потрібно перевірити/очистити, схему параметра та назву параметра (назва буде виводиться в повідомленні при помилці).
Використовувати ці функції потрібно в строгому порядку: спочатку перевіряти значення (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
. Наприклад: