web-dev-qa-db-fra.com

Comment les ressources de streaming s'intègrent-elles dans le paradigme RESTful?

Avec un service RESTful, vous pouvez créer, lire, mettre à jour et supprimer des ressources. Tout cela fonctionne bien lorsque vous traitez quelque chose comme une ressource de base de données, mais comment cela se traduit-il en données en streaming? (Ou le fait-il?) Par exemple, dans le cas de la vidéo, il semble idiot de traiter chaque image comme une ressource que je devrais interroger une à la fois. Je préfère plutôt configurer 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? Donc: Comment les ressources de streaming s'intègrent-elles dans le paradigme RESTful?

En termes d'implémentation, je me prépare à créer un tel service de streaming de données, et je veux m'assurer de le faire de la "meilleure façon". Je suis sûr que ce problème a été résolu auparavant. Quelqu'un peut-il m'indiquer du bon matériel?

96
JnBrymn

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

En ce qui concerne le streaming, je pense que nous devons séparer le problème en deux parties indépendantes:

  1. accès aux ressources médiatiques (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 permettra 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 pour les 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 la partie la plus problématique. Vous avez déjà souligné une option dans votre question, à savoir autoriser l'accès aux trames 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. en utilisant les 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 peut ê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 de contrôler correctement les ressources et leurs métadonnées via GET/POST/PUT/DELETE, et nous fournissons des liens vers le service de streaming (respectant ainsi l'aspect connectivité de REST).

Cette dernière option - en streaming via HTTP - n'est peut-être pas aussi efficace que ci-dessus, 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 conseille é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 consiste pour le client à télécharger la ressource entière - téléchargement progressif HTTP . Une alternative plus propre consisterait à ce que le client accède à la ressource par blocs en utilisant HTTP En-têtes de plage . Pour récupérer le deuxième bloc de 256 Ko d'un fichier de 1 Mo, la demande du client devrait alors ressembler à ceci:

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

Un serveur qui prend en charge les plages répondrait alors par 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 le cas où le client ne connaîtrait pas la taille de la ressource, il doit d'abord appeler HEAD /media/1.3gp afin de déterminer la taille, sinon cela risque de provoquer une réponse du serveur avec 416 Requested Range Not Satisfiable.

77
MicE