Bayangkan sebuah API untuk mengidentifikasi apakah seseorang telah memilih hewan roh mereka. Mereka hanya dapat memiliki nol atau satu binatang roh.
Saat ini:
/person/{id}/selectedSpiritAnimal
ketika mereka telah memilih binatang, kembalikan http 200 dan {selectedAnimal:mole}
tetapi ketika mereka tidak memiliki pilihan itu mengembalikan http 404.
Ini membuat hewan roh saya tidak bahagia karena kami mewakili masalah domain yang valid - karena belum memilih hewan roh - sebagai kesalahan HTTP.
Plus, sebagai bisnis - erm Sprit-Animal-Hampers-R-us - kami ingin tahu ketika seseorang tidak memiliki pilihan sehingga kami dapat meminta mereka.
Apa tanggapan yang lebih baik di sini:
HTTP 200 dan {selectedAnimal:null}
atau bahkan lebih eksplisit
HTTP 200 dan {selectedAnimal:null, spiritAnimalSelected: false}
Atau lebih baik mengembalikan 404? Karena seperti this image has not yet been uploaded
ketika melihat gambar secara online akan menjadi 404. this person has not selected a spirit animal
mungkin 404
Pertanyaan ini ini telah diusulkan sebagai duplikat tetapi pertanyaan itu membahas URL yang valid yang diminta ketika aplikasi telah dikonfigurasi untuk tidak mengizinkan perubahan yang diwakili oleh URL.
Sedangkan di sini saya melihat bagaimana seseorang mewakili sumber daya di mana ketiadaan sumber daya itu bermakna. Yaitu sah bagi klien untuk meminta URL dan jawabannya adalah Anda telah berhasil meminta sumber daya yang mewakili tidak adanya sesuatu.
Jadi ini bukan 'logika bisnis' melainkan keadaan di mana ketiadaan sesuatu memiliki makna (mungkin karena banyak rekan saya berpendapat bahwa 404 masih benar) tetapi saya tidak yakin bagaimana memetakan itu ke spek.
Sangat sulit untuk memilih jawaban. Saya telah berubah pikiran beberapa kali selama pembicaraan di sini dan yang sedang berlangsung di tempat kerja.
Hal yang menentukan bagi saya di sini adalah bahwa spesifikasi mengatakan bahwa 4xx adalah ketika klien melakukan kesalahan . Dalam hal ini klien telah diberitahu untuk mengharapkan respons dari urlSpiritAnimal yang dipilih sehingga belum keliru.
Konsensus di antara rekan-rekan saya adalah bahwa ini adalah gejala dari desain API yang buruk
Mungkin akan lebih baik jika kita hanya meminta / orang / {id} dan mengembalikan seperangkat hubungan tautan untuk orang tersebut ... maka jika Anda tidak diberi tautan / terpilihSpiritAnimal (ketika seseorang tidak memiliki pilihan) tetapi Anda sebut saja demikian maka 404 masuk akal. Atau Anda menerapkan respons sebagian dan membiarkan / orang / {id} mengembalikan dokumen yang lebih lengkap kecuali klien meminta subset data
Jawaban:
Kode HTTP 4xx mungkin bukan pilihan yang tepat untuk skenario ini. Anda menyatakan bahwa tidak memiliki hewan roh nol adalah keadaan yang valid, dan rute API
person/{id}/selectedSpiritAnimal
akan menjelaskan apakah orangid
tersebut memiliki atau tidak.Respons HTTP 4xx dicadangkan untuk situasi ketika klien telah melakukan sesuatu yang salah dalam permintaan (lihat arsip spesifikasi asli w3 ). Tetapi klien membuat permintaan yang valid, apakah seseorang
id
memiliki hewan roh atau tidak .Jadi saya condong ke solusi kedua menggunakan tubuh JSON yang diformat dengan baik dalam respon dan kode HTTP 2xx.
Sekarang jika Anda mendapatkan permintaan seperti itu dan ternyata orang
id
itu tidak ada, kode 4xx lebih masuk akal.sumber
cases in which the client seems to have erred
, tetapi di sisi lain 404 langsung mengatakanThe server has not found anything matching the Request-URI
. Anda dapat mempertimbangkan meminta sesuatu yang tidak ada kesalahan klien. Saya mengerti orang yang tidak ada vs sub prop tidak ada, tapi itu bisa diindikasikan sebagai pesan respon. 204 juga tampaknya relevan, karena entitas itu ada, tetapi tidak memiliki konten untuk sub properti.Izinkan saya memperkenalkan Anda kepada Model Kematangan Richardson .
Masalah Anda adalah bahwa Anda mewakili dua sumber daya sebagai satu, di mana Anda harus benar-benar memiliki dua sumber daya yang memiliki hubungan yang ditunjukkan oleh hypermedia. Menggunakan hypermedia untuk menggambarkan hubungan adalah level 3 Rest yang mulia.
Orang Anda harus hidup di bawah URI
/person/{id}
dan hewan itu harus hidup di bawah/spiritanimal/{id}
. Orang tersebut harus menunjukkan bahwa ia memiliki hewan roh dengan menggunakan tautan ke hewan tersebut.Mari kita bayangkan seseorang bernama Bob, yang memiliki id 123 dan binatang roh Unicorn.
GET /person/123
akan kembali;
Sekarang siapa pun yang membaca orang 123 akan tahu bahwa mereka memiliki binatang roh, dan memiliki URI di mana mereka dapat memperoleh lebih banyak informasi tentangnya.
GET /spitiranimal/789
mungkin kembali
Sekarang mari kita bayangkan seseorang bernama Fred, yang memiliki id 456 dan tidak memiliki binatang roh.
GET /person/456
akan kembali;
Sekarang siapa pun yang membaca orang 456 akan tahu bahwa mereka tidak memiliki binatang roh, karena tidak ada tautan. Tidak perlu menggunakan kode status HTTP untuk mewakili kurangnya hubungan.
sumber
Ini adalah url yang tepat untuk mendapatkan hewan roh; oleh karena itu, kesalahan 404 tidak pantas. 404 adalah untuk merepresentasikan masalah teknis, bukan masalah logika.
Solusi yang tepat adalah mengembalikan http 200 dan
{"selectedAnimal": null}
Anda harus memiliki metode web terpisah
/person/{id}/hasSelectedSpiritAnimal
yang mengembalikan{"isSpiritAnimalSelected": false}
. Di balik layar, mungkin atau mungkin tidak membuat panggilan metode yang sama, hanya mengembalikan false jika null, tetapi itu terserah dia yang memutuskan, bukan kode pengkonsumsi.Lebih baik untuk menghindari menggabungkan permintaan yang terpisah menjadi satu metode web tanpa alasan kuat untuk melakukannya, bahkan jika permintaan itu terkait erat.
sumber
When you said "the spirit animal is not currently on file", it seemed quite similar to me to "there is no content"
Tidak ada konten berarti tidak ada konten . yaitu: mengembalikan "". Keduanya sama sekali tidak mirip. "Binatang roh saat ini tidak ada dalam arsip" sangat berbeda dari "".Apa yang diwakili oleh titik akhir Anda bukan hanya binatang; itu binatang atau kurang. Ini nilai terbaik yang diwakili oleh
Optional
/Maybe
/Nullable
/ dll.Jadi nilai yang sah (seperti pada 200 OK) mungkin:
{'animal': <some animal>, 'selected': true}
{'animal': null, 'selected': false}
Saya bisa membayangkan bahwa
DELETE
metode, ketika diterapkan ke titik akhir, dapat diatur'selected'
kefalse
lagi, yaitu, unset hewan yang dipilih.Anda dapat, tentu saja, menjatuhkan
'selected'
kunci di sini, itu hanya ditampilkan untuk kejelasan; string vsnull
sudah cukup untuk membedakannya.sumber
Anda harus menggunakan 404.
Karena Anda membuat antarmuka pemrograman, bukan antarmuka manusia, teks 404 adalah opsional.
Saya lebih suka ini karena saya lebih suka protokol standar sebanyak mungkin. HTTP memiliki cara untuk merepresentasikan non-keberadaan, dan itulah yang akan saya gunakan.
EDIT: Misalkan Anda menambahkan fitur di mana pengguna dapat memilih apakah akan membagikan hewan roh mereka, dan seseorang tidak membagikannya. Apakah Anda akan mengembalikan 200 OK
null
, atau 200 OK"Unauthorized
? Atau apakah Anda akan menggunakan standar 401 Unauthorized / 403 Forbidden? Ini sepertinya analog dengan tidak memilih yang pertama kali.Atau, jika Anda ingin menggunakan 200 OK + JSON, Anda harus kembali
null
.Jaga kebersihan. Buat lebih banyak pembungkus hanya jika perlu.
sumber
null
(tidak memiliki nilai). Ini berbeda dari klien yang meminta sesuatu yang tidak memiliki slot untuk menyimpan nilai. Anda tidak akan menyarankan melempar denganAttributeError
Python ketika nilainya terjadiNone
; yang akan membuat antarmuka tidak praktis dan sulit untuk dikerjakan. Lebih pragmatis, banyak klien API HTTP dapat mengubah 404 menjadi mekanisme penanganan kesalahan standar bahasa (kode kesalahan, pengecualian, jenis kesalahan), yang berarti Anda harus menekan kesalahan yang tidak berhubungan./person/{id}/selectedSpritAnimal
, amati kesalahan ketikSprit
)./person/{id}/isSpiritAnimalSelected
yang akan memberi tahu klien apakah ada yang dipilih. Menurut saya contoh klasik yang sama untuk menguji apakah suatu file ada sebelum membacanya. Baca saja file tersebut dan tangani kesalahan ENOENT jika harus dibuang./person/{id}/selectedSpiritAnimal
itu dimaksudkan untuk digunakan bahkan jika hewan roh tidak ada. Ini berarti bahwa HTTP 4xx salah, bila digunakan dalam kasus seperti itu. Op juga dengan benar menyatakan bahwa ini mungkin bau desain API yang buruk.