Bagaimana sumber daya streaming sesuai dengan paradigma RESTful?

101

Dengan layanan RESTful, Anda dapat membuat, membaca, memperbarui, dan menghapus sumber daya. Ini semua berfungsi dengan baik ketika Anda berurusan dengan sesuatu seperti aset database - tetapi bagaimana ini diterjemahkan ke data streaming? (Atau apakah itu?) Misalnya, dalam kasus video, tampaknya konyol untuk memperlakukan setiap frame sebagai sumber daya yang harus saya kueri satu per satu. Sebaliknya saya akan mengatur koneksi soket dan mengalirkan serangkaian bingkai. Tapi apakah ini mematahkan paradigma RESTful? Bagaimana jika saya ingin dapat memutar ulang atau mempercepat streaming? Apakah ini mungkin dalam paradigma RESTful? Jadi: Bagaimana sumber daya streaming sesuai dengan paradigma RESTful?

Sebagai masalah implementasi, saya bersiap untuk membuat layanan data streaming, dan saya ingin memastikan bahwa saya melakukannya dengan "cara terbaik". Saya yakin masalah ini telah diselesaikan sebelumnya. Bisakah seseorang mengarahkan saya ke materi yang bagus?

JnBrymn
sumber
2
Pilihan apa yang akhirnya Anda pilih? Sudahkah Anda melihat gRPc? Ini mendukung streaming dua arah.
Mac

Jawaban:

80

Saya tidak berhasil menemukan materi tentang streaming yang benar-benar tenang - tampaknya hasilnya sebagian besar tentang mendelegasikan streaming ke layanan lain (yang bukan merupakan solusi yang buruk). Jadi saya akan melakukan yang terbaik untuk mengatasinya sendiri - perhatikan bahwa streaming bukan domain saya, tetapi saya akan mencoba menambahkan 2 sen saya.

Dalam aspek streaming, menurut saya kita perlu memisahkan masalah menjadi dua bagian independen:

  1. akses ke sumber daya media (meta data)
  2. akses ke media / aliran itu sendiri (data biner)

1.) Akses ke sumber daya media
Ini cukup mudah dan dapat ditangani dengan cara yang bersih dan tenang. Sebagai contoh, katakanlah kita akan memiliki API berbasis XML yang memungkinkan kita mengakses daftar aliran:

GET /media/

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

... dan juga ke aliran individu:

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.) Akses ke media / aliran itu sendiri
Ini adalah bit yang lebih bermasalah. Anda sudah menunjukkan satu opsi dalam pertanyaan Anda, dan itu adalah mengizinkan akses ke frame secara individual melalui RESTful API. Meskipun ini mungkin berhasil, saya setuju dengan Anda bahwa ini bukan pilihan yang layak.

Saya pikir ada pilihan yang harus dibuat antara:

  1. mendelegasikan streaming ke layanan khusus melalui protokol streaming khusus (mis. RTSP)
  2. memanfaatkan opsi yang tersedia di HTTP

Saya percaya yang pertama menjadi pilihan yang lebih efisien, meskipun membutuhkan layanan streaming khusus (dan / atau perangkat keras). Ini mungkin sedikit di tepi dari apa yang dianggap RESTful, namun perhatikan bahwa API kami RESTful dalam semua aspek dan meskipun layanan streaming khusus tidak mematuhi antarmuka yang seragam (GET / POST / PUT / DELETE), API kami tidak. API kami memungkinkan kami mengontrol sumber daya dan meta datanya dengan tepat melalui GET / POST / PUT / DELETE, dan kami menyediakan tautan ke layanan streaming (dengan demikian mengikuti aspek keterhubungan REST).

Opsi terakhir - streaming melalui HTTP - mungkin tidak seefisien cara di atas, tetapi itu pasti mungkin. Secara teknis, ini tidak jauh berbeda dengan mengizinkan akses ke segala bentuk konten biner melalui HTTP. Dalam hal ini, API kami akan menyediakan tautan ke sumber daya biner yang dapat diakses melalui HTTP, dan juga memberi tahu kami tentang ukuran sumber daya:

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>

Klien dapat mengakses sumber daya melalui HTTP dengan menggunakan GET /media/1.3gp. Salah satu opsinya adalah agar klien mengunduh seluruh sumber daya - unduhan progresif HTTP . Alternatif yang lebih bersih adalah bagi klien untuk mengakses sumber daya dalam potongan dengan memanfaatkan header HTTP Range . Untuk mengambil potongan 256 KB kedua dari file yang berukuran 1MB, permintaan klien akan terlihat seperti ini:

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

Server yang mendukung rentang kemudian akan merespons dengan header Rentang Konten , diikuti dengan representasi parsial sumber daya:

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

Perhatikan bahwa API kami telah memberi tahu klien tentang ukuran file yang tepat dalam byte (1MB). Dalam kasus di mana klien tidak akan mengetahui ukuran sumber daya, itu harus terlebih dahulu memanggil HEAD /media/1.3gpuntuk menentukan ukuran, jika tidak maka itu mempertaruhkan respons server dengan 416 Requested Range Not Satisfiable.

MicE
sumber
2
Wow ... ini informasi yang bagus. Anda telah menarik perhatian saya pada beberapa cara baru untuk memikirkan hal ini. Saya juga tidak mengetahui tentang Real Time Streaming Protocol.
JnBrymn
1
Tidak masalah, saya senang bisa membantu. Harap dicatat bahwa saya belum memiliki kesempatan untuk bekerja dengan protokol streaming secara pribadi (dengan pengecualian streaming progresif melalui HTTP). Saya memilih RTSP hanya sebagai contoh, saya tidak tahu apakah itu mungkin berguna dalam skenario spesifik Anda. Anda mungkin ingin menanyakan pertanyaan SO lain tentang protokol streaming secara khusus. Wikipedia juga menawarkan titik awal yang baik untuk protokol lain - lihat bagian "Masalah protokol" dan "Lihat juga" di sini: en.wikipedia.org/wiki/Streaming_Media
MicE
1
Terima kasih, sejauh ini penjelasan paling sederhana dan teknis.
silentsudo