meilleure approche pour concevoir un service web rest avec des données binaires à consommer à partir du navigateur
je suis en train de développer un service Web JSON rest qui sera consommé à partir d'une seule application de page Web construite avec l'épine dorsale.js
cette API permettra au consommateur de télécharger des fichiers liés à une entité, comme des rapports pdf liés à un projet
Googler autour et en faisant quelques recherche à débordement de pile je suis venu avec ces approches possibles:
première approche: base64 champ de données codées
POST: /api/projects/234/reports
{
author: 'xxxx',
abstract: 'xxxx',
filename: 'xxxx',
filesize: 222,
content: '<base64 encoded binary data>'
}
Deuxième approche: multipart post de formulaire:
POST: /api/projects/234/reports
{
author: 'xxxx',
abstract: 'xxxx',
}
comme une réponse je vais obtenir un ID de rapport, et avec cela je vais émettre un autre post
POST: /api/projects/234/reports/1/content
enctype=multipart/form-data
et ensuite il suffit d'envoyer les données binaires
(regardez ça: https://stackoverflow.com/a/3938816/47633 )
troisième approche: post les données binaires d'une ressource distincte et enregistrer le href
d'abord je génère une clé aléatoire au client et y affiche le contenu binaire
POST: /api/files/E4304205-29B7-48EE-A359-74250E19EFC4
enctype=multipart/form-data
et ensuite
POST: /api/projects/234/reports
{
author: 'xxxx',
abstract: 'xxxx',
filename: 'xxxx',
filesize: 222,
href: '/api/files/E4304205-29B7-48EE-A359-74250E19EFC4'
}
(voir ceci: https://stackoverflow.com/a/4032079/47633 )
je voulais juste savoir s'il y avait une autre approche que je pourrais utiliser, le pour et le contre de chacune, et s'il y a une établir une façon de répondre à ce genre d'exigences
le grand con que je vois à la première approche, est que je dois pleinement charger et base64 Encoder le fichier sur le client
quelques ressources utiles:
- Post données binaires à une application RESTful
- Quelle est la bonne façon de transférer des données binaires vers un service API HTTP REST?
- comment télécharger un fichier avec des métadonnées en utilisant un service REST web?
- Mauvaise idée de transfert de charge utile importante de l'utilisation de web services?
- https://stackoverflow.com/a/5528267/47633
3 réponses
mes résultats de recherche:
-
demande unique (données incluses)
la requête contient des métadonnées. Les données sont une propriété de métadonnées et codées (par exemple: Base64).
Points forts:
- transactionnelle
- everytime valide (pas de métadonnées manquantes ou de données)
Points de vente:
- l'encodage rend la requête très grande
Exemples:
-
Unique request (multipart)
la demande contient une ou plusieurs parties contenant des métadonnées et des données.
types de contenu:
Points forts:
- transactionnelle
- everytime valide (pas de métadonnées manquantes ou de données)
Points de vente:
- la négociation du type de contenu est complexe
- le type de contenu pour les données n'est pas visible dans WADL
Exemples:
- Confluence (avec des parties pour les données et pour les métadonnées)
- Jira (avec une partie pour les données, les métadonnées seulement les en-têtes de partie pour le nom de fichier et le type mime)
- Bitbucket (avec une partie pour les données, pas de métadonnées)
- Google Drive (avec une partie pour les métadonnées et une autre pour les données)
-
demande unique (métadonnées dans L'en-tête HTTP et L'URL)
le corps de la requête contient les données et L'en-tête HTTP et L'URL contient les métadonnées.
Points forts:
- transactionnelle
- everytime valide (pas de métadonnées manquantes ou de données)
Points de vente:
- pas de possibilité de métadonnées imbriquées
-
deux requêtes
Une demande de métadonnées et d'une ou plusieurs demandes de données.
Pour:
- évolutivité (par exemple: la demande de données peut aller au serveur de dépôt)
- réutilisable (voir par exemple Google Drive )
Points de vente:
- non transactionnel
- pas à chaque fois valide (avant la deuxième demande, une partie est manquante)
Exemples:
Je ne peux pas penser à d'autres approches du haut de ma tête.
de vos 3 approches, j'ai le plus travaillé avec la méthode 3. La plus grande différence que je vois est entre la première méthode et les 2 autres: séparer les métadonnées et le contenu en 2 ressources
- Pro: L'Évolutivité
- alors que votre solution consiste à poster sur le même serveur, cela peut facilement être modifié pour pointer le téléchargement de contenu vers un autre serveur (c'est à dire Amazon S3)
- dans la première méthode, le même serveur qui fournit des métadonnées aux utilisateurs aura un processus bloqué par un gros téléchargement.
- Con: données orphelines / complexité ajoutée
- les téléchargements en panne (métadonnées ou contenu) laisseront des données orphelines dans le serveur DB
- données orphelines peuvent être nettoyées avec un emploi programmé, mais cela ajoute la complexité du code
- la méthode II réduit les possibilités d'orphelins, au prix d'un délai d'attente plus long du client que vous bloquez sur la réponse du premier POST
La première méthode semble la plus simple à coder. Cependant, je n'utiliserais la première méthode que si je m'attendais à ce que ce service soit utilisé peu fréquemment et que vous pouvez fixer une limite raisonnable au téléchargement des fichiers utilisateurs.
je crois que la méthode ultime est le numéro 3 (ressource séparée) pour la principale raison qu'elle permet de maximiser la valeur que j'obtiens de la norme HTTP, qui correspond à la façon dont je pense de REST APIs. Par exemple, et en supposant qu'un client HTTP bien fondé est dans l'utilisation, vous obtenez les avantages suivants:
- compression de contenu : vous optimisez en permettant aux serveurs de répondre avec résultat comprimé si les clients indiquent qu'ils soutiennent, votre L'API est inchangée, les clients existants continuent de travailler, les futurs clients peuvent s'en servir
- Caching : If-Modified-Since, ETag, etc. Les Clients peuvent advoid refetching les données binaires tout à fait
- Type de contenu abstraction: par exemple, vous avez besoin d'une image téléchargée, elle peut être des types
image/jpeg
ouimage/png
. Les en-têtes HTTP acceptent le type de contenu et donnez-nous une élégante sémantique pour négocier cela entre clients et serveurs sans avoir à tout coder dur comme partie de notre schéma et / ou API
d'un autre côté, je crois qu'il est juste de conclure que cette méthode n'est pas la plus simple si les données binaires en question ne sont pas optionnelles. Dans ce cas, les inconvénients énumérés dans la réponse D'Eric Hu entreront en jeu.