Tolong selesaikan argumen antara saya dan seorang teman.
Kami sedang merancang API produk. Entitas Produk kami terlihat seperti ini
{
"Id": "",
"ProductName": "",
"StockQuantity": 0
}
Penjualan produk ditangani oleh pihak ke-3 dan mereka wajib memberi tahu kami dengan jumlah yang dibeli sehingga StockQuantity
bidangnya dapat dikurangi.
Pendekatan saya:
PUT /api/Product/{Id}/ --data { "StockQuantity": "{NewStockQuantity}" }
Pihak ke-3 bertanggung jawab dengan menanyakan produk, membuat perhitungan berdasarkan StockQuantity
kuantitas saat ini dan yang dibeli dan mengirimkan PUT
permintaan dengan nilai baru.
Teman saya tidak ingin pihak ke-3 melakukan perhitungan. Pendekatannya
PUT /api/Product/{Id}/DecreaseStock --data { "PurchasedQuantity": "{PurchasedQuantity}" }
Jadi kita bisa melakukan perhitungan dan memperbarui StockQuantity
Saya tidak ingin membuat titik akhir berbasis fungsi dan dia tidak ingin mempercayai pihak ketiga untuk membuat perhitungan.
Apa cara yang benar bagi kita untuk mendekati masalah ini?
sumber
Jawaban:
Anda dapat membiarkan pihak ke-3 Anda mengirim penjualan ke produk Anda. Sebagai contoh:
Saya setuju dengan poin Anda dan kolega Anda. Ini adalah logika bisnis, dan tidak boleh diserahkan kepada klien API, tetapi Anda juga harus menghindari "fungsi" sebagai titik akhir.
Terkadang menyelesaikan masalah seperti itu semudah menyebutnya secara berbeda, diakui tidak selalu.
sumber
/sale
titik akhir masih valid?/sale
dan/product/{id}/sale
sepenuhnya independen dan fakta bahwa mereka memiliki nama yang sama tidak berarti bahwa mereka merujuk ke sumber daya yang sama.sale
tidak ada dalam domain saya dan itu bukan bagian dariproduct
. Apakah masih masuk akal untuk membuat/product/{id}/sale
sementara itu tidak mewakili sumber daya yang sebenarnya?Tidak ada alasan bahwa Anda juga tidak dapat melakukannya; atau keduanya.
Dalam konteks titik penjualan, melacak transaksi individu sangat masuk akal. Di sana, solusi Robert sangat masuk akal.
Dalam konteks stok / gudang, Anda tidak perlu melacak transaksi sebanyak "mengambil inventaris"; memiliki titik akhir yang memungkinkan klien untuk melaporkan tingkat stok mereka
sangat masuk akal.
Tingkat stok berubah karena alasan selain "penjualan"; hanya sesuatu yang perlu diingat.
Secara teori, level stok harus dapat dihitung dari perubahan; tetapi dalam beberapa domain itulah asumsi yang ingin Anda verifikasi . Anda ingin dapat menghitung tingkat stok dengan dua cara berbeda dan memeriksa perbedaan (alias "penyusutan").
Jadi saya tidak berpikir semantiknya jelas, berdasarkan konteks yang Anda berikan.
Adapun bagian HTTP;
PUT [target-uri]
masuk akal secara semantik ketika Anda mengganti satu representasi dokumen dengan yang lain. Ini adalahUPSERT
- PUT kedua untuk sumber daya meminta untuk menimpa representasi yang ada.mengatakan bahwa jumlah unit yang terjual adalah
3
, bukan10
.10
Seperti itulah bentuknyaItu cara lain untuk mengeja
10
.Sejauh menyangkut HTTP, ini juga dapat diterima. Namun, ini bukan pilihan tepat pada jaringan yang tidak dapat diandalkan karena pesan terkadang digandakan.
Apakah itu
13
? atau10
?Itu jelas
10
Itu jelas
10
Itu jelas
13
Itu jelas
13
10
13
(Agar adil, HTTP memang memiliki dukungan untuk permintaan bersyarat ; Anda dapat mengangkat beberapa metadata dari protokol khusus domain Anda ke header agnostik domain untuk menghilangkan beberapa ambiguitas - jika Anda dapat membujuk klien untuk bermain bersama).
Tentu saja, ada trade off - HTML tidak memiliki dukungan PUT asli; jika Anda bermaksud agar klien API Anda menjadi browser, maka Anda memerlukan protokol berdasarkan POST atau Anda memerlukan ekstensi kode-sesuai-permintaan untuk mengonversi pengiriman formulir dari POST ke PUT.
sumber
Ini sepertinya desain yang sangat buruk tidak peduli bagaimana Anda mengirisnya. Saya tidak akan pernah mempercayai pihak ketiga untuk memberi tahu saya inventaris saat ini kecuali saya telah mempekerjakan mereka untuk mengelola gudang saya.
Lebih jauh, pendekatan yang tampak fungsi sama sekali tidak tenang dan pasti akan menciptakan kekhawatiran di antara konsumen Anda.
Akhirnya, saya tidak bisa membayangkan skenario di mana satu-satunya hal yang Anda pedulikan tentang penjualan adalah inventaris yang dihasilkan yang tersisa setelah selesai.
Anda jauh lebih baik jika pihak ketiga memposting sumber daya Penjualan atau Faktur kepada Anda (dengan info seperti produk, jumlah, tanggal, metode pengiriman, info pelanggan, dll). Ini memungkinkan Anda benar-benar melakukan analisis nyata dan melacak apa yang Anda jual, kepada siapa, kapan, dll sehingga Anda dapat mengelola bisnis Anda.
Bahkan jika pihak ketiga Anda melakukan pemenuhan pesanan total, Anda akan ingin melacak penjualan untuk keperluan akuntansi dan demografi pelanggan jika tidak ada yang lain.
sumber
Jenis desain ini memiliki masalah besar yaitu jika Anda ingin memiliki lebih dari satu utas klien berjalan melawan API Anda, Anda akan terkena baca / tulis kotor. Yaitu, antara waktu klien menarik jumlah saat ini, dan menghitung nilai baru, klien lain dapat menarik nilai sebelumnya yang sama dan menghitung jawaban yang berbeda. Kuantitas yang Anda hasilkan adalah pembaruan mana saja yang terakhir tetapi tidak ada yang benar. Misalnya, jumlah Anda saat ini adalah 10. Klien A ingin menjual 5 item dan menarik jumlah saat ini. Pada saat yang sama, klien B ingin menjual 6 item dan menarik jumlah saat ini. Keduanya melihat 10 item dalam stok. A menghitung 5 item tersisa. Bmenghitung sisa 4. Keduanya memperbarui. Anda sekarang menampilkan 4 atau 5 item yang tersisa tergantung pada siapa yang terakhir direkam. Namun, Anda sebenarnya telah menjual lebih banyak barang yang sebenarnya Anda miliki. Yang lebih buruk adalah bahwa tidak ada cara mudah untuk berjalan dan melihat apa yang salah. Yang Anda miliki hanyalah dua yang salah
PUTs
dalam log Anda untuk dilihat.Dalam sistem catatan dunia nyata apa pun, sekadar memiliki total saat ini tidak memadai. Pertimbangkan jika Anda pergi ke toko dan membeli sejumlah barang. Anda meminta tanda terima dan kasir hanya menyerahkan slip kepada Anda dengan jumlah total di atasnya. Bagaimana Anda menunjukkan bahwa jumlah itu benar dari tanda terima itu? Bagaimana Anda menunjukkan Anda membeli barang jika Anda ingin mengembalikan sesuatu?
Pendekatan teman Anda lebih baik tetapi saya akan menyarankan menambahkan id transaksi ke dalam campuran. Ini mengatasi kekhawatiran VoiceOfUnason yang sebenarnya menyebutkan tentang transaksi duplikat. Salah satu opsi adalah menyediakan
POST
operasi untuk membuat transaksi baru dan kemudianPUT
untuk transaksi itu untuk mengonfirmasi. Pada titik konfirmasi Anda mengurangi stok total atau menolak permintaan karena tidak tersedia cukup.sumber
Karena penjualan ditangani oleh pihak ke-3, Anda harus memiliki kontrol atas inventaris produk Anda dengan tidak memperbolehkan mereka untuk memperbarui jumlah stok.
Untuk penggunaan internal, mis. Tujuan penghitungan stok, Anda dapat memiliki pendekatan Anda, yaitu
PUT /api/Product/{Id}/ --data { "StockQuantity": "{NewStockQuantity}" }
.Untuk penggunaan eksternal, Anda harus membuat antarmuka terpisah, mis.
/api/SalesOrder/
Yang mengambil daftar produk dan jumlah, seperti:Berdasarkan dari
SalesOrder
pengiriman oleh pihak ke-3, jumlah setiap produk dapat diperbarui dan ditetapkan ke pesanan atau Anda dapat menolak pesanan jika tidak tersedia cukup produk.Pemrosesan dan penghitungan stok adalah proses internal, pihak ke-3 hanya membutuhkan antarmuka sehingga mereka dapat meneruskan pesanan mereka ke inventaris. Pada dasarnya, itulah
SalesOrder
cara Penjualan, Keuangan, dan Gudang berkomunikasi untuk menyelesaikan penjualan.sumber