REST API для загрузки файлов ОЭД (beta)

REST API - как определенный интерфейс, через который происходит взаимодействие посредством определенного набора HTTP-запросов, а также получение HTTP-ответов определенной структуры в формате JSON.

Все запросы осуществляются с использованием протокола HTTPS с применением протокола защиты транспортного уровня (TLS) 1.3.

В настоящий момент rest-api для ОЭД находится в стадии тестирования.

Типовое соглашение и спецификация для телевизионных СМИ для использования API

Порядок загрузки материала

Аутентификация

Вычисление Request-hash

Структура ресурсов

Карточка материала

Создание материала

Список полей карточки материала

Состояние материала

Внешний уникальный ключ

Ошибки валидации полей

Редактирование материала

Удаление файлов и материалов

Просмотр списка материалов

Загрузка файла

Ограничения на количество запросов

Список кодов состояния HTTP

Порядок загрузки материала

Создать карточку материала.

Загрузить файл в карточку.

Отправить карточку на проверку.

Аутентификация

Процесс аутенитфикации возможен при наличии персонального ключа (ApiKey) и секретного ключа (SecretKey) на основе которого вычисляется RequestHash, которым, в дальнейшем, должен быть подписан каждый запрос к API.

Данные ApiKey и RequestHash необходимо оправлять в виде HTTP-заголовков в каждом запросе к сервису.

Заголовки запроса, необходимые для аутентификации

"ApiKey:4c832ce76e40bb7fdb776fcb328981d4d4c58f5c"

"RequestHash:1216dbef35ae3ea74ab197a9cc23882e91d79209a0773703798a498599d4b85d"

Вычисление Request-hash

Получить секретный ключ (SecretKey) можно на специальной странице, ссылку на которую можно получить у сотрудника ОЕДа. Срок действия ссылки - 3 суток. После истечения этого времени ее необходимо получить заново.

С помощью SecretKey, необходимо генерировать хеш запроса (RequestHash), который и предавать вместе с данными запроса. На сервере , с помощью секретного ключа проверяются переданные данные.

Для генерации RequestHash необходимо использовать метод HMAC с алгоритмом ‘sha256’ и генерировать строку содержащую хеш-код в шестнадцатеричной кодировке в нижнем регистре.

При загрузке файла, тело файла не добавляем в строку для хеширования.

Вычисление Request-hash

Строка для хеширования = <RequestURL> + <Тело запроса> + <Заголовки>

RequestURL - относительный Url запроса без имени хоста со всеми параметрами строки запроса

Тело запроса  - сериализованное в json тело запроса перед отправкой

Заголовки -  ApiKey, FileHash (в случае отправки файла)

Части строки конкатенируются без разделителей.

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

Запрос для создания карточки материала:

curl -X POST -H "ApiKey:test"

-H "RequestHash:1216dbef35ae3ea74ab197a9cc23882e91d79209a0773703798a498599d4b85d" https://oed.gtrf.ru/api/materials/ -d '{"title":"Test Send materials","date_aired":"20.10.2016 16:10:33","broadcast_country_id":"1","Languages":["42"]}’

Сторока для хеширования:

toHash =  ‘/api/materials{"title":"Test Send materials","date_aired":"20.10.2016 16:10:33","broadcast_country_id":"1","Languages":["42"]}test’

RequestHash = 1216dbef35ae3ea74ab197a9cc23882e91d79209a0773703798a498599d4b85d

Структура ресурсов

Метод

URL

Описание

Пример curl-запроса

GET

/api/languages

Справочник "Языки"

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/languages

GET

/api/countries

Справочник "Страны вещания"

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/countries

GET

/api/materials/

/api/materials/index/page/pagenum

Просмотр списка карточек материалов

Постраничный вывод материалов

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/index/page/2

GET

/api/files

Просмотр списка загруженных файлов

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/files/

DELETE

/api/files/fileId

Удаление загруженного файла

curl -X DELETE -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/files/12345

POST

/api/files? material_id=materialId& filename=fileName

Загрузка файла в карточку материала

curl -X POST -H "ApiKey:test" -H "RequestHash:test" -H “FileHash:df1555ec0c2d7fcad3a03770f9aa238a“ ‘https://oed.gtrf.ru/api/files/?material_id=12345&filename=2.mpeg’ --data-binary @2.mpeg

POST

/api/materials

Создание карточки материала

curl -X POST -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/

 -d '{"title":"testPOST$", "date_aired":"11.08.2016 00:00:00", "broadcast_country_id":"1","Languages":[“42”,”23”,”1”]}'

DELETE

/api/materials

Удаление карточки материала

curl -X DELETE -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/12345

PATCH

/api/materials/materialId

Изменение карточки материала

curl  -X PATCH -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/12345 

-d '{"director":"Режиссер","anons":"Описание материала","guests":"Гость","title":"test PATCH"}'

GET

/api/materials/materialId

Просмотр карточки материала

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/12345

POST

/api/materials/send/materialId

Отправка материала на проверку

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/send/12345/

DELETE

/api/materials/deleteIn/materialId

Удаление файла (всех файлов) из карточки материала

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/deleteIn/12345/

GET

/api/materials/foreign_id/foreignId

Получение материала по внешнему ключу

curl -H "ApiKey:test" -H "RequestHash:test" https://oed.gtrf.ru/api/materials/foreign_id/12345

Карточка материала

Создание материала.

Пример запроса для создания карточки материала

POST  /api/materials/

{
   "title": "testPOST$",                   // заголовок
   "date_aired": "11.08.2016 00:00:00",    // дата в формате dd.MM.yyyy HH:mm:ss
   "broadcast_country_id": "1",            // страна вещания
   "Languages": ["42"]
}

Данные для заполнения полей broadcast_country_id и Languages получаются из соответствующих справочников.

Метод возвращает созданную карточку, в заголовке Location url созданной карточки.

В случае ошибок валидации данных, возвращает код 422 и список полей и описание ошибок в теле ответа.

Список полей карточки материала

Поле

Тип

Формат (Размер)

Обяз.

Описание

title

Строка

255

+

Заголовок

date_aired

Дата Время

 dd.MM.yyyy HH:mm:ss

+

Дата и время первого выхода в эфир

broadcast_country_id

Число

 ид из справочника Countries

+

Страна вещания

Languages

Массив

Ид языков из справочника Languages

Пример:

[ "42",”1” ]

+

 

Языки

date_air_end

Дата

dd.MM.yyyy

 

Дата выхода в эфир последнего выпуска, если материал содержит более одного выпуска

vendor

Строка

255

 

Производитель (если по заказу)

author

Строка

255

 

Автор(ы) сценария

composer

Строка

255

 

Композитор

director

Строка

255

 

Режиссер

fragments

Текст

65535

 

Используемые фрагменты

presenters

Текст

65535

 

Ведущие

guests

Текст

65535

 

Гости

anons

Текст

5000

 

Аннотация

foreign_id

Строка

255

Внешний ключ пользователя,

уникальный для текущего пользователя

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

HTTP/1.1 201 Created

Date: Tue, 20 Sep 2016 10:39:32 GMT

Content-Type: application/json

Location: https://oed.gtrf.local/api/materials/12345
{"id":"12345","date_created":"2016-09-22 16:25:47", "title":"testPOST$","author":null,"composer":null,"director":null,"fragments":null,"presenters":null, "guests":null, "broadcast_country_id":"1","anons":null,"date_aired":"2016-08-11 00:00:00","date_air_end":null, "Languages":"13, 42", "MediaFiles":[]}

Состояние материала

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

Код

Статус

Описание

Действия

1

Новый

Создана новая карточка. Файл не загружен.

Доступны все действия корме отправки на проверку

2

Загружен

В карточку материала загружен файл

Все действия

3

Отправлен

Материал отправлен на проверку

Только просмотр

4

Принят

Материал принят службой ОЭД

Только просмотр

5

Отклонен

Материал отклонен службой ОЭД

Удаление, редактирование, удаление файла

Внешний уникальный ключ

Внешний уникальный ключ возможно применять для контроля уникальности материалов на строне клиента. Поле необязательное. Также есть возможность получать карточку материала по этому ид. Примеры запросов и возвращаемых ошибок см. в соотв. таблицах.

Ошибки валидации полей

Код

Описание

dateFalseFormat

Неправильный формат даты

stringLengthTooLong

Днинна строки превышает допустимую

notInArray

Значение не находится в списке допустимых.

isEmpty

Пустое значение недопустимо.

not_in

Дата выхода звгружаемого материала не входит в срок действия соглашений

not_unique

Запись с таким внешним ключом (foreign_id) для этого пользователя существует

 

Редактирование материала

В теле запроса передаем только те поля, которые необходимо изменить. Тело запроса обязательно.

Можно редактировать материалы со статусом новый, загружен, отклонен

Метод возвращает отредактированную карточку

 

PATCH /api/materials/:id
{
        "director":"Режиссер",
        "anons":"Материал",
        "guests":"Гость",
        "title":"test PATCH"
}

Удаление файлов и материалов

Обращение к методу возвращает код 204, в случае успешного удаления.

Нельзя удалить материалы со статусом отправлен и принят

DELETE /api/materials/:id

Просмотр списка материалов

Для материалов доступны дополнительные параметры строки запроса. Для справочников (языки и страны) данные параметры не доступны

page - номер страницы, по умолчанию на странице 100 элементов,

per_page - размер страницы

order - сортировка по полю, "-" - обратный порядок.

Пример:
Получаем втораую страницу, на странице 100 элементов отсортировано по полю в обратном порядке id.

GET /api/materials/index/page/2/per_page/100/order/-id

В ответе получаем даанные о колочиестве материалов, и сами материалы в массиве data.

{

    "data":[{},...],

    "current_page":2,

    "pages":4,

    "per_page":100,

    "count":325

}

Загрузка файла

Параметр

Обязателен

Описание

Где передается

FileHash

+

MD5-хэш файла

В заголовке

material_id

+

Ид материала в который загружается файл

В строке запроса

filename

Имя файла

В строке запроса

@FILE

+

Тело файла

В теле запроса

Перед загрузкой файла, необходимо создать карточку материала. Для прикрепления файла к карточке материала, необходимо добавить в качестве параметров запроса id материала и название файла (необязательный). В случае, если карточка с таким номером не найдена, вернется код ошибки 404 'Material not found'.

Для проверки целостности отправленного файла, в заголовке запроса должен быть праметр FileHash - MD5-хэш файла, используя » алгоритм MD5 RSA.  Если отправленное значение этого не совпадет со значением, вычисляемом на сервере вернется ошибка 400 'Integrity verification failed'

Нельзя загружать файлы в карточки со статусом принят или отправлен

POST /api/files?material_id=12345&filename=video.mp4 HTTP/1.1
Host: oed.gtrf.ru
ApiKey: your_api_token
RequestHash: your_secret_key

FileHash:df1555ec0c2d7fcad3a03770f9aa238a
Content-Length: number_of_bytes_in_file
Content-Type: application/x-www-form-urlencoded

FILE data

Если файл загружен успешно, сервер возвращает HTTP-код  201 Created с метаданными записи и загруженного файла.

Обратите внимание, если файл загружен без ошибок, но поля файла, такие как duration, bitrate, container пусты, то возможно файл поврежден и необходимо его проверить и загрузить его повторно. Или обратиться в службу поддержки.

HTTP/1.1 201 Created
Content-Type: application/json
{
        "id":"12345",
        "date_created":"2016-09-06 15:50:09",
        "material_id":"23456",
        "original_filename":"video.mp4",
        "size":45224490,
        "format":"",
        "container":"mov,mp4,m4a,3gp,3g2,mj2",
        "duration":41.19,
        "bitrate":"8783",
        ...
}

 

Удалить файл из карточки можно или по ид карточки материала или по ид файла. Нельзя удалять файлы из отправленных и принятых материалов.

Возможные исключения

код

название

описание

400

Integrity verification failed

Хеш файла не совпадает

404

Material not found

Не найден материал к которому должен быть прикреплен файл

406

Material not editable

Материал нельзя редактировать: удалени и отправлен на проверку

422

File format error

Недопустимый формат файла

Ограничения на количество запросов.

Чтобы обеспечить бесперебойное обслуживание пользователей, мы ограничиваем скорость отправки запросов, используя алгоритм leaky bucket. Этот механизм позволяет избежать ситуаций, когда вредоносное или некорректно работающее приложение вызывает ошибку отказа в обслуживании для остальных клиентов.

Если будет превышено частотное ограничение, сервер вернет ошибку с кодом 429: "Too Many Requests".

Заголовки, информирующие  об ограничениях:

 

X-Rate-Limit-Limit: Максимальное количество запросов за период

X-Rate-Limit-Remaining: Количество оставшихзя запросовзв текущий период

X-Rate-Limit-Reset: количество секунд ожидания до возобновления лимита до максимума

Список кодов состояния HTTP

200: OK. Все сработало именно так, как и ожидалось.

201: Ресурс был успешно создан в ответ на POST-запрос. Заголовок Location содержит URL, указывающий на только что созданный ресурс.

204: Запрос обработан успешно, и в ответе нет содержимого (для запроса DELETE, например).

304: Ресурс не изменялся. Можно использовать закэшированную версию.

400: Неверный запрос. Может быть связано с разнообразными проблемами на стороне пользователя, такими как неверные JSON-данные в теле запроса, неправильные параметры действия, и т.д.

401: Аутентификация завершилась неудачно.

403: Аутентифицированному пользователю не разрешен доступ к указанной точке входа API.

404: Запрошенный ресурс не существует.

405: Метод не поддерживается. Сверьтесь со списком поддерживаемых HTTP-методов в заголовке Allow.

406: Действие невозможно, например нельзя изменять объект.

415: Не поддерживаемый тип данных. Запрашивается неправильный тип данных или номер версии.

422: Проверка данных завершилась неудачно (в ответе на POST-запрос, например). Подробные сообщения об ошибках смотрите в теле ответа.

429: Слишком много запросов. Запрос отклонен из-за превышения ограничения частоты запросов.

500: Внутренняя ошибка сервера. Возможная причина — ошибки в самой программе.

503: Cервер временно не имеет возможности обрабатывать запросы по техническим причинам (обслуживание, перегрузка и прочее). В поле RetryAfter заголовка сервер может указать время, через которое клиенту рекомендуется повторить запрос.