То, что вы не заключаете тело запроса в JSON, вовсе не означает, что не рекомендуется использовать REST multipart/form-data
для публикации как JSON, так и файлов в одном запросе:
curl -F "metadata=<metadata.json" -F "file=@my-file.tar.gz" http://example.com/add-file
на стороне сервера (с использованием Python для псевдокода):
class AddFileResource(Resource):
def render_POST(self, request):
metadata = json.loads(request.args['metadata'][0])
file_body = request.args['file'][0]
...
для загрузки нескольких файлов, можно использовать отдельные «поля формы» для каждого:
curl -F "metadata=<metadata.json" -F "file1=@some-file.tar.gz" -F "file2=@some-other-file.tar.gz" http://example.com/add-file
... в этом случае код сервера будет иметь request.args['file1'][0]
и request.args['file2'][0]
или используйте один и тот же для многих:
curl -F "metadata=<metadata.json" -F "files=@some-file.tar.gz" -F "files=@some-other-file.tar.gz" http://example.com/add-file
... в этом случае request.args['files']
будет просто списком длины 2.
или фактически передать несколько файлов в одно поле за один раз:
curl -F "metadata=<metadata.json" -F "files=@some-file.tar.gz,some-other-file.tar.gz" http://example.com/add-file
... в этом случае request.args['files']
будет строкой, содержащей все файлы, которые вам придется проанализировать самостоятельно - не уверен, как это сделать, но я уверен, что это не сложно, или лучше просто использовать предыдущие подходы.
Разница между @
и <
заключается в том, что @
приводит к тому, что файл прикрепляется при загрузке файла, тогда как <
присоединяет содержимое файла в виде текстового поля.
PS То, что я использую curl
как способ генерации POST
запросов, не означает, что те же самые HTTP-запросы не могут быть отправлены с языка программирования, такого как Python или используя любой достаточно мощный инструмент.