Общее описание
API v01
Публичное API. Версия v01. Все запросы выполняются по HTTPS.
https://<host>/api/v01/<Service>/...Этот раздел — общие правила работы с API: транспорт, формат запросов и ответов, OData-параметры чтения, типы данных. Описание конкретных сервисов вынесено в отдельные разделы документации.
Сервисы и операции
| Сервис | Чтение (OData) | Изменение (REST) |
|---|---|---|
Task / Tasks | одна задача · список задач · справочники | Create, Update, Delete |
Project / Projects | список проектов · справочники | Create, Update, Deactivate, Restore |
User / Users | список пользователей · профили · настройки · справочники | Create, UpdateProfile, UpdateSettings, Activate, Deactivate |
WorkLog / WorkLogs | список списаний времени · справочники | Create, Update, Delete |
Соглашение по именам сервисов
Каждая сущность представлена парой endpoint-ов:
- Сервис в единственном числе (
/api/v01/Task,/api/v01/Project,/api/v01/User,/api/v01/WorkLog) — операции над одной записью: REST-операции записи (Create,Update,Deleteи пр.) и, где применимо, OData-чтение одной записи по ключу. - Сервис во множественном числе (
/api/v01/Tasks,/api/v01/Projects,/api/v01/Users,/api/v01/WorkLogs) — выборка коллекции и связанные объекты-справочники (Statuses,Types,Priorities, и т. п.).
Транспорт
Используется два транспорта:
- OData v2 — для чтения данных. Поддерживаются стандартные операторы
$select,$filter,$orderby,$skip,$topи формат ответа$format=json. По умолчанию OData возвращает XML — на практике почти всегда требуется явно запросить JSON. - REST — для операций записи. Метод
POST, тело — JSON, ответ — JSON.
Конверт ответа REST
Все REST-операции отвечают унифицированным JSON-документом.
Успех:
{
"status": "Success",
"statusCode": 200,
"details": { /* ключи созданной/изменённой сущности */ }
}Ошибка:
{
"status": "Error",
"statusCode": 500,
"statusText": "Wrong parameters"
}Особый случай — бизнес-ошибка из логики БД: statusCode = 399, в statusText приходит MessageCode (строковый код, который клиент локализует самостоятельно). Во всех остальных случаях statusText содержит готовый локализованный текст.
HTTP / statusCode | statusText | Когда возникает |
|---|---|---|
200 | — | Успех |
399 | MessageCode (например, JBTASKS.TASK_PROJECT_NOT_FOUND) | Бизнес-ошибка; клиент должен локализовать код |
500 | "Wrong parameters" | Не передан обязательный конверт XxxData или ключи |
| прочие 4xx/5xx | готовый текст (MessageText) | Прочие ошибки слоя БД |
Конверт запроса REST
Все REST-операции принимают JSON-тело со следующей общей формой:
{
"<Entity>Data": { /* поля сущности */ },
"<Entity>KeyField": "TaskID",
"Parent<Entity>KeyField": "TaskKey"
}Поле <Entity>Data — основной контейнер. Поля <Entity>KeyField и Parent<Entity>KeyField (если применимо) задают, какой именно ключ из переданных является ведущим: TaskID, TaskKey, IntegrationID, Email, EmployeeID и т. п. Если <Entity>KeyField опущен, сервис сам определит ведущий ключ по тому, какие поля заполнены — приоритет <Entity>ID → бизнес-код → IntegrationID.
OData: чтение данных
Чтение всегда выполняется через сервисы во множественном числе или через единичный сервис с параметрами.
Базовый запрос коллекции
GET /api/v01/Tasks/odata/Tasks?$format=json
GET /api/v01/Projects/odata/Projects?$format=json
GET /api/v01/Users/odata/Users?$format=json
GET /api/v01/WorkLogs/odata/WorkLogs?$format=jsonПоддерживаемые параметры запроса
| Параметр | Назначение | Пример |
|---|---|---|
$select | Список возвращаемых полей через запятую. Сильно сокращает payload и ускоряет ответ. | $select=TaskID,TaskKey,TaskText,StatusID |
$filter | Условие фильтрации. Операторы: eq, ne, gt, ge, lt, le, логические and, or, not. Строки — в одинарных кавычках. | $filter=ProjectCode eq 'PROJ' and StatusCategoryID ne '3' |
$orderby | Сортировка. Направления asc / desc. Поддерживается сортировка по нескольким полям через запятую. | $orderby=PriorityID asc, DueDateTime desc |
$top | Сколько записей вернуть (страница). | $top=50 |
$skip | Сколько записей пропустить (offset). Используется в паре с $top для постраничной выборки. | $skip=100&$top=50 |
$format | Формат ответа. Для JSON указывать json. | $format=json |
$inlinecount | Запросить общее число записей в коллекции (без учёта $top / $skip). | $inlinecount=allpages |
Сводный пример
Получить вторую страницу из 50 открытых задач проекта PROJ, отсортированных по приоритету, только нужные поля, с общим счётчиком:
GET /api/v01/Tasks/odata/Tasks
?$select=TaskID,TaskKey,TaskText,StatusID,PriorityID,AssigneeFullName,DueDateTime
&$filter=ProjectCode eq 'PROJ' and StatusCategoryID ne '3'
&$orderby=PriorityID asc, DueDateTime asc
&$skip=50&$top=50
&$inlinecount=allpages
&$format=jsonОтвет (сокращённо):
{
"d": {
"__count": "327",
"results": [
{
"TaskID": "0000004242",
"TaskKey": "PROJ-42",
"TaskText": "Починить логин",
"StatusID": "10",
"PriorityID": "HIGH",
"AssigneeFullName": "Иван Петров",
"DueDateTime": "/Date(1735603200000)/"
}
]
}
}Чтение одной записи
Если у сервиса есть OData-точка одиночника, она принимает значения ключа через параметры пути:
GET /api/v01/Task/odata/Task(ID='PROJ-42',TaskKeyField='TaskKey')/Results?$format=jsonРазрешённые значения …KeyField:
| Сущность | Имя поля | Допустимые значения |
|---|---|---|
| Task | TaskKeyField | TaskID, TaskKey, IntegrationID |
| Project | ProjectKeyField | ProjectID, ProjectCode, IntegrationID |
| User | UserKeyField | UserID, EmployeeID, Email, IntegrationID |
| WorkLog | WorkLogKeyField | WorkLogID, IntegrationID |
Кодировки и типы данных
| Тип данных | JSON-представление | Комментарий |
|---|---|---|
строковый (NVARCHAR(n)) | string | UTF-8 |
целочисленный (INTEGER, INT, SMALLINT) | number | целое |
длинный целочисленный (BIGINT) | number / string | большие значения могут приходить как строка |
дробный (DECIMAL(p,s)) | string | OData сериализует дробные значения как строку |
дата/время (SECONDDATE, TIMESTAMP) | string | формат OData: "/Date(epochMs)/"; на вход в REST допускается ISO YYYY-MM-DDTHH:MM:SS |
В REST-операциях даты-времена в формате YYYY-MM-DDTHH:MM:SS нормализуются сервером в YYYYMMDDHHMMSS (14 символов).
Подсказки клиенту
- Всегда указывайте
$format=json— иначе OData возвращает XML. - Не запрашивайте «все поля» — используйте
$select, payload крупный. - Для постраничной выборки используйте
$top+$skip+$inlinecount=allpages. - В
$filterстроки заключаются в одинарные кавычки. - При записи передавайте только те поля, которые меняете — пустые/отсутствующие поля интерпретируются как
nullи могут затереть значения. Поведение зависит от конкретной операции — см. описание соответствующей операции.