Типизация атрибутов
Схема данных атрибута
Для типизации атрибутов Памир использует схему данных атрибута. Схема данных атрибута — это язык описания структуры и ограничений для данных в формате JSON. Он позволяет определять, как должен выглядеть JSON-документ, какие поля обязательны, какие типы данных допустимы, какие значения могут принимать поля и другие правила валидации.
Схему данных атрибута построена на основе JSON Schema (спецификация 2020-12).
Пример схемы данных атрибута:
{
"type": "string",
"format": "email"
}
type
: Определяет тип данных
format
: Уточняет формат данных
Типы данных
string
:
- Строка текста.
- Пример:
"Hello, world!"
.
number
:
- Число с плавающей точкой (включая целые числа).
- Пример:
42
,3.14
.
integer
:
- Целое число.
- Пример:
42
.
boolean
:
- Логическое значение (
true
илиfalse
). - Пример:
true
.
array
:
- Упорядоченный список значений.
- Пример:
[1, 2, 3]
.
object
:
- Неупорядоченный набор пар ключ-значение.
- Пример:
{ "name": "Alice", "age": 30 }
.
null
:
- Значение
null
. - Пример:
null
.
Форматы
date
:
- Дата в формате
YYYY-MM-DD
. - Пример:
"2023-10-05"
.
date-time
:
- Дата и время в формате
YYYY-MM-DDTHH:MM:SSZ
. - Пример:
"2023-10-05T14:30:00Z"
.
email
:
- Адрес электронной почты.
- Пример:
"user@example.com"
.
hostname
:
- Имя хоста.
- Пример:
"example.com"
.
ipv4
,ipv6
:
- IPv4 или IPv6 адрес.
- Пример:
"192.168.1.1"
,"2001:0db8:85a3:0000:0000:8a2e:0370:7334"
.
uri
:
- URI (Uniform Resource Identifier).
- Пример:
"https://example.com"
.
uuid
:
- Уникальный идентификатор (UUID).
- Пример:
"550e8400-e29b-41d4-a716-446655440000"
.
Тип string
В схеме данных атрибута Памир для типа string
существует несколько ключевых слов (keywords), которые позволяют задавать
дополнительные ограничения.
-
minLength
Определяет минимальную длину строки.
Пример:{
"type": "string",
"minLength": 5
}Строка должна содержать не менее 5 символов.
-
maxLength
Определяет максимальную длину строки.
Пример:{
"type": "string",
"maxLength": 10
}Строка должна содержать не более 10 символов.
-
pattern
Задает регулярное выражение, которому должна соответствовать строка.
Пример:{
"type": "string",
"pattern": "^[A-Za-z]+$"
}Строка должна состоять только из букв латинского алфавита.
-
format
Указывает формат строки. Поддерживаемые форматы включают:email
(адрес электронной почты)date
(дата в форматеYYYY-MM-DD
)date-time
(дата и время в формате ISO 8601)uri
(URL)uuid
(уникальный идентификатор)hostname
(имя хоста)password
(пароль)
Пример:
{
"type": "string",
"format": "email"
}Строка должна быть валидным адресом электронной почты.
-
enum
Ограничивает строку определенным набором значений.
Пример:{
"type": "string",
"enum": ["red", "green", "blue"]
}Строка должна быть одним из значений:
"red"
,"green"
или"blue"
. -
const
Указывает, что строка должна быть равна определенному значению.
Пример:{
"type": "string",
"const": "active"
}Строка должна быть равна
"active"
.
Пример схемы данных атрибута с использованием нескольких ключевых слов
{
"type": "string",
"minLength": 3,
"maxLength": 20,
"pattern": "^[A-Za-z0-9]+$",
"format": "email"
}
Эта схема требует, чтобы строка:
- Была длиной от 3 до 20 символов,
- Состояла только из букв и цифр,
- Была валидным адресом электронной почты.
Тип number
В схеме данных атрибута Памир существует несколько ключевых слов (keywords), которые позволяют задавать ограничения и правила для числовых данных.
-
minimum
Определяет минимальное значение числа (включительно).
Пример:{
"type": "number",
"minimum": 0
}Число должно быть больше или равно 0.
-
maximum
Определяет максимальное значение числа (включительно).
Пример:{
"type": "number",
"maximum": 100
}Число должно быть меньше или равно 100.
-
exclusiveMinimum
Определяет минимальное значение числа (исключительно).
Пример:{
"type": "number",
"exclusiveMinimum": 0
}Число должно быть строго больше 0.
-
exclusiveMaximum
Определяет максимальное значение числа (исключительно).
Пример:{
"type": "number",
"exclusiveMaximum": 100
}Число должно быть строго меньше 100.
-
multipleOf
Указывает, что число должно быть кратно заданному значению.
Пример:{
"type": "number",
"multipleOf": 2
}Число должно быть четным (кратным 2).
-
enum
Ограничивает число определенным набором значений.
Пример:{
"type": "number",
"enum": [1, 2, 3]
}Число должно быть одним из значений:
1
,2
или3
. -
const
Указывает, что число должно быть равно определенному значению.
Пример:{
"type": "number",
"const": 42
}Число должно быть равно
42
.
Пример JSON Schema с использованием нескольких ключевых слов
{
"type": "number",
"minimum": 0,
"maximum": 100,
"multipleOf": 5
}
Эта схема требует, чтобы число:
- Было в диапазоне от 0 до 100 (включительно),
- Было кратно 5 (например, 0, 5, 10, ..., 100).
Пример с exclusiveMinimum
и exclusiveMaximum
{
"type": "number",
"exclusiveMinimum": 0,
"exclusiveMaximum": 100
}
Эта схема требует, чтобы число:
- Было строго больше 0,
- Было строго меньше 100.
Тип integer
В схеме данных атрибута Памир для типа integer используются те же ключевые слова, что и для типа number, но с учетом того, что integer представляет только целые числа.
Тип boolean
Для типа boolean
в схеме данных атрибута Памир ключевых слов меньше, чем для других типов, так как boolean
может
принимать только два значения: true
или false
. Однако есть несколько полезных ключевых слов, которые можно
использовать для работы с этим типом.
-
enum
Ограничивает значениеboolean
определенным набором значений.
Пример:{
"type": "boolean",
"enum": [true]
}Значение должно быть
true
. -
const
Указывает, что значениеboolean
должно быть равно определенному значению.
Пример:{
"type": "boolean",
"const": false
}Значение должно быть
false
.
Пример JSON Schema для типа boolean
:
{
"type": "boolean"
}
Эта схема допускает только значения true
или false
.
Пример с использованием enum
:
{
"type": "boolean",
"enum": [true]
}
Эта схема требует, чтобы значение было true
.
Пример с использованием const
:
{
"type": "boolean",
"const": false
}
Эта схема требует, чтобы значение было false
.
Когда использовать boolean
Тип boolean
полезен, когда нужно описать логические значения, такие как:
- Флаги (
true
/false
), - Переключатели (включено/выключено),
- Условия (да/нет).
Тип array
Для типа array
в схеме данных атрибута Памир существует множество ключевых слов (keywords), которые позволяют
описывать структуру и ограничения для массивов.
-
items
Определяет схему для элементов массива.- Если
items
— это объект, то все элементы массива должны соответствовать этой схеме. - Если
items
— это массив, то используется позиционная валидация (каждый элемент массива проверяется по соответствующей схеме).
Пример (все элементы должны быть строками):
{
"type": "array",
"items": {
"type": "string"
}
}Пример (позиционная валидация):
{
"type": "array",
"items": [
{ "type": "string" },
{ "type": "number" }
]
}Первый элемент должен быть строкой, второй — числом.
- Если
-
minItems
Определяет минимальное количество элементов в массиве.
Пример:{
"type": "array",
"minItems": 2
}Массив должен содержать не менее 2 элементов.
-
maxItems
Определяет максимальное количество элементов в массиве.
Пример:{
"type": "array",
"maxItems": 5
}Массив должен содержать не более 5 элементов.
-
uniqueItems
Указывает, что все элементы массива должны быть уникальными.
Пример:{
"type": "array",
"uniqueItems": true
}Все элементы массива должны быть уникальными.
-
additionalItems
Определяет, разрешены ли дополнительные элементы в массиве, если используется позиционная валидация (items
как массив).- Если
additionalItems: false
, то дополнительные элементы запрещены. - Если
additionalItems: true
или указана схема, то дополнительные элементы разрешены.
Пример:
{
"type": "array",
"items": [
{ "type": "string" },
{ "type": "number" }
],
"additionalItems": false
}Массив может содержать только два элемента: строку и число.
- Если
-
contains
Указывает, что массив должен содержать хотя бы один элемент, соответствующий указанной схеме.
Пример:{
"type": "array",
"contains": {
"type": "number"
}
}Массив должен содержать хотя бы одно число.
Пример JSON Schema для типа array
:
{
"type": "array",
"items": {
"type": "string",
"minLength": 3
},
"minItems": 1,
"maxItems": 10,
"uniqueItems": true
}
Эта схема требует, чтобы массив:
- Содержал от 1 до 10 элементов,
- Каждый элемент был строкой длиной не менее 3 символов,
- Все элементы были уникальными.
Пример с contains
:
{
"type": "array",
"items": {
"type": "number"
},
"contains": {
"type": "number",
"minimum": 10
}
}
Эта схема требует, чтобы массив содержал хотя бы одно число, которое больше или равно 10.
Тип object
Для типа array
в схеме данных атрибута Памир существует множество ключевых слов (keywords), которые позволяют описывать структуру и ограничения для объектов. Вот основные из них:
-
properties
Определяет свойства объекта и их схемы.
Пример:{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
}
}Объект может содержать свойства
name
(строка) иage
(число). -
required
Указывает список обязательных свойств объекта.
Пример:{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"required": ["name"]
}Свойство
name
обязательно, аage
— нет. -
additionalProperties
Определяет, разрешены ли дополнительные свойства, не указанные вproperties
.- Если
additionalProperties: false
, дополнительные свойства запрещены. - Если
additionalProperties: true
или указана схема, дополнительные свойства разрешены.
Пример:
{
"type": "object",
"properties": {
"name": { "type": "string" }
},
"additionalProperties": false
}Объект может содержать только свойство
name
. - Если
-
patternProperties
Определяет схемы для свойств, имена которых соответствуют регулярным выражениям.
Пример:{
"type": "object",
"patternProperties": {
"^S_": { "type": "string" },
"^N_": { "type": "number" }
}
}Свойства, начинающиеся с
S_
, должны быть строками, а начинающиеся сN_
— числами. -
minProperties
Определяет минимальное количество свойств в объекте.
Пример:{
"type": "object",
"minProperties": 2
}Объект должен содержать не менее 2 свойств.
-
maxProperties
Определяет максимальное количество свойств в объекте.
Пример:{
"type": "object",
"maxProperties": 5
}Объект должен содержать не более 5 свойств.
-
propertyNames
Определяет схему для имен свойств объекта.
Пример:{
"type": "object",
"propertyNames": {
"pattern": "^[A-Za-z_]+$"
}
}Имена свойств должны состоять только из букв и символа
_
. -
dependencies
Указывает зависимости между свойствами.- Если зависимость — это массив, то при наличии одного свойства должны присутствовать и другие.
- Если зависимость — это схема, то при наличии одного свойства объект должен соответствовать указанной схеме.
Пример:
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" }
},
"dependencies": {
"age": ["name"]
}
}Если есть свойство
age
, то должно быть и свойствоname
.
Пример JSON Schema для типа object
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number", "minimum": 0 }
},
"required": ["name"],
"additionalProperties": false,
"minProperties": 1,
"maxProperties": 3
}
Эта схема требует, чтобы объект:
- Содержал обязательное свойство
name
(строка), - Мог содержать свойство
age
(число, не меньше 0), - Не содержал других свойств (
additionalProperties: false
), - Содержал от 1 до 3 свойств.
Пример с patternProperties
:
{
"type": "object",
"patternProperties": {
"^S_": { "type": "string" },
"^N_": { "type": "number" }
},
"additionalProperties": false
}
Эта схема требует, чтобы:
- Свойства, начинающиеся с
S_
, были строками, - Свойства, начинающиеся с
N_
, были числами, - Другие свойства были запрещены.
Пример с dependencies
:
{
"type": "object",
"properties": {
"name": { "type": "string" },
"age": { "type": "number" },
"license": { "type": "boolean" }
},
"dependencies": {
"license": ["age"]
}
}
Эта схема требует, чтобы:
- Если есть свойство
license
, то должно быть и свойствоage
.
Составные типы
Схема данных атрибута Памир составные типы позволяют комбинировать несколько схем или типов данных для создания более сложных и гибких правил валидации. Они используются, когда нужно описать данные, которые могут соответствовать одному из нескольких типов, или когда нужно применить несколько условий одновременно. Ключевые слова для работы с составными типами:
allOf
Указывает, что данные должны соответствовать всем указанным схемам одновременно.
Пример:{
"allOf": [
{ "type": "string" },
{ "minLength": 5 }
]
}
Данные должны быть строкой длиной не менее 5 символов.
anyOf
Указывает, что данные должны соответствовать хотя бы одной из указанных схем.
Пример:{
"anyOf": [
{ "type": "string" },
{ "type": "number" }
]
}
Данные могут быть либо строкой, либо числом.
oneOf
Указывает, что данные должны соответствовать только одной из указанных схем (но не нескольким одновременно).
Пример:{
"oneOf": [
{ "type": "string" },
{ "type": "number" }
]
}
Данные могут быть либо строкой, либо числом, но не одновременно и тем, и другим.
not
Указывает, что данные не должны соответствовать указанной схеме.
Пример:{
"not": {
"type": "string"
}
}
Данные не должны быть строкой.
if
/then
/else
Позволяет задать условную логику валидации.if
: Условие, которое проверяется.then
: Схема, которая применяется, если условие истинно.else
: Схема, которая применяется, если условие ложно.
Пример:
{
"type": "object",
"properties": {
"isMember": { "type": "boolean" }
},
"if": {
"properties": {
"isMember": { "const": true }
}
},
"then": {
"required": ["memberId"]
},
"else": {
"required": ["guestId"]
}
}
Если isMember
равно true
, то обязательно должно быть свойство memberId
. В противном случае обязательно должно быть свойство guestId
.
Примеры использования составных типов
Пример 1: Комбинация allOf
и anyOf
{
"allOf": [
{ "type": "object" },
{
"anyOf": [
{ "required": ["name"] },
{ "required": ["email"] }
]
}
]
}
Данные должны быть объектом и содержать либо свойство name
, либо свойство email
.
Пример 2: Использование oneOf
{
"oneOf": [
{ "type": "string", "maxLength": 10 },
{ "type": "number", "minimum": 0 }
]
}
Данные могут быть либо строкой длиной не более 10 символов, либо числом, не меньшим 0.
Пример 3: Использование not
{
"not": {
"type": "array"
}
}
Данные не должны быть массивом.
Пример 4: Условная валидация с if
/ then
/ else
{
"type": "object",
"properties": {
"age": { "type": "number" }
},
"if": {
"properties": {
"age": { "minimum": 18 }
}
},
"then": {
"required": ["license"]
},
"else": {
"required": ["parentConsent"]
}
}
Если возраст (age
) больше или равен 18, то обязательно должно быть свойство license
. В противном случае обязательно должно быть свойство parentConsent
.
Когда использовать составные типы:
allOf
: Когда данные должны соответствовать нескольким схемам одновременно.anyOf
: Когда данные могут соответствовать одной из нескольких схем.oneOf
: Когда данные должны соответствовать только одной из нескольких схем.not
: Когда данные не должны соответствовать определенной схеме.if
/then
/else
: Когда валидация зависит от значения других полей.
Пример схемы с использованием типов
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"age": {
"type": "integer",
"minimum": 0
},
"email": {
"type": "string",
"format": "email"
},
"isStudent": {
"type": "boolean"
},
"hobbies": {
"type": "array",
"items": {
"type": "string"
}
},
"address": {
"type": "object",
"properties": {
"city": { "type": "string" },
"zip": { "type": "string", "pattern": "^\\d{5}$" }
},
"required": ["city", "zip"]
}
},
"required": ["name", "age"]
}
Валидные данные:
{
"name": "Alice",
"age": 25,
"email": "alice@example.com",
"isStudent": true,
"hobbies": ["reading", "swimming"],
"address": {
"city": "New York",
"zip": "10001"
}
}
Невалидные данные:
{
"name": "", // пустая строка (нарушает minLength)
"age": -5, // отрицательное число (нарушает minimum)
"email": "not-an-email", // не соответствует формату email
"address": {
"city": "New York" // отсутствует обязательное поле "zip"
}
}
Визуальное представление атрибута
Визуальное представление атрибута позволяет настраивать внешний вид и поведение формы, созданной на основе схемы данных атрибута. В то время как схема данных атрибута определяет структуру данных и правила валидации, визуальное представление определяет, как эти данные будут отображаться в пользовательском интерфейсе.
В визуальном представлении атрибута Памир существует несколько ключевых слов (keywords):
ui:widget
Указывает, какой компонент использовать для отображения поля.
Пример:Для отрисовки содержимого будет использоваться редактор кода.{
"ui:widget": "code_editor"
}
Шаблон схемы атрибута
Из всей совокупности типов и форматов выделяются наиболее используемые случаи. Они сгруппированы в шаблоны:
- Строка
- Строка (длина строки ограничена размером 8 КБ)
- Текст
- Пароль
- IP адрес ipv4
- Цвет
- Число
- Целое число
- Число с плавающей точкой
- Дата и время
- Дата
- Дата и время
- Логический
- Логический
- Список
- Список строк
- Json
- Объект
- Массив