J'ai un service Web REST qui expose actuellement cette URL:
http: // serveur / données / média
où les utilisateurs peuvent POST
le JSON suivant:
{
"Name": "Test",
"Latitude": 12.59817,
"Longitude": 52.12873
}
afin de créer une nouvelle métadonnée Media.
Maintenant, j'ai besoin de pouvoir télécharger un fichier en même temps que les métadonnées multimédias. Quelle est la meilleure façon de procéder? Je pourrais introduire une nouvelle propriété appelée file
et base64 encoder le fichier, mais je me demandais s'il y avait une meilleure façon.
Il y a aussi l'utilisation multipart/form-data
comme ce qu'un formulaire HTML enverrait, mais j'utilise un service Web REST et je veux m'en tenir à JSON si possible.
web-services
json
rest
file-upload
Daniel T.
la source
la source
Réponses:
Je suis d'accord avec Greg qu'une approche en deux phases est une solution raisonnable, mais je le ferais dans l'autre sens. Je ferais:
Pour créer l'entrée de métadonnées et renvoyer une réponse comme:
Le client peut ensuite utiliser cette ContentUrl et effectuer un PUT avec les données du fichier.
La bonne chose à propos de cette approche est que lorsque votre serveur commence à s'alourdir avec d'immenses volumes de données, l'url que vous renvoyez peut simplement pointer vers un autre serveur avec plus d'espace / de capacité. Ou vous pouvez implémenter une sorte d'approche à tour de rôle si la bande passante est un problème.
la source
Ce n'est pas parce que vous n'encapsulez pas tout le corps de la demande dans JSON que cela n'est pas RESTful à utiliser
multipart/form-data
pour publier à la fois le JSON et les fichiers dans une seule demande:côté serveur (en utilisant Python pour le pseudocode):
pour télécharger plusieurs fichiers, il est possible d'utiliser soit des "champs de formulaire" séparés pour chacun:
... auquel cas le code du serveur aura
request.args['file1'][0]
etrequest.args['file2'][0]
ou réutiliser le même pour plusieurs:
... auquel cas
request.args['files']
sera simplement une liste de longueur 2.ou passez plusieurs fichiers dans un seul champ:
... auquel cas
request.args['files']
sera une chaîne contenant tous les fichiers, que vous devrez analyser vous-même - je ne sais pas comment le faire, mais je suis sûr que ce n'est pas difficile, ou mieux utilisez simplement les approches précédentes.La différence entre
@
et<
est que@
le fichier est joint en tant que téléchargement de fichier, tandis que<
le contenu du fichier est joint en tant que champ de texte.PS Ce n'est pas parce que j'utilise
curl
comme moyen de générer desPOST
requêtes que les mêmes requêtes HTTP ne peuvent pas être envoyées à partir d'un langage de programmation tel que Python ou en utilisant un outil suffisamment performant.la source
curl -f 'metadata={"foo": "bar"}'
?Une façon d'aborder le problème est de faire du téléchargement un processus en deux phases. Tout d'abord, vous téléchargez le fichier lui-même à l'aide d'un POST, où le serveur renvoie un identifiant au client (un identifiant peut être le SHA1 du contenu du fichier). Ensuite, une deuxième requête associe les métadonnées aux données du fichier:
L'inclusion de la base de données de fichiers64 encodée dans la demande JSON elle-même augmentera la taille des données transférées de 33%. Cela peut être important ou non en fonction de la taille globale du fichier.
Une autre approche pourrait consister à utiliser un POST des données de fichier brutes, mais inclure toutes les métadonnées dans l'en-tête de requête HTTP. Cependant, cela se situe un peu en dehors des opérations REST de base et peut être plus gênant pour certaines bibliothèques client HTTP.
la source
Je me rends compte que c'est une très vieille question, mais j'espère que cela aidera quelqu'un d'autre quand je suis tombé sur ce post à la recherche de la même chose. J'ai eu un problème similaire, juste que mes métadonnées étaient un Guid et un int. La solution est cependant la même. Vous pouvez simplement intégrer les métadonnées nécessaires à l'URL.
Méthode d'acceptation POST dans votre classe "Controller":
Ensuite, quel que soit l'enregistrement des itinéraires, WebApiConfig.Register (configuration HttpConfiguration) pour moi dans ce cas.
la source
Si votre fichier et ses métadonnées créent une ressource, il est tout à fait correct de les télécharger tous les deux en une seule demande. Un exemple de demande serait:
la source
Je ne comprends pas pourquoi, en huit ans, personne n'a publié la réponse facile. Plutôt que de coder le fichier en base64, codez le json en tant que chaîne. Il suffit ensuite de décoder le json côté serveur.
En Javascript:
POSTEZ-le en utilisant Content-Type: multipart / form-data
Côté serveur, récupérez le fichier normalement et récupérez le json sous forme de chaîne. Convertissez la chaîne en un objet, qui est généralement une ligne de code, quel que soit le langage de programmation que vous utilisez.
(Oui, cela fonctionne très bien. Le faire dans l'une de mes applications.)
la source