Saya memiliki layanan web REST yang saat ini memaparkan URL ini:
http: // server / data / media
di mana pengguna dapat POST
mengikuti JSON:
{
"Name": "Test",
"Latitude": 12.59817,
"Longitude": 52.12873
}
untuk membuat metadata Media baru.
Sekarang saya membutuhkan kemampuan untuk mengunggah file pada saat yang sama dengan metadata media. Apa cara terbaik untuk melakukan ini? Saya bisa memperkenalkan properti baru yang disebut file
dan base64 menyandikan file, tetapi saya bertanya-tanya apakah ada cara yang lebih baik.
Ada juga yang menggunakan multipart/form-data
seperti apa bentuk HTML akan mengirim, tapi saya menggunakan layanan web REST dan saya ingin tetap menggunakan JSON jika memungkinkan.
web-services
json
rest
file-upload
Daniel T.
sumber
sumber
Jawaban:
Saya setuju dengan Greg bahwa pendekatan dua fase adalah solusi yang masuk akal, namun saya akan melakukannya sebaliknya. Saya akan lakukan:
Untuk membuat entri metadata dan mengembalikan respons seperti:
Klien kemudian dapat menggunakan ContentUrl ini dan melakukan PUT dengan data file.
Yang menyenangkan tentang pendekatan ini adalah ketika server Anda mulai terbebani dengan volume data yang sangat besar, url yang Anda kembalikan hanya dapat menunjuk ke beberapa server lain dengan lebih banyak ruang / kapasitas. Atau Anda bisa menerapkan semacam pendekatan round robin jika bandwidth merupakan masalah.
sumber
Hanya karena Anda tidak membungkus seluruh badan permintaan di JSON, tidak berarti tidak RESTful digunakan
multipart/form-data
untuk memposting JSON dan file dalam satu permintaan:di sisi server (menggunakan Python untuk pseudocode):
untuk mengunggah banyak file, dimungkinkan untuk menggunakan "kolom formulir" yang terpisah untuk masing-masing:
... dalam hal ini kode server akan memiliki
request.args['file1'][0]
danrequest.args['file2'][0]
atau menggunakan kembali yang sama untuk banyak orang:
... dalam hal
request.args['files']
ini hanya akan menjadi daftar panjang 2.atau melewati beberapa file melalui satu bidang:
...dalam hal ini
request.args['files']
akan menjadi string yang berisi semua file, yang Anda harus mengurai sendiri - tidak yakin bagaimana melakukannya, tapi saya yakin itu tidak sulit, atau lebih baik gunakan saja pendekatan sebelumnya.Perbedaan antara
@
dan<
adalah yang@
menyebabkan file untuk dilampirkan sebagai unggahan file, sedangkan<
melampirkan konten file sebagai bidang teks.PS Hanya karena saya menggunakan
curl
sebagai cara untuk menghasilkanPOST
permintaan tidak berarti permintaan HTTP yang sama persis tidak dapat dikirim dari bahasa pemrograman seperti Python atau menggunakan alat yang cukup mampu.sumber
curl -f 'metadata={"foo": "bar"}'
?Salah satu cara untuk mendekati masalah adalah membuat proses unggah menjadi dua fase. Pertama, Anda akan mengunggah file itu sendiri menggunakan POST, di mana server mengembalikan beberapa pengenal kembali ke klien (pengidentifikasi mungkin SHA1 dari konten file). Kemudian, permintaan kedua mengaitkan metadata dengan data file:
Termasuk data base64 yang disandikan ke dalam permintaan JSON itu sendiri akan meningkatkan ukuran data yang ditransfer sebesar 33%. Ini mungkin atau mungkin tidak penting tergantung pada ukuran keseluruhan file.
Pendekatan lain mungkin menggunakan POST dari data file mentah, tetapi sertakan metadata apa pun di header permintaan HTTP. Namun, ini sedikit di luar operasi REST dasar dan mungkin lebih canggung untuk beberapa perpustakaan klien HTTP.
sumber
Saya menyadari ini adalah pertanyaan yang sangat lama, tetapi mudah-mudahan ini akan membantu orang lain ketika saya menemukan posting ini mencari hal yang sama. Saya memiliki masalah serupa, hanya saja metadata saya adalah Guid dan int. Solusinya sama saja. Anda bisa menjadikan metadata yang dibutuhkan sebagai bagian dari URL.
Metode penerimaan POST di kelas "Controller" Anda:
Kemudian dalam apa pun yang Anda daftarkan rute, WebApiConfig.Register (konfigurasi HttpConfiguration) untuk saya dalam kasus ini.
sumber
Jika file Anda dan metadata-nya menciptakan satu sumber daya, tidak apa-apa untuk mengunggah keduanya dalam satu permintaan. Permintaan sampel akan:
sumber
Saya tidak mengerti mengapa, selama delapan tahun, tidak ada yang memposting jawaban yang mudah. Daripada mengkodekan file sebagai base64, mengkodekan json sebagai string. Kemudian, cukup decode json di sisi server.
Dalam Javascript:
POST menggunakan Content-Type: multipart / form-data
Di sisi server, ambil file secara normal, dan ambil json sebagai string. Konversikan string ke objek, yang biasanya satu baris kode apa pun bahasa pemrograman yang Anda gunakan.
(Ya, itu bekerja dengan baik. Melakukannya di salah satu aplikasi saya.)
sumber