Comment les ressources de streaming s'inscrivent-elles dans le paradigme RESTful?

101

Avec un service RESTful, vous pouvez créer, lire, mettre à jour et supprimer des ressources. Tout cela fonctionne bien lorsque vous avez affaire à quelque chose comme des actifs de base de données - mais comment cela se traduit-il par des données en continu? (Ou est-ce le cas?) Par exemple, dans le cas de la vidéo, il semble ridicule de traiter chaque image comme une ressource que je devrais interroger une à la fois. Je voudrais plutôt mettre en place une connexion socket et diffuser une série de trames. Mais cela brise-t-il le paradigme RESTful? Que faire si je veux pouvoir rembobiner ou avancer rapidement le flux? Est-ce possible dans le paradigme RESTful? Alors: comment les ressources de streaming s'inscrivent-elles dans le paradigme RESTful?

En ce qui concerne la mise en œuvre, je me prépare à créer un tel service de données en continu et je veux m'assurer de le faire de la «meilleure façon». Je suis sûr que ce problème a déjà été résolu. Quelqu'un peut-il m'indiquer du bon matériel?

JnBrymn
la source
2
Quelle option avez-vous finalement choisie? Avez-vous regardé gRPc? Il prend en charge le streaming bidirectionnel.
Mac

Réponses:

80

Je n'ai pas réussi à trouver du matériel sur le streaming vraiment RESTful - il semble que les résultats concernent principalement la délégation de streaming à un autre service (ce qui n'est pas une mauvaise solution). Je ferai donc de mon mieux pour m'y attaquer moi-même - notez que le streaming n'est pas mon domaine, mais je vais essayer d'ajouter mes 2 cents.

Dans l'aspect du streaming, je pense qu'il faut séparer le problème en deux parties indépendantes:

  1. accès aux ressources multimédias (métadonnées)
  2. accès au support / flux lui-même (données binaires)

1.) Accès aux ressources multimédias
Ceci est assez simple et peut être géré de manière propre et RESTful. À titre d'exemple, disons que nous aurons une API basée sur XML qui nous permet d'accéder à une liste de flux:

GET /media/

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

... et aussi aux flux individuels:

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.) Accès au support / flux lui-même
C'est le bit le plus problématique. Vous avez déjà signalé une option dans votre question, à savoir permettre l'accès aux cadres individuellement via une API RESTful. Même si cela peut fonctionner, je suis d'accord avec vous que ce n'est pas une option viable.

Je pense qu'il y a un choix à faire entre:

  1. déléguer le streaming à un service dédié via un protocole de streaming spécialisé (par exemple RTSP)
  2. utilisation des options disponibles dans HTTP

Je pense que le premier est le choix le plus efficace, bien qu'il nécessite un service de streaming dédié (et / ou du matériel). Cela pourrait être un peu à la limite de ce qui est considéré comme RESTful, mais notez que notre API est RESTful dans tous les aspects et même si le service de streaming dédié n'adhère pas à l'interface uniforme (GET / POST / PUT / DELETE), notre API Est-ce que. Notre API nous permet un contrôle approprié sur les ressources et leurs métadonnées via GET / POST / PUT / DELETE, et nous fournissons des liens vers le service de streaming (adhérant ainsi à l'aspect de connectivité de REST).

Cette dernière option - le streaming via HTTP - n'est peut-être pas aussi efficace que la précédente, mais c'est certainement possible. Techniquement, ce n'est pas si différent que d'autoriser l'accès à toute forme de contenu binaire via HTTP. Dans ce cas, notre API fournirait un lien vers la ressource binaire accessible via HTTP, et nous conseillerait également sur la taille de la ressource:

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>

Le client peut accéder à la ressource via HTTP en utilisant GET /media/1.3gp. Une option est pour le client de télécharger la ressource entière - téléchargement progressif HTTP . Une alternative plus propre serait que le client accède à la ressource par morceaux en utilisant les en- têtes HTTP Range . Pour récupérer le deuxième morceau de 256 Ko d'un fichier d'une taille de 1 Mo, la demande du client ressemblerait alors à ceci:

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

Un serveur qui prend en charge les plages répondrait alors avec l'en -tête Content-Range , suivi de la représentation partielle de la ressource:

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

Notez que notre API a déjà indiqué au client la taille exacte du fichier en octets (1 Mo). Dans un cas où le client ne connaîtrait pas la taille de la ressource, il devrait d'abord appeler HEAD /media/1.3gpafin de déterminer la taille, sinon il risque une réponse du serveur avec 416 Requested Range Not Satisfiable.

MicE
la source
2
Wow ... c'est une excellente information. Vous avez attiré mon attention sur quelques nouvelles façons de penser à ce sujet. Je n'étais pas non plus au courant du protocole de diffusion en temps réel.
JnBrymn
1
Pas de problème, je suis content d'avoir pu aider. Veuillez noter cependant que je n'ai pas encore eu l'occasion de travailler personnellement avec des protocoles de streaming (à l'exception du streaming progressif via HTTP). J'ai choisi RTSP juste comme exemple, je ne peux pas dire s'il pourrait être utile dans votre scénario spécifique. Vous voudrez peut-être poser une autre question SO sur les protocoles de streaming en particulier. Wikipedia offre également un bon point de départ vers d'autres protocoles - voir les sections "Problèmes de protocole" et "Voir aussi" ici: en.wikipedia.org/wiki/Streaming_Media
MicE
1
Merci c'est de loin l'explication la plus simple et technique.
silentsudo