Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Руководство [8.17] ›REST API

Конвенции API

REST API Elasticsearch реализованы через HTTP. За исключением случаев, когда оговорено иное, следующие соглашения применимы ко всем API.

Требования к типу содержимого

Тип содержимого, отправляемого в теле запроса, должен быть указан с помощью заголовка Content-Type. Значение этого заголовка должно соответствовать одному из поддерживаемых форматов, которые поддерживает API. Большинство API поддерживают JSON, YAML, CBOR и SMILE. API массовой загрузки и многократного поиска поддерживают NDJSON, JSON и SMILE; другие типы приведут к ошибочному ответу.

При использовании параметра строки запроса source тип содержимого должен быть указан с помощью параметра строки запроса source_content_type.

Elasticsearch поддерживает только JSON, закодированный в UTF-8. Elasticsearch игнорирует любые другие кодировки, отправленные с запросом. Ответы также закодированы в UTF-8.

X-Opaque-Id Заголовок HTTP

Вы можете передать заголовок HTTP X-Opaque-Id для отслеживания происхождения запроса в логах и задачах Elasticsearch. При предоставлении Elasticsearch отображает значение X-Opaque-Id в:

  • Ответе на любой запрос, включающий заголовок
  • Ответе API управления задачами управления задачами
  • Логах медленных запросов
  • Логах устаревания

Для логов устаревания Elasticsearch также использует значение X-Opaque-Id для ограничения и устранения дублирования предупреждений об устаревании. См. Ограничение логов устаревания.

Заголовок X-Opaque-Id принимает любое произвольное значение. Однако рекомендуется ограничивать эти значения конечным набором, например, ID на клиент. Не генерируйте уникальный заголовок X-Opaque-Id для каждого запроса. Слишком много уникальных значений заголовка X-Opaque-Id может помешать Elasticsearch устранять дублирование предупреждений в логах устаревания.

traceparent Заголовок HTTP

Elasticsearch также поддерживает заголовок HTTP traceparent, используя официальную спецификацию контекста трассировки W3C. Вы можете использовать заголовок traceparent для отслеживания запросов через продукты Elastic и другие сервисы. Поскольку он используется только для отслеживания, вы можете безопасно генерировать уникальный заголовок traceparent для каждого запроса.

При предоставлении Elasticsearch отображает значение заголовка trace-id как trace.id в:

  • JSON-логи сервера Elasticsearch
  • Логах медленных запросов
  • Логах устаревания

Например, следующая traceparent значение приведет к следующему trace.id значению в указанных выше логах.

`traceparent`: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
`trace.id`: 0af7651916cd43dd8448eb211c80319c

GET и POST запросы

Некоторые API Elasticsearch GET, в частности API поиска, поддерживают тело запроса. Хотя действие GET логично в контексте получения информации, GET-запросы с телом не поддерживаются всеми библиотеками HTTP. Все API Elasticsearch GET, требующие тела, также могут быть отправлены как POST-запросы. Кроме того, вы можете передать тело запроса в качестве source параметра строки запроса при использовании GET.

Выражения cron

Выражение cron — это строка следующего формата:

    <seconds> <minutes> <hours> <day_of_month> <month> <day_of_week> [year]

Elasticsearch использует парсер cron из Quartz Job Scheduler. Дополнительную информацию о написании выражений cron Quartz см. в руководстве Quartz CronTrigger.

Все временные интервалы расписания заданы в координированном универсальном времени (UTC); другие часовые пояса не поддерживаются.

Вы можете использовать утилиту командной строки elasticsearch-croneval для проверки выражений cron.

Элементы выражения cron

Все элементы обязательны, за исключением year. См. специальные символы cron для получения информации о разрешенных специальных символах.

<seconds>
(Обязательно) Допустимые значения: 0-59 и специальные символы , - * /
<minutes>
(Обязательно) Допустимые значения: 0-59 и специальные символы , - * /
<hours>
(Обязательно) Допустимые значения: 0-23 и специальные символы , - * /
<day_of_month>
(Обязательно) Допустимые значения: 1-31 и специальные символы , - * / ? L W
<month>
(Обязательно) Допустимые значения: 1-12, JAN-DEC, jan-dec, и специальные символы , - * /
<day_of_week>
(Обязательно) Допустимые значения: 1-7, SUN-SAT, sun-sat, и специальные символы , - * / ? L #
<year>
(Необязательно) Допустимые значения: 1970-2099 и специальные символы , - * /

Специальные символы cron

*
Выбирает все возможные значения для поля. Например, * в поле hours означает "каждый час".
?
Нет конкретного значения. Используйте, когда неважно, какое значение. Например, если вы хотите, чтобы расписание срабатывало в определенный день месяца, но неважно, какой день недели это будет, вы можете указать ? в поле day_of_week.
-
Диапазон значений (включительно). Используйте для разделения минимального и максимального значения. Например, если вы хотите, чтобы расписание срабатывало каждый час с 9:00 до 17:00, вы можете указать 9-17 в поле hours.
,
Несколько значений. Используйте для разделения нескольких значений для поля. Например, если вы хотите, чтобы расписание срабатывало каждую вторник и четверг, вы можете указать TUE,THU в поле day_of_week.
/
Приращение. Используйте для разделения значений при указании приращения времени. Первое значение представляет начальную точку, а второе значение - интервал. Например, если вы хотите, чтобы расписание срабатывало каждые 20 минут, начиная с начала часа, вы можете указать 0/20 в поле minutes. Аналогично, указание 1/5 в поле day_of_month приведет к срабатыванию каждые 5 дней, начиная с первого числа месяца.
L
Последний. Используйте в поле day_of_month, чтобы обозначить последний день месяца — 31-е число января, 28-е число февраля в не високосные годы, 30-е число апреля и так далее. Используйте его самостоятельно в поле day_of_week вместо 7 или SAT, или после определенного дня недели, чтобы выбрать последний день такого типа в месяце. Например, 6L означает последний пятницу месяца. Вы можете указать LW в поле day_of_month, чтобы указать последний рабочий день месяца. Избегайте использования опции L при указании списков или диапазонов значений, так как результаты, вероятно, не будут такими, как вы ожидаете.
W
Будний день. Используйте для указания ближайшего рабочего дня (понедельник-пятница) к заданному дню. Например, если вы укажете 15W в поле day_of_month, а 15-е число — суббота, расписание сработает 14-го числа. Если 15-е число — воскресенье, расписание сработает в понедельник 16-го числа. Если 15-е число — вторник, расписание сработает 15-го числа. Однако если вы укажете 1W в качестве значения для day_of_month, а 1-е число — суббота, расписание сработает в понедельник 3-го числа — оно не перепрыгнет границу месяца. Вы можете указать LW в поле day_of_month, чтобы указать последний рабочий день месяца. Вы можете использовать опцию W только тогда, когда day_of_month — это один день — она недействительна при указании диапазона или списка дней.
#
N-ый XXX день месяца. Используйте в поле day_of_week, чтобы указать n-ый XXX день месяца. Например, если вы укажете 6#1, расписание сработает в первую пятницу месяца. Обратите внимание, что если вы укажете 3#5, а в данном месяце нет 5 вторников, расписание не сработает в этом месяце.

Примеры

Установка ежедневных срабатываний
0 5 9 * * ?
Срабатывание в 9:05 утра UTC каждый день.
0 5 9 * * ? 2020
Срабатывание в 9:05 утра UTC каждый день в 2020 году.
Ограничение срабатываний диапазоном дней или времени
0 5 9 ? * MON-FRI
Срабатывание в 9:05 утра UTC с понедельника по пятницу.
0 0-5 9 * * ?
Срабатывание каждую минуту, начиная с 9:00 утра UTC и заканчивая 9:05 утра UTC каждый день.
Установка срабатываний с интервалом
0 0/15 9 * * ?
Срабатывание каждые 15 минут, начиная с 9:00 утра UTC и заканчивая 9:45 утра UTC каждый день.
0 5 9 1/3 * ?
Срабатывание в 9:05 утра UTC каждые 3 дня в каждом месяце, начиная с первого числа месяца.
Установка расписаний, срабатывающих в определенный день
0 1 4 1 4 ?
Срабатывание 1 апреля в 4:01 утра UTC.
0 0,30 9 ? 4 WED
Срабатывание в 9:00 утра UTC и в 9:30 утра UTC каждую среду в апреле.
0 5 9 15 * ?
Срабатывание в 9:05 утра UTC 15-го числа каждого месяца.
0 5 9 15W * ?
Срабатывание в 9:05 утра UTC ближайшим рабочим днем к 15-му числу каждого месяца.
0 5 9 ? * 6#1
Срабатывание в 9:05 утра UTC в первую пятницу каждого месяца.
Установка срабатываний с помощью last
0 5 9 L * ?
Срабатывание в 9:05 утра UTC в последний день каждого месяца.
0 5 9 ? * 2L
Срабатывание в 9:05 утра UTC в последний понедельник каждого месяца.
0 5 9 LW * ?
Срабатывание в 9:05 утра UTC в последний рабочий день каждого месяца.

Поддержка математики дат в именах индексов и алиасов индексов

Разрешение имён математики дат позволяет вам искать диапазон временных рядов индексов или алиасов индексов, а не искать все ваши индексы и фильтровать результаты. Ограничение числа ищущих индексов уменьшает нагрузку на кластер и улучшает производительность поиска. Например, если вы ищете ошибки в ваших ежедневных журналах, вы можете использовать шаблон имени математики дат, чтобы ограничить поиск двумя предыдущими днями.

Большинство API, принимающих аргумент индекса или алиаса индекса, поддерживают математику дат. Имя математики дат имеет следующий вид:

<static_name{date_math_expr{date_format|time_zone}}>

Где:

static_name

Статический текст

date_math_expr

Динамическое выражение математики дат, которое вычисляет дату динамически

date_format

Необязательный формат, в котором вычисляемая дата должна быть представлена. По умолчанию yyyy.MM.dd. Формат должен соответствовать java-time https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html

time_zone

Необязательная временная зона. По умолчанию UTC.

Обращайте внимание на использование строчных и заглавных букв в date_format. Например: mm обозначает минуту часа, а MM обозначает месяц года. Аналогично, hh обозначает час в диапазоне 1-12 в сочетании с AM/PM, а HH обозначает час в диапазоне 0-23 24-часов.

Выражения математики дат разрешаются независимо от локали. Следовательно, нельзя использовать другие календари, кроме григорианского.

Вы должны заключить имена математики дат в угловые скобки. Если вы используете имя в пути запроса, специальные символы должны быть закодированы в URI. Например:

resp = client.indices.create(
    index="<my-index-{now/d}>",
)
print(resp)
response = client.indices.create(
  index: '<my-index-{now/d}>'
)
puts response
const response = await client.indices.create({
  index: "<my-index-{now/d}>",
});
console.log(response);
# PUT /<my-index-{now/d}>
PUT /%3Cmy-index-%7Bnow%2Fd%7D%3E

Кодирование процентов символов математики дат

Специальные символы, используемые для округления дат, должны быть закодированы в URI следующим образом:

<

%3C

>

%3E

/

%2F

{

%7B

}

%7D

|

%7C

+

%2B

:

%3A

,

%2C

Следующий пример демонстрирует различные формы имён математики дат и итоговые имена, к которым они приводят, если текущее время — полдень UTC 22 марта 2024 года.

Выражение Преобразуется в

<logstash-{now/d}>

logstash-2024.03.22

<logstash-{now/M}>

logstash-2024.03.01

<logstash-{now/M{yyyy.MM}}>

logstash-2024.03

<logstash-{now/M-1M{yyyy.MM}}>

logstash-2024.02

<logstash-{now/d{yyyy.MM.dd|+12:00}}>

logstash-2024.03.23

Для использования символов { и } в статической части шаблона имени, экранируйте их обратной косой чертой \, например:

  • <elastic\{ON\}-{now/M}> преобразуется в elastic{ON}-2024.03.01

Следующий пример демонстрирует запрос поиска в индексах Logstash за последние три дня, предполагая, что индексы используют стандартный формат имени индекса Logstash, logstash-YYYY.MM.dd.

$params = [
    'index' => '%3Clogstash-%7Bnow%2Fd-2d%7D%3E%2C%3Clogstash-%7Bnow%2Fd-1d%7D%3E%2C%3Clogstash-%7Bnow%2Fd%7D%3E',
    'body' => [
        'query' => [
            'match' => [
                'test' => 'data',
            ],
        ],
    ],
];
$response = $client->search($params);
resp = client.search(
    index="<logstash-{now/d-2d}>,<logstash-{now/d-1d}>,<logstash-{now/d}>",
    query={
        "match": {
            "test": "data"
        }
    },
)
print(resp)
response = client.search(
  index: '<logstash-{now/d-2d}>,<logstash-{now/d-1d}>,<logstash-{now/d}>',
  body: {
    query: {
      match: {
        test: 'data'
      }
    }
  }
)
puts response
res, err := es.Search(
	es.Search.WithIndex("%3Clogstash-%7Bnow%2Fd-2d%7D%3E%2C%3Clogstash-%7Bnow%2Fd-1d%7D%3E%2C%3Clogstash-%7Bnow%2Fd%7D%3E"),
	es.Search.WithBody(strings.NewReader(`{
	  "query": {
	    "match": {
	      "test": "data"
	    }
	  }
	}`)),
	es.Search.WithPretty(),
)
fmt.Println(res, err)
const response = await client.search({
  index: "<logstash-{now/d-2d}>,<logstash-{now/d-1d}>,<logstash-{now/d}>",
  query: {
    match: {
      test: "data",
    },
  },
});
console.log(response);
# GET /<logstash-{now/d-2d}>,<logstash-{now/d-1d}>,<logstash-{now/d}>/_search
GET /%3Clogstash-%7Bnow%2Fd-2d%7D%3E%2C%3Clogstash-%7Bnow%2Fd-1d%7D%3E%2C%3Clogstash-%7Bnow%2Fd%7D%3E/_search
{
  "query" : {
    "match": {
      "test": "data"
    }
  }
}

Синтаксис для нескольких целей

Большинство API, которые принимают параметр пути запроса <data-stream>, <index> или <target>, также поддерживают синтаксис для нескольких целей.

В синтаксисе для нескольких целей вы можете использовать список, разделенный запятыми, для выполнения запроса на нескольких ресурсах, таких как потоки данных, индексы или псевдонимы: test1,test2,test3. Вы также можете использовать шаблоны, похожие на glob (*), чтобы нацеливаться на ресурсы, которые соответствуют шаблону: test* или *test или te*t или *test*.

Вы можете исключить цели, используя символ -: test*,-test3.

Псевдонимы разрешаются после шаблонов, похожих на glob. Это может привести к запросу, который нацеливается на исключённый псевдоним. Например, если test3 — это псевдоним индекса, шаблон test*,-test3 всё равно нацеливается на индексы для test3. Чтобы избежать этого, исключите конкретные индексы для псевдонима.

Вы также можете исключить кластеры из списка кластеров для поиска, используя символ -: remote*:*,-remote1:*,-remote4:* будет искать все кластеры с псевдонимом, начинающимся с "remote", за исключением "remote1" и "remote4". Обратите внимание, что для исключения кластера с помощью этой нотации необходимо исключить все его индексы. Исключение подмножества индексов в удалённом кластере в настоящее время не поддерживается. Например, это вызовет исключение: remote*:*,-remote1:logs*.

Многоцелевые API, которые могут нацеливаться на индексы, поддерживают следующие параметры запроса:

ignore_unavailable
(Необязательно, логическое значение) Если false, запрос возвращает ошибку, если он нацелен на отсутствующий или закрытый индекс. По умолчанию false.
allow_no_indices
(Необязательно, логическое значение) Если false, запрос возвращает ошибку, если какой-либо шаблон, похожий на glob, псевдоним индекса или значение _all нацелены только на отсутствующие или закрытые индексы. Это поведение применяется даже если запрос нацелен на другие открытые индексы. Например, запрос, нацеленный на foo*,bar*, возвращает ошибку, если индекс начинается с foo, но ни один индекс не начинается с bar.
expand_wildcards

(Необязательно, строка) Тип индекса, на который могут соответствовать шаблоны, похожие на glob. Если запрос может нацеливаться на потоки данных, этот аргумент определяет, соответствуют ли шаблоны, похожие на glob, скрытым потокам данных. Поддерживает значения, разделённые запятыми, такие как open,hidden. Допустимые значения:

all
Соответствие любому потоку данных или индексу, включая скрытые.
open
Соответствие открытым, нескрытым индексам. Также соответствует любому нескрытому потоку данных.
closed
Соответствие закрытым, нескрытым индексам. Также соответствует любому нескрытому потоку данных. Потоки данных не могут быть закрытыми.
hidden
Соответствие скрытым потокам данных и скрытым индексам. Должно сочетаться с open, closed или обоими.
none
Шаблоны, похожие на glob, не принимаются.

Значения параметров по умолчанию зависят от используемого API.

Некоторые многоцелевые API, которые могут нацеливаться на индексы, также поддерживают следующий параметр запроса:

ignore_throttled

(Необязательно, логическое значение) Если true, конкретные, расширенные или псевдонимизированные индексы игнорируются при заморозке. По умолчанию true.

[7.16.0] Устарело в 7.16.0.

API с единственной целью, такие как API получения документа, не поддерживают синтаксис для нескольких целей.

Скрытые потоки данных и индексы

Для большинства API шаблоны, похожие на glob, по умолчанию не соответствуют скрытым потокам данных и индексам. Чтобы шаблоны, похожие на glob, соответствовали скрытым потокам данных и индексам, необходимо указать параметр запроса expand_wildcards.

В качестве альтернативы, поиск шаблона индекса, начинающегося с точки, например, .watcher_hist*, по умолчанию будет соответствовать скрытым индексам. Это призвано отражать поведение Unix file-globbing и обеспечить более плавный переход к скрытым индексам.

Вы можете создать скрытые потоки данных, установив data_stream.hidden в значение true в соответствующем шаблоне индекса index.hidden. Вы можете скрыть индексы, используя настройку индекса index.hidden.

Поддерживающие индексы потоков данных скрываются автоматически. Некоторые функции, такие как машинное обучение, хранят информацию в скрытых индексах.

Глобальные шаблоны индексов, соответствующие всем индексам, не применяются к скрытым индексам.

Системные индексы

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

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

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

resp = client.cluster.state(
    metric="metadata",
    filter_path="metadata.indices.*.system",
)
print(resp)
const response = await client.cluster.state({
  metric: "metadata",
  filter_path: "metadata.indices.*.system",
});
console.log(response);
GET _cluster/state/metadata?filter_path=metadata.indices.*.system

При перезаписи текущего состояния кластера системные индексы должны восстанавливаться как часть их состояния функции.

Параметры

Параметры REST (при использовании HTTP, сопоставляются с параметрами HTTP URL) следуют соглашению об использовании нижнего подчеркивания.

Тело запроса в строке запроса

Для библиотек, которые не принимают тело запроса для запросов, отличных от POST, вы можете передать тело запроса как параметр строки запроса source вместо этого. При использовании этого метода параметр source_content_type также должен быть передан со значением типа носителя, которое указывает формат источника, например application/json.

Совместимость с версией REST API

Обновления основных версий часто включают ряд несовместимых изменений, которые влияют на то, как вы взаимодействуете с Elasticsearch. Хотя мы рекомендуем отслеживать логи устаревания и обновлять приложения до обновления Elasticsearch, необходимость согласования необходимых изменений может быть препятствием для обновления.

Вы можете настроить существующее приложение для работы без изменений после обновления, включив заголовки совместимости API, которые сообщают Elasticsearch, что вы всё ещё используете предыдущую версию REST API. Использование этих заголовков позволяет структуре запросов и ответов оставаться неизменной; это не гарантирует одинакового поведения.

Вы устанавливаете совместимость версии на основе каждого запроса в заголовках Content-Type и Accept. Установка compatible-with на ту же основную версию, что и у используемой вами версии, не оказывает влияния, но гарантирует, что запрос всё ещё будет работать после обновления Elasticsearch.

Чтобы сообщить Elasticsearch 8.0, что вы используете формат запроса и ответа 7.x, установите заголовок compatible-with=7:

Content-Type: application/vnd.elasticsearch+json; compatible-with=7
Accept: application/vnd.elasticsearch+json; compatible-with=7

HTTP 429 Too Many Requests код состояния отката

API Elasticsearch могут отвечать кодом состояния HTTP 429 Too Many Requests, указывая, что кластер слишком занят, чтобы обработать запрос. В этом случае попробуйте повторить запрос через небольшую задержку. Если повторный запрос также получает ответ 429 Too Many Requests, увеличьте задержку, применяя экспоненциальное увеличение задержки перед каждым последующим повторением.

Контроль доступа на основе URL

Многие пользователи используют прокси с управлением доступом на основе URL для защиты доступа к потокам данных и индексам Elasticsearch. Для запросов многократного поиска, многократного получения и bulk запросов пользователь может указать поток данных или индекс как в URL, так и в теле каждого запроса. Это может затруднить управление доступом на основе URL.

Чтобы предотвратить переопределение потока данных или индекса, указанного в URL, установите значение rest.action.multi.allow_explicit_index на false в elasticsearch.yml.

Это заставит Elasticsearch отклонять запросы, которые явно указывают поток данных или индекс в теле запроса.

Логические значения

Все параметры REST API (как параметры запроса, так и тело JSON) поддерживают предоставление булевого значения «false» в качестве значения false и булевого значения «true» в качестве значения true. Все остальные значения приведут к ошибке.

Числовые значения

При передаче числового параметра в теле запроса вы можете использовать строку string, содержащую число, вместо числового типа данных. Например:

resp = client.search(
    size="1000",
)
print(resp)
response = client.search(
  body: {
    size: '1000'
  }
)
puts response
const response = await client.search({
  size: 1000,
});
console.log(response);
POST /_search
{
  "size": "1000"
}

Целочисленные поля в теле ответа описаны как integer (или иногда как long) в этом руководстве, но в целом нет явных ограничений на такие значения. JSON, SMILE, CBOR и YAML допускают произвольно большие целочисленные значения. Не предполагайте, что поля integer в теле ответа всегда будут помещаться в 32-битное знаковое целое число.

Единицы измерения размера в байтах

Всякий раз, когда необходимо указать размер данных в байтах, например, при установке параметра размера буфера, значение должно указывать единицу измерения, например, 10kb для 10 килобайт. Обратите внимание, что эти единицы используют степени числа 1024, поэтому 1kb означает 1024 байта. Поддерживаемые единицы:

b

Байты

kb

Килобайты

mb

Мегабайты

gb

Гигабайты

tb

Терабайты

pb

Петабайты

Единицы измерения расстояния

В тех случаях, когда необходимо указать расстояния, например, параметр distance в запросе на расстояние по геоданным, по умолчанию используется метры, если единица не указана. Расстояния можно указывать в других единицах, таких как "1km" или "2mi" (2 мили).

Полный список единиц приведен ниже:

Миля

mi или miles

Ярд

yd или yards

Фут

ft или feet

Дюйм

in или inch

Километр

km или kilometers

Метр

m или meters

Сантиметр

cm или centimeters

Миллиметр

mm или millimeters

Морская миля

NM, nmi или nauticalmiles

Единицы измерения времени

Всякий раз, когда необходимо указывать продолжительность, например, для параметра timeout, продолжительность должна указывать единицу измерения, например, 2d для 2 дней. Поддерживаемые единицы:

d

Дни

h

Часы

m

Минуты

s

Секунды

ms

Миллисекунды

micros

Микросекунды

nanos

Наносекунды

Безразмерные величины

Безразмерные величины означают, что у них нет «единиц» типа «байты» или «Герц» или «метр» или «тонна».

Если одна из этих величин велика, мы выведем её как 10m для 10 000 000 или 7k для 7 000. Но мы все равно выведем 87, когда имеем в виду 87. Вот поддерживаемые множители:

k

Кило

m

Мега

g

Гига

t

Тера

p

Пета

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/api-conventions.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API