Topik temu duga representatif

Temu Duga Backend: Bagaimana Anda Memilih 308 atau 301 untuk Migrasi API?

BackendSederhana
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Satu API POST mesti berpindah secara kekal dari `/v1/orders` ke `/v2/orders`. Adakah anda akan memilih 301, 307, atau 308? Terangkan semantik lencongan, keserasian klien, kedidempotensian, dan rollback.

Gesaan dan konteks

Satu API dalam talian mesti memindahkan laluan sumbernya secara kekal daripada /v1/orders kepada /v2/orders. Pemanggil termasuk borang pelayar, klien mudah alih, SDK pihak ketiga, dan pekerja tak segerak (asynchronous workers); permintaan mungkin merupakan POST dengan badan JSON yang besar dan kunci kedidempotensian (idempotency key). Reka bentuk kod status, tingkah laku klien, kebolehcerapan (observability), dan laluan rollback untuk migrasi tersebut.

Soalan ini menguji sama ada anda boleh menggunakan semantik lencongan secara tepat dan mengelakkan kesan sampingan berganda semasa pemindahan API. RFC 9110 mentakrifkan 308 Permanent Redirect; MDN menjelaskan bahawa klien tidak seharusnya menukar kaedah asal atau badan permintaan apabila ia menghantar semula permintaan di lokasi baharu. 301 adalah kekal, tetapi klien terdahulu mempunyai perbezaan keserasian untuk permintaan bukan GET dan mungkin menukar kaedahnya.

Perkara yang diuji oleh penemu duga

Penemu duga mahu anda membezakan antara pemindahan kekal dan sementara, kemudian bertanyakan sama ada pemeliharaan kaedah dan badan permintaan diperlukan. Jawapan yang kukuh membandingkan 301, 302, 307, dan 308, menerangkan sebab POST yang mempunyai kesan sampingan tidak boleh bergantung pada tekaan klien tentang cara mencuba semula, dan merangkumi idempotency key, pengesahan, had masa tamat (timeout), dan rollback.

Mereka juga menjangkakan anda mempertimbangkan sempadan kepercayaan Location, kelayakan rentas asal (cross-origin credentials), penyebaran cache, had lencongan SDK, dan klien yang tidak menyokong 308. Menyebut setakat "308 ialah 301 ditambah pemeliharaan POST" tanpa pelan ujian migrasi adalah tidak lengkap.

Penjelasan yang perlu ditanya terlebih dahulu

Kekekalan dan skop

Sahkan bahawa URL baharu adalah stabil dan sama ada pemindahan tersebut meliputi satu sumber, awalan API, atau asal yang berbeza. Jika sasaran masih boleh berubah, gunakan 307 untuk menyatakan pemindahan sementara dan bukannya mengajar klien dan perantara semantik cache kekal secara pramatang.

Keupayaan klien dan kesan sampingan

Senaraikan pelayar, versi mudah alih, SDK, pengguna barisan gilir (queue consumers), dan rakan kongsi. Tanya sama ada POST membuat pesanan, mengenakan bayaran wang, atau mengeluarkan mesej, dan sama ada pemanggil menghantar idempotency key. Tanpa bukti bahawa ulangan (replay) adalah selamat, lencongan bukanlah arahan cubaan semula tanpa syarat.

Kelayakan, cache, dan rollback

Sahkan skop pengesahan, CORS, proksi, dan tingkah laku CDN untuk kedua-dua hos. Tanya sama ada titik akhir lama boleh terus beroperasi dan sama ada rollback bermakna mengalih keluar lencongan, menukar penghalaan, atau memulihkan pengendali lama.

Jawapan 30 saat

"Mula-mula saya akan mengesahkan sama ada perpindahan itu kekal dan menginventori setiap klien. Untuk perpindahan kekal yang mesti mengekalkan kaedah dan badan POST, saya akan menggunakan 308; perpindahan sementara menggunakan 307. Kod 301 bukan kontrak yang ketat untuk mengekalkan semantik bukan GET merentas klien terdahulu. Pada mulanya saya akan memproksi titik akhir lama ke pengendali baharu, menggunakan semula satu idempotency key untuk setiap kesan sampingan, dan menyekat hos Location serta pemajuan kelayakan. Semasa fasa kenari (canary), saya akan menjejaki kadar ikut 3xx, penciptaan pendua, 4xx/5xx, saiz badan, dan versi SDK. Jika isyarat merosot, saya akan berhenti menghantar 308 dan mengekalkan keupayaan titik akhir lama untuk beroperasi."

Analisis terperinci langkah demi langkah

Langkah 1: Pilih kod status dengan tepat

308 bermaksud perpindahan kekal dan mengekalkan kaedah serta badan permintaan; 307 adalah sementara dan juga mengekalkannya. 301 adalah kekal, tetapi tidak semua klien terdahulu mengekalkan kaedah seperti POST, jadi ia bukan kontrak migrasi POST yang ketat. 302 juga tidak sepatutnya membawa jaminan tersebut.

Langkah 2: Rawat replay sebagai kekangan utama

Oleh kerana 308 boleh menyebabkan klien menyerahkan keseluruhan badan permintaan sekali lagi, kedua-dua titik akhir mesti mengenali arahan perniagaan yang sama melalui idempotency key yang sama. Sebelum melaksanakan kesan sampingan, pelayan mengesahkan kunci terhadap ringkasan (digest) permintaan; kunci yang sama dengan parameter berbeza menjadi konflik dan bukannya pesanan kedua. Klien masih mengikut belanjawan cubaan semulanya selepas timeout dan tidak boleh mengikut 308 selama-lamanya.

Langkah 3: Lepaskan secara berperingkat dan perhatikan

Pastikan alamat baharu berfungsi secara langsung sebelum menghalakan alamat lama melalui proksi yang boleh dicerap atau respons 308. Laksanakan pelepasan kenari mengikut versi SDK, asal sumber, dan kaedah. Rekod panjang rantaian lencongan, kegagalan mengikut lencongan, kesan sampingan berganda, kependaman sasaran, kegagalan pengesahan, dan saiz badan. Bagi klien yang tidak menyokong 308, kekalkan proksi sebelah pelayan jangka pendek dan bukannya menukar secara senyap kepada 301 sambil menganggap tingkah lakunya setara.

Langkah 4: Kendalikan keselamatan, caching, dan rollback

Location hanya boleh menghala ke sasaran yang berada dalam senarai dibenarkan (allow-list). Nilai semula kuki, Authorization, dan CORS sebelum lompatan rentas asal supaya kelayakan tidak sampai ke hos yang tidak dipercayai. Tetapkan tetingkap cache CDN dan klien secara eksplisit, bermula dengan tempoh singkat semasa pengesahan dan memanjangkannya secara beransur-ansur. Semasa rollback, berhenti mengeluarkan lencongan baharu dan biarkan titik akhir lama menerima idempotency key yang sama; hasil yang telah ditulis pada titik akhir baharu tidak boleh 'dibuat asal' hanya dengan menukar laluan kembali.

Contoh jawapan berkualiti tinggi

Saya akan menganggap ini sebagai soalan protokol dan migrasi, bukan latihan memilih nombor semata-mata. Bagi pemindahan kekal yang mana kaedah dan badan POST mesti dikekalkan, saya memilih 308; untuk peralihan trafik sementara, saya memilih 307. 301 sesuai untuk banyak perpindahan URL halaman web, tetapi ia tidak memberikan jaminan pemeliharaan kaedah ketat yang saya perlukan untuk API bukan GET.

Sebelum pelancaran, kedua-dua URL menyokong pengesahan, pengesahan permintaan, dan kontrak idempotency-key yang sama. Titik akhir lama pada mulanya memproksi ke pengendali baharu dengan log lengkap, dan kunci yang sama serta digest permintaan hanya boleh menghasilkan satu kesan sampingan. Saya kemudiannya melaksanakan kenari 308 mengikut versi klien, menyekat hos sasaran, menyemak semula kelayakan rentas asal, dan mengesahkan tingkah laku CDN, SDK, serta pengguna barisan gilir.

Saya memantau kadar ikut lencongan, panjang rantaian, penciptaan pendua, ralat sasaran, kegagalan pengesahan, dan saiz badan. Jika klien lama tidak memahami 308, saya mengekalkan proksi titik akhir lama dan bukannya menurunkan taraf secara senyap kepada 301. Semasa insiden berlaku, saya menghentikan 308, mengekalkan titik akhir lama dan rekod kedidempotensian, memulihkan penghalaan, serta menyelaraskan hasil perniagaan yang selesai mengikut ID permintaan.

Kesilapan lazim

  • Mengembalikan 301 untuk setiap perpindahan → Klien terdahulu mungkin menukar POST kepada kaedah lain atau menggugurkan badan permintaan → Gunakan 308 untuk pemindahan API kekal yang memerlukan pemeliharaan, kemudian sahkan klien.
  • Melaksanakan kesan sampingan sekali lagi selepas melihat 308 → Lencongan, had masa tamat, dan cubaan semula klien boleh menggandakan permintaan cipta → Gunakan idempotency key, digest permintaan, dan belanjawan cubaan semula yang terikat.
  • Menganggap 307 sebagai kekal → Keadaan sementara boleh kekal lama dalam cache atau konfigurasi SDK, menjadikan rollback lebih sukar → Gunakan 307 untuk peralihan sementara dan buat keputusan mengenai 308 hanya selepas penstabilan.
  • Mengabaikan risiko Location rentas asal → Kuki atau Authorization mungkin sampai ke sasaran yang tidak dipercayai → Sahkan senarai dibenarkan, dasar kelayakan, dan CORS secara bersama.
  • Hanya melihat kiraan 3xx → Kegagalan mengikut lencongan SDK lama dan penulisan pendua kekal tidak kelihatan → Gabungkan kadar ikut lencongan, ralat, dan hasil kesan sampingan mengikut versi klien.

Soalan susulan

Soalan susulan 1: Mengapa tidak mengembalikan 200 daripada URL lama dan menyatakan URL baharu dalam badan respons?

Cara itu tidak membenarkan klien generik, cache, atau SDK berhijrah secara automatik, dan tidak menyatakan bahawa sumber tersebut telah berpindah secara kekal. Proksi sebelah pelayan boleh dikekalkan semasa peralihan, tetapi kontrak migrasi masih memerlukan status dan header Location yang eksplisit sambil merekodkan sama ada pemanggil benar-benar telah bertukar.

Soalan susulan 2: Bolehkah 308 memajukan Authorization tanpa perubahan ke hos baharu?

Bukan secara lalai. Mula-mula pastikan bahawa kedua-dua hos berkongsi sempadan yang dipercayai; jika tidak, minta klien mendapatkan atau menghantar kelayakan secara eksplisit untuk hos sasaran. Pelayan mesti menolak nilai Location yang dikawal pengguna untuk mengelakkan open redirect dan kebocoran kelayakan.

Soalan susulan 3: Bagaimana jika klien lama tidak menyokong 308 langsung?

Kekalkan proksi sebelah pelayan untuk titik akhir lama atau kembalikan respons keserasian berdasarkan keupayaan klien yang diketahui sehingga versi lama ditamatkan. Proksi mesti menggunakan semula idempotency key permintaan dan mempunyai tarikh persaraan; anda tidak boleh mendakwa setiap klien akan melayan 308 seperti 301 tanpa bukti.

Soalan susulan 4: Adakah rollback hanya sekadar menukar 308 kembali kepada 200?

Lakukan juga penyelarasan pesanan, peristiwa, dan rekod audit yang telah ditulis oleh titik akhir baharu. Hentikan lencongan baharu dan pulihkan titik masuk lama, kemudian pastikan kedua-dua laluan membaca sumber kebenaran (source of truth) yang sama supaya penulisan tidak berpecah atau bertindih. Sahkan kesan sampingan yang telah selesai mengikut ID permintaan dan idempotency key selepas penghalaan dipulihkan.

Sumber awam

Soalan berkaitan