Perintah dan konteks
Dua klien mengedit dokumen yang sama. Server mewajibkan pembaruan bersyarat: mengembalikan 428 ketika kondisi tidak ada dan 412 ketika kondisi yang diberikan tidak lagi cocok. Jelaskan bagaimana ETag, If-Match, caching, dan percobaan ulang bekerja sama sehingga penulisan yang lebih lambat tidak dapat menimpa penulisan sebelumnya secara diam-diam.
Hal yang dievaluasi pewawancara
- Membedakan 428 sebagai persyaratan kebijakan dari 412 sebagai kondisi terevaluasi yang gagal.
- Menggunakan ETag yang kuat dan If-Match untuk kontrol konkurensi optimis.
- Merancang langkah membaca, mengedit, mengirimkan, menampilkan konflik, dan menggabungkan.
- Menangani caching, idempoten, auditabilitas, dan batasan percobaan ulang.
Pertanyaan untuk diklarifikasi sebelum menjawab
- Sumber daya dan metode penulisan mana yang memerlukan kondisi, dan apakah
If-Match: *diizinkan? - Apakah ETag bersifat kuat atau lemah, dan apakah itu berubah pada setiap pembaruan representasi yang dilindungi?
- Bagaimana klien harus menangani 428, 412, 404, dan 409 masing-masing?
- Apakah konflik digabungkan berdasarkan bidang, dipilih oleh pengguna, atau ditinggalkan?
- Apa saja persyaratan cache, versi, kunci idempoten, dan audit?
Kerangka jawaban 30 detik
Klien melakukan GET pada sumber daya dan menyimpan ETag-nya, lalu mengirimkan pengeditan dengan If-Match. Kondisi yang hilang menghasilkan 428, memberi tahu klien untuk menambahkannya; ketidakcocokan menghasilkan 412, memberi tahu bahwa sumber daya telah berubah. Klien membaca ulang, menampilkan perbedaan, menggabungkan, dan mengirimkan dengan ETag baru alih-alih menimpa secara membabi buta. Server membandingkan ETag kuat secara atomik, mencatat versi dan data audit, serta memisahkan caching bersyarat dari perlindungan penulisan.
Pembahasan mendalam langkah demi langkah
Langkah 1: Pisahkan 428 dan 412
428 adalah respons kebijakan server: permintaan melewatkan prasyarat yang diwajibkan. 412 berarti kondisi yang diberikan telah dievaluasi dan status sumber daya saat ini tidak memenuhinya. Keduanya tidak berarti mencoba kembali permintaan asli tanpa perubahan.
Langkah 2: Buat versi sumber daya
Server mengeluarkan ETag kuat dan mengubahnya setiap kali representasi yang dilindungi berubah. Klien menyimpan ETag dari GET tersebut sebagai garis dasar pengeditannya alih-alih hanya mengandalkan stempel waktu lokal.
Langkah 3: Kirimkan If-Match
Klien mengirimkan If-Match dengan PUT, PATCH, atau pembaruan berefek samping lainnya. Sebelum menerapkan penulisan, server membandingkan ETag saat ini secara atomik; hanya kecocokan yang dilanjutkan, sedangkan ketidakcocokan mengembalikan 412 dan membiarkan sumber daya tidak berubah.
GET /documents/42
ETag: "v17"
PUT /documents/42
If-Match: "v17"Langkah 4: Selesaikan konflik
Setelah 412, lakukan GET lagi dan tampilkan versi server di samping perubahan lokal. Gabungkan bidang jika kebijakan mengizinkan; jika tidak, minta pengguna untuk memilih. Jangan pernah mengirim ulang nilai If-Match yang sudah usang.
Langkah 5: Rancang perilaku cache
GET bersyarat dapat menggunakan If-None-Match dan menerima 304, sementara perlindungan penulisan menggunakan If-Match. Cache tidak boleh memperlakukan ETag lama sebagai yang terkini atau menyimpan kesalahan dalam cache dengan cara yang mengungkapkan status sumber daya.
Langkah 6: Tangani kegagalan dan percobaan ulang
Setelah batas waktu jaringan habis, jangan memutar ulang penulisan non-idempoten secara membabi buta. Tanyakan versi sumber daya atau gunakan kunci idempoten untuk menetapkan hasilnya. Respons 428 membutuhkan prasyarat; respons 412 membutuhkan pembacaan ulang dan penggabungan.
Langkah 7: Catat dan verifikasi
Lacak versi, ETag, jumlah konflik, tingkat penggabungan otomatis, dan pengabaian pengguna. Pengujian pembaruan bersamaan harus menunjukkan satu penulis berhasil dan yang lainnya menerima 412, dengan jejak audit untuk setiap perubahan versi.
Contoh jawaban berkualitas tinggi
Saya akan mengembalikan ETag kuat seperti "v17" dari GET dan meminta klien menyimpannya selama pengeditan. PUT tanpa If-Match mengembalikan 428 dengan instruksi untuk menggunakan pembaruan bersyarat; ETag yang usang gagal dalam perbandingan atomik dan mengembalikan 412. Klien kemudian melakukan GET untuk versi terbaru, menampilkan perbedaannya, menggabungkan, dan mencoba kembali dengan ETag baru daripada memutar ulang kondisi yang usang. If-None-Match dan 304 mengoptimalkan pembacaan tetapi tidak melindungi penulisan. Penulisan yang kehabisan batas waktu diperiksa berdasarkan versi atau kunci idempoten sebelum pemutaran ulang, dan kami memantau tingkat konflik dan penggabungan.
Kesalahan umum
- Memperlakukan 428 dan 412 sebagai kesalahan sementara dan mencoba ulang selamanya.
- Mengganti perbandingan ETag kuat dengan stempel waktu klien.
- Menimpa versi server setelah menerima 412.
- Membingungkan validasi cache If-None-Match dengan perlindungan penulisan If-Match.
- Memutar ulang penulisan berefek samping tanpa syarat setelah batas waktu habis.
Pertanyaan lanjutan dan tanggapan
Lanjutan 1: Mengapa tidak menggunakan Last-Modified?
Presisi stempel waktu dan masalah jam dapat membuat dua versi terlihat sama. ETag kuat terikat langsung ke versi representasi dan lebih baik untuk mencegah pembaruan yang hilang.
Lanjutan 2: Kapan If-Match: * berguna?
Ini menyatakan bahwa sumber daya harus ada atau mencegah pembuatan atau penggantian terhadap versi yang tidak diketahui, tergantung pada kontrak API. Ini bukan penulisan tanpa syarat.
Lanjutan 3: Apa perbedaan 412 dengan 409?
412 berarti prasyarat HTTP tidak terpenuhi. 409 berarti permintaan berkonflik dengan status sumber daya saat ini pada tingkat bisnis. API dapat menggunakan keduanya tetapi harus menyatakan tindakan pemulihannya.
Lanjutan 4: Bagaimana Anda menggabungkan pada tingkat bidang?
Muat garis dasar umum, versi server, dan versi lokal, lalu gabungkan sesuai dengan kebijakan bidang. Kirim konflik bidang yang sama ke pengguna dan kirimkan hasilnya dengan ETag baru.
Lanjutan 5: Bagaimana jika cache mengembalikan ETag lama?
Gunakan kontrol cache atau validasi ulang yang sesuai sebelum mengedit dan paksakan pembacaan asal setelah pembaruan yang gagal. Perbandingan atomik server dengan versi saat ini tetap menjadi otoritas utama.
Lanjutan 6: Bagaimana Anda menguji keamanan konkurensi?
Minta dua klien membaca satu ETag dan menulis secara bersamaan. Verifikasi bahwa tepat satu yang berhasil dan yang lain menerima 412, lalu cakup percobaan ulang, batas waktu, cache, dan jalur audit.