Chỉ vì bạn không gói toàn bộ phần yêu cầu trong JSON, không có nghĩa là nó không RESTful để sử dụng multipart/form-data
để đăng cả JSON và (các) tệp trong một yêu cầu:
curl -F "metadata=<metadata.json" -F "file=@my-file.tar.gz" http://example.com/add-file
về phía máy chủ (sử dụng Python cho mã giả):
class AddFileResource(Resource):
def render_POST(self, request):
metadata = json.loads(request.args['metadata'][0])
file_body = request.args['file'][0]
...
để tải lên nhiều tệp, có thể sử dụng "trường biểu mẫu" riêng biệt cho mỗi tệp:
curl -F "metadata=<metadata.json" -F "file1=@some-file.tar.gz" -F "file2=@some-other-file.tar.gz" http://example.com/add-file
... trong trường hợp đó, mã máy chủ sẽ có request.args['file1'][0]
vàrequest.args['file2'][0]
hoặc sử dụng lại cùng một thứ cho nhiều người:
curl -F "metadata=<metadata.json" -F "files=@some-file.tar.gz" -F "files=@some-other-file.tar.gz" http://example.com/add-file
... trong trường hợp đó request.args['files']
sẽ chỉ là một danh sách có độ dài 2.
hoặc chuyển nhiều tệp qua một trường:
curl -F "metadata=<metadata.json" -F "files=@some-file.tar.gz,some-other-file.tar.gz" http://example.com/add-file
...trong trường hợp request.args['files']
sẽ là một chuỗi chứa tất cả các tệp, bạn sẽ phải tự phân tích - không chắc chắn cách thực hiện, nhưng tôi chắc chắn rằng nó không khó, hoặc tốt hơn là chỉ sử dụng các phương pháp trước đó.
Sự khác biệt giữa @
và <
là @
làm cho tệp được đính kèm dưới dạng tải lên tệp, trong khi <
đính kèm nội dung của tệp dưới dạng trường văn bản.
PS Chỉ vì tôi đang sử dụng curl
như một cách để tạo các POST
yêu cầu không có nghĩa là các yêu cầu HTTP chính xác giống nhau không thể được gửi từ một ngôn ngữ lập trình như Python hoặc sử dụng bất kỳ công cụ đủ khả năng nào.