Topik temu duga representatif

Temuduga backend: Bilakah sesuatu API patut mengembalikan HTTP 202 Accepted?

BackendSederhana
Pasukan Editorial Offer.ccDiterbitkan Dikemas kini

Soalan

Satu POST memulakan kerja yang mungkin mengambil masa lebih lama daripada had masa tamat (timeout) permintaan. Bilakah API patut mengembalikan 202 Accepted, apakah yang patut terkandung dalam respons, dan bagaimanakah anda menjadikan percubaan semula serta kegagalan boleh diperhatikan?

Arahan dan latar belakang

Anda bertanggungjawab terhadap POST /exports untuk eksport berskala besar. Permintaan tersebut mengesahkan input dan memulakan kerja, tetapi proses eksport mungkin mengambil masa beberapa minit. Penemu duga bertanya sama ada perlu mengembalikan 200, 201, atau 202, dan bagaimana klien mengetahui hasil akhirnya.

Andaikan pelayan boleh menyimpan rekod eksport secara kekal dan memasukkan kerja ke dalam barisan giliran (enqueue work). Klien mungkin mengalami had masa tamat dan mengulangi permintaan. Jawapan mestilah mentakrifkan kontraknya, bukan sekadar menamakan kod status.

Perkara yang diuji oleh penemu duga

  • Sama ada anda membezakan antara "sumber dicipta" dengan "permintaan diterima untuk pemprosesan kemudian".
  • Sama ada anda memodelkan sumber status yang tahan lama (durable), keadaan terminal (terminal states), dan butiran ralat.
  • Sama ada percubaan semula boleh mencipta dua eksport atau menyebabkan kehilangan respons asal.
  • Sama ada kemas kini barisan giliran dan pangkalan data adalah boleh dipercayai tanpa berpura-pura mempunyai transaksi teragih (distributed transaction).

Soalan penjelasan sebelum menjawab

  1. Adakah POST mencipta sumber eksport yang tahan lama serta-merta? Jika ya, 201 Created boleh menerangkan sumber tersebut; jika tidak, 202 boleh memperakui kerja yang telah diterima.
  2. Bolehkah permintaan logik yang sama dicuba semula? Jika ya, wajibkan kunci keidempotenan (idempotency key) atau ID operasi yang disediakan oleh pemanggil.
  3. Adakah klien memerlukan pengundian (polling), webhook, atau kedua-duanya? Ini mengubah perwakilan status dan kontrak pemberitahuan.
  4. Apakah peraturan pengekalan (retention) dan pembenaran (authorization) bagi fail yang dieksport? Kerja yang selesai bukanlah kebenaran untuk mendedahkan hasilnya kepada setiap pemanggil.

Kerangka jawapan 30 saat

"Saya mengembalikan 202 Accepted hanya apabila pemprosesan ditangguhkan dan hasil akhir belum sedia. Saya mencipta rekod kerja yang tahan lama terlebih dahulu, kemudian mengembalikan URI statusnya serta pengecam operasi. Klien mengundi URI tersebut dengan backoff atau menerima panggilan balik (callback) yang disahkan. Kunci keidempotenan memetakan percubaan semula kepada kerja dan respons yang sama. Kerja tersebut bergerak melalui keadaan yang eksplisit seperti queued, running, succeeded, dan failed; pekerja (worker) dan outbox boleh dicuba semula, dan titik akhir status kekal sebagai punca kebenaran tunggal (source of truth)."

Perbincangan mendalam langkah demi langkah

1. Pilih status berdasarkan kitaran hayat sumber

200 OK bermaksud permintaan telah selesai dengan suatu perwakilan. 201 Created bermaksud sumber telah dicipta dan sepatutnya boleh dikenal pasti. 202 Accepted bermaksud permintaan telah diterima, manakala pemprosesan mungkin belum dimulakan atau belum selesai; ia tidak menjanjikan kejayaan akhirnya.

Jika rekod eksport dicipta secara segerak (synchronously) dan merupakan sumber yang akan diuruskan oleh pemanggil, saya boleh mengembalikan 201 bersama sumber tersebut. Jika API hanya memperakui kerja dan hasilnya masih belum selesai, 202 berserta URI pemantau adalah lebih jelas. Pilihan ini mengikut kitaran hayat yang boleh diperhatikan, bukan sekadar fakta bahawa barisan giliran kebetulan wujud.

2. Jadikan respons boleh diambil tindakan

Kembalikan ID operasi, URL status, dan perwakilan dengan state, cap masa (timestamps), serta petunjuk percubaan semula yang selamat. Respons minimum boleh kelihatan seperti ini:

http
HTTP/1.1 202 Accepted
Location: /exports/exp_123
Retry-After: 5
Content-Type: application/json

{"id":"exp_123","state":"queued","status_url":"/exports/exp_123"}

Sumber status hendaklah menggunakan pembenaran pada setiap bacaan. queued dan running adalah bukan terminal. succeeded menyertakan rujukan muat turun jangka pendek; failed menyertakan kod ralat yang stabil dan petunjuk pemulihan tanpa membocorkan surihan tindanan (stack traces). Klien mesti bertoleransi terhadap kehilangan sumber selepas tetingkap pengekalannya tamat.

3. Pastikan percubaan semula menumpu (converge)

Wajibkan Idempotency-Key bagi operasi yang mencipta kerja. Simpan cincangan (hash) bagi permintaan yang berkaitan, ID kerja yang terhasil, dan status respons secara kekal. Kunci berulang dengan permintaan yang sama mengembalikan hasil asal; kunci yang sama dengan permintaan yang berbeza adalah ralat klien. Jangan gunakan tetingkap masa sahaja sebagai peraturan identiti, kerana percubaan semula yang lewat boleh tiba selepas tetingkap tersebut.

API masih boleh menerima dua kunci berbeza untuk dua eksport. Keidempotenan menghalang kerja pendua untuk satu operasi logik; ia tidak menjadikan pekerja beroperasi secara tepat sekali (exactly once).

4. Rapatkan jurang antara pangkalan data dan barisan giliran

Tulis baris eksport dan peristiwa outbox dalam satu transaksi pangkalan data. Relay menerbitkan baris outbox yang belum selesai dan menandakannya sebagai dihantar selepas broker memperakuinya. Ranap sistem (crash) boleh menerbitkan peristiwa yang sama sekali lagi, jadi pengguna (consumer) menggunakan ID eksport sebagai kunci keidempotenan. Ini mengekalkan invarian bahawa kerja yang telah komited akhirnya boleh ditemui tanpa mendakwa bahawa pangkalan data dan broker melakukan komit secara atomik.

Pekerja mengemas kini keadaan dengan peralihan bersyarat, contohnya queued -> running -> succeeded|failed. Percubaan semula yang basi tidak boleh memindahkan succeeded kembali kepada running. Metrik hendaklah mendedahkan usia barisan giliran, usia pelaksanaan, kadar kegagalan terminal, dan kelengahan outbox.

5. Takrifkan pengundian, panggilan balik, dan pembatalan

Titik akhir status menyokong ETag atau versi supaya pengundian boleh menggunakan permintaan bersyarat. Klien menggunakan backoff eksponen dengan petunjuk pelayan dan berhenti mengundi selepas mencapai keadaan terminal. Webhook adalah satu pengoptimuman, bukan satu-satunya cara untuk mengetahui hasilnya: penghantaran boleh gagal, jadi klien mesti membuat penyelarasan dengan membaca sumber status.

Pembatalan ialah arahan yang berasingan, seperti POST /exports/exp_123/cancel. Ia hanya diterima untuk keadaan yang boleh dibatalkan dan ia sendiri bersifat idempoten. Kerja yang telah mencapai succeeded tidak boleh diundur balik oleh pembatalan yang lewat.

Contoh jawapan berkualiti tinggi

Saya terlebih dahulu akan bertanya sama ada rekod eksport merupakan sumber yang dicipta oleh panggilan ini. Jika ya, saya mungkin mengembalikan 201 dan rekod tersebut. Bagi operasi tertangguh yang hasilnya belum sedia, saya mengembalikan 202 bersama ID operasi dan URL status yang disahkan. Saya mewajibkan kunci keidempotenan, menyimpan cap jari (fingerprint) permintaan dan ID kerja, serta mengembalikan perwakilan yang sama untuk percubaan semula.

Transaksi menulis baris eksport dan peristiwa outbox bersama-sama. Relay dan pengguna idempoten mengendalikan penghantaran sekurang-kurangnya sekali (at least once). Mesin keadaan status adalah monotonik: queued, running, kemudian succeeded atau failed. Klien mengundi dengan permintaan bersyarat dan backoff; webhook hanyalah pemecut. Saya menerbitkan usia barisan giliran, kelengahan outbox, dan ralat terminal, serta saya mentakrifkan pengekalan, pembenaran, tamat tempoh muat turun, dan pembatalan secara berasingan. 202 memperakui penerimaan, bukan kejayaan.

Kesilapan biasa

  • Ralat: Menganggap 202 sebagai bukti bahawa kerja akan berjaya → Sebab ia gagal: semantik RFC membenarkan pemprosesan gagal atau tidak pernah bermula → Penyelesaian: dedahkan kegagalan terminal dan tingkah laku pengekalan.
  • Ralat: Hanya mengembalikan 202 tanpa URL pemantau → Sebab ia gagal: klien tidak dapat mengetahui keadaan tanpa membuat tekaan → Penyelesaian: kembalikan sumber status yang disahkan dan ID operasi.
  • Ralat: Bergantung pada penerbitan ke barisan giliran selepas komit pangkalan data → Sebab ia gagal: ranap sistem mencipta kerja yang tidak dapat dilihat oleh mana-mana pekerja → Penyelesaian: gunakan transactional outbox dan relay yang boleh dimainkan semula.
  • Ralat: Menganggap barisan giliran memberikan pelaksanaan tepat sekali (exactly-once) → Sebab ia gagal: percubaan semula dan ranap sistem boleh menduplikasi penghantaran → Penyelesaian: jadikan pengguna idempoten dan peralihan bersyarat.
  • Ralat: Membiarkan setiap penggunaan semula kunci keidempotenan mengembalikan kejayaan → Sebab ia gagal: kunci boleh menyembunyikan permintaan yang telah diubah → Penyelesaian: bandingkan cap jari permintaan dan tolak ketidakpadanan.

Soalan susulan dan jawapan

Patutkah titik akhir ini mengembalikan 201 sebaliknya?

Kembalikan 201 apabila panggilan segerak mencipta sumber eksport yang tahan lama dan boleh mengenal pastinya dengan Location. Kembalikan 202 apabila hasil yang bermakna ditangguhkan dan respons hanya memperakui penerimaan. Sesetengah API boleh menggunakan 201 untuk sumber kerja sementara masih mendedahkan keadaan belum selesai; dokumentasikan sumber mana yang diterangkan oleh status tersebut.

Bagaimana jika klien tidak pernah mengundi?

Kekalkan keadaan kerja secara tahan lama untuk tempoh pengekalan yang didokumentasikan, hantar webhook pilihan yang disahkan, dan benarkan GET kemudian melalui ID operasi. Kegagalan panggilan balik tidak boleh memadamkan satu-satunya laluan status. URL muat turun yang telah tamat tempoh dan pemeriksaan pembenaran masih terpakai apabila klien kembali beberapa hari kemudian.

Bolehkah pekerja mengemas kini kerja sebanyak dua kali?

Ya, penghantaran biasanya sekurang-kurangnya sekali. Gunakan ID eksport yang unik, peralihan keadaan bersyarat, dan penulisan output yang idempoten. Peristiwa succeeded pendua sepatutnya tidak mendatangkan bahaya; peralihan daripada keadaan terminal kembali kepada running hendaklah ditolak dan dilog.

Sumber awam

Soalan berkaitan