Как потоковые ресурсы вписываются в парадигму RESTful? - PullRequest
94 голосов
/ 28 января 2011

С сервисом RESTful вы можете создавать, читать, обновлять и удалять ресурсы. Все это хорошо работает, когда вы имеете дело с чем-то вроде активов базы данных - но как это перевести на потоковую передачу данных? (Или так?) Например, в случае видео кажется глупым рассматривать каждый кадр как ресурс, который я должен запрашивать по одному за раз. Скорее я бы установил соединение с сокетом и выполнил бы поток кадров. Но это нарушает парадигму RESTful? Что если я захочу перемотать или перемотать поток вперед? Возможно ли это в рамках парадигмы RESTful? Итак: Как потоковые ресурсы вписываются в парадигму RESTful?

Что касается реализации, я готовлюсь к созданию такой службы потоковой передачи данных и хочу убедиться, что я делаю это "наилучшим образом". Я уверен, что эта проблема была решена раньше. Может кто-нибудь указать мне на хороший материал?

1 Ответ

74 голосов
/ 29 января 2011

Мне не удалось найти материалы о действительно RESTful потоковой передаче - похоже, результаты в основном касаются делегирования потоковой передачи другому сервису (что не является плохим решением).Поэтому я сделаю все возможное, чтобы заняться этим самостоятельно - учтите, что потоковая передача не является моей областью, но я постараюсь добавить свои 2 цента.проблема в двух независимых частях:

  1. доступ к медиа-ресурсам (метаданным)
  2. доступ к самой среде / потоку (двоичные данные)

1.) Доступ к медиаресурсам Это довольно просто и может быть обработано чистым и RESTful способом.В качестве примера, скажем, у нас будет API на основе XML, который позволит нам получить доступ к списку потоков:

GET /media/

<?xml version="1.0" encoding="UTF-8" ?>
<media-list uri="/media">
    <media uri="/media/1" />
    <media uri="/media/2" />
    ...
</media-list>

... а также к отдельным потокам:

GET /media/1

<?xml version="1.0" encoding="UTF-8" ?>
<media uri="/media/1">
    <id>1</id>
    <title>Some video</title>
    <stream>rtsp://example.com/media/1.3gp</stream>
</media>

2.) Доступ к самой среде / потоку Это более проблемный бит.Вы уже указали одну опцию в своем вопросе, а именно: предоставить индивидуальный доступ к фреймам через RESTful API.Несмотря на то, что это может сработать, я согласен с вами, что это нереальный вариант.

Я думаю, что можно сделать выбор между:

  1. делегированием потоковой передачи выделенному сервисучерез специализированный протокол потоковой передачи (например, RTSP)
  2. с использованием параметров, доступных в HTTP

Я считаю, что первый вариант является более эффективным, хотя для него требуется выделенная служба потоковой передачи (и / или оборудование).Это может быть немного на грани того, что считается RESTful, однако обратите внимание, что наш API является RESTful во всех аспектах, и хотя выделенный потоковый сервис не придерживается единого интерфейса (GET / POST / PUT / DELETE), наш APIделает.Наш API позволяет нам надлежащим образом контролировать ресурсы и их метаданные через GET / POST / PUT / DELETE, и мы предоставляем ссылки на потоковую службу (таким образом придерживаясь аспекта связности REST).

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

GET /media/1

<?xml version="1.0" encoding="UTF-8" ?>
<media uri="/media/1">
    <id>1</id>
    <title>Some video</title>
    <bytes>1048576</bytes>
    <stream>/media/1.3gp</stream>
</media>

Клиент может получить доступ к ресурсу через HTTP, используя GET /media/1.3gp,Один из вариантов для клиента - загрузить весь ресурс - HTTP прогрессивная загрузка .Более чистой альтернативой было бы для клиента получить доступ к ресурсу порциями, используя HTTP Range headers .Для извлечения второго фрагмента размером 256 КБ файла размером 1 МБ клиентский запрос будет выглядеть следующим образом:

GET /media/1.3gp
...
Range: bytes=131072-262143
...

Сервер, который поддерживает диапазоны, будет отвечать заголовком Content-Range , за которым следует частичное представление ресурса:

HTTP/1.1 206 Partial content
...
Content-Range: bytes 131072-262143/1048576
Content-Length: 1048576
...

Обратите внимание, что наш API уже сообщил клиенту точный размер файла в байтах (1 МБ).В случае, когда клиент не знает размер ресурса, он должен сначала вызвать HEAD /media/1.3gp, чтобы определить размер, иначе он рискует получить ответ сервера с 416 Requested Range Not Satisfiable.

...