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:

29
demandé sur Community 2013-01-19 18:33:35

3 réponses

mes résultats de recherche:

  1. 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:

  2. 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)
  3. 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
  4. 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:

12
répondu dur 2016-06-02 11:23:38

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.

8
répondu Eric Hu 2013-02-23 05:12:43

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 ou image/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.

5
répondu Amr Mostafa 2017-05-23 11:47:10