HTTP atsakymo kodas POST, kai išteklius jau yra

Sukuriu serverį, kuris leidžia klientams saugoti objektus. Šie objektai yra visiškai pastatyti kliento pusėje, su objekto identifikatoriais, kurie yra pastovūs visam objekto gyvavimo ciklui.

Apibrėžiau API, kad klientai galėtų kurti arba keisti objektus naudodami PUT:

 PUT /objects/{id} HTTP/1.1 ... {json representation of the object} 

Identifikatorius {id} yra objekto identifikatorius, todėl jis yra užklausos-URI dalis.

Dabar taip pat svarsto galimybę sukurti klientus naudojant POST:

 POST /objects/ HTTP/1.1 ... {json representation of the object, including ID} 

Kadangi POST suprantama kaip „pridėti“ operacija, nesu tikras, ką daryti, jei objektas jau yra. Ar turėčiau apdoroti užklausą kaip pakeitimo užklausą, ar turiu grąžinti klaidos kodą (kuris)?

454
30 сент. nustatė vmj 30 sep . 2010-09-30 00:26 '10 - 0:26 2010-09-30 00:26
@ 12 atsakymų

Mano supratimas apie 409 Conflict yra tinkamiausias, bet retai pasitaiko laukinėje gamtoje:

Prašymas negalėjo būti užbaigtas dėl prieštaravimo dabartinei išteklių būsenai. Šis kodas leidžiamas tik tais atvejais, kai tikimasi, kad vartotojas galės išspręsti konfliktą ir iš naujo pateikti prašymą. Atsakymo įstaiga turi turėti pakankamai informacijos, kad vartotojas galėtų atpažinti konflikto šaltinį. Idealu atveju atsakymo objektas turi pakankamai informacijos, kad vartotojas ar vartotojo agentas galėtų išspręsti problemą; tačiau tai gali būti neįmanoma ar reikalinga.

Dažniausiai konfliktai atsiranda atsakant į PUT užklausą. Pvz., Jei buvo naudojamas versijas ir PUT objektas buvo įtrauktas į išteklių, kurie prieštarauja ankstesnio (trečiosios šalies) užklausai, pakeitimus, serveris gali naudoti 409 atsakymą, nurodydamas, kad jis negali vykdyti užklausos. Atsakymo objekto atveju gali būti, kad yra dviejų skirtingų versijų skirtumų sąrašas formatu, kurį apibrėžia turinio tipo atsakymas.

544
30 сент. Wrikken atsakė 30 rugsėjo. 2010-09-30 00:31 '10 - 0:31 2010-09-30 00:31

Asmeniškai aš einu su „WebDAV 422 Unprocessable Entity .

REST šablonai jį apibūdina kaip

422 Unprocessable Entity būsenos kodas reiškia, kad serveris supranta užklausos objekto turinio tipą (todėl 415 Unsupported Media Type būsenos kodas yra netinkamas) ir užklausos objekto sintaksė yra teisinga (taigi 400 Bad Request būsenos kodas yra netinkamas), bet negalėjo apdoroti turinio instrukcijas.

41
30 сент. Gareth atsakymas 2010-09-30 00:44 '10 - 0:44 2010-09-30 00:44

Pagal RFC 7231 galite naudoti 303 Žr. Kita . Jei POST apdorojimo rezultatas yra lygiavertis esamo išteklių reprezentavimas.

33
09 нояб. Atsakymas pateikiamas Nullius lapkričio 9 d. 2016-11-09 12:54 '16 at 12:54 2016-11-09 12:54

Vėliau žaidime galbūt, bet aš suklupau į šią semantinę problemą, bandydamas padaryti REST API.

Norėčiau šiek tiek pasakyti apie „Wrikken“ atsakymą, manau, kad galite naudoti arba 409 Conflict arba 403 Forbidden priklausomai nuo situacijos - trumpai tariant, naudokite klaidą 403, kai vartotojas nieko negali išspręsti konflikto ir užbaigti užklausą (pvz., negali išsiųsti DELETE užklausos aiškiai ištrinti šaltinį) arba naudoti 409, jei ką nors galima padaryti.

10.4.4 403 Draudžiama

Serveris suprato prašymą, tačiau atsisako jį vykdyti. Autorizacija nepadės, ir prašymas NEGALIMA kartoti. Jei užklausos metodas nebuvo HEAD, o serveris nori viešai paskelbti, kodėl prašymas nebuvo įvykdytas, TURI aprašyti atsisakymo priežastį juridiniame asmenyje. Jei serveris nenori, kad ši informacija būtų prieinama klientui, būsenos kodas yra 404 (nerastas).

Kažkas šiuo metu sako „403“, o problema, susijusi su leidimais ar autentifikavimu, atsimena, tačiau specifikacijoje teigiama, kad iš esmės serveris klientui sako, ką jis neketins daryti, neprašykite jo dar kartą, ir todėl klientas neturėtų .

Dėl PUT vs POST ... POST turėtų būti naudojamas kuriant naują išteklių pavyzdį, kai vartotojas neturi priemonių, kad sukurtų ar ne. PUT naudojamas, kai žinomas išteklių identifikatorius.

9.6 PUT

...

Pagrindinis skirtumas tarp POST ir PUT užklausų atsispindi kitoje užklausos-URI vertėje. POST užklausos URI identifikuoja šaltinį, kuris tvarkys prijungtą organizaciją. Šis išteklius gali būti duomenų priėmimo procesas, vartai į kitą protokolą arba vienas subjektas, kuris priima anotacijas. Priešingai, UUT prašyme PUT nurodo objektą, pridėtą prie užklausos - vartotojo agentas žino, kas yra URI, ir serveris NEGALIMA bandyti taikyti užklausą kitam ištekliui. Jei serveris nori, kad prašymas būtų taikomas kitam URI,

jis turi išsiųsti 301 (perkelti nuolatinį) atsakymą; vartotojo agentas GALI tada nuspręsti, ar peradresuoti užklausą.

9
25 дек. Atsakymas duotas p0lar_bear 25 Dec. 2015-12-25 01:40 '15 - 1:40 2015-12-25 01:40

„302 Rasta“ man atrodo logiška. RFC 2616 sako, kad į jį gali būti atsakyta kitiems nei GET ir HEAD užklausoms (ir tai, žinoma, apima POST)

Tačiau jis vis tiek neleidžia lankytojui eiti į šį URL, kad gautų šį „rastą“ išteklių, RFC. Jei norite, kad jis tiesiogiai pasiektų tikrąjį URL „Rasta“, turėtumėte naudoti „303 See“ Kita ", kuri yra prasminga, tačiau dar vienas skambutis GET šį URL. Gera pusė, šis GET gali būti išsaugotas talpykloje.

Manau, norėčiau naudoti „303 Žr. Kitas“ . Nežinau, ar galiu atsakyti su kūnu rastu „dalyku“, bet norėčiau tai padaryti, kad būtų išsaugotas vienas atvirkštinis judėjimas serveryje.

UPDATE :. Perskaičius RFC, vis dar manau, kad kodas, kuris neegzistuoja "4XX + 303", turėtų būti teisingas. Tačiau „409 Konfliktas“ yra geriausias esamas atsakymo kodas (kaip nurodyta @Wrikken), galbūt įtraukiant vietovės antraštę, rodančią esamą išteklių.

9
16 мая '12 в 12:25 2012-05-16 12:25 atsakymą pateikė alanjds gegužės 16, 12, 12:25 2012-05-16 12:25

Nemanau, kad turėtumėte tai padaryti.

POST, kaip žinote, modifikuoja kolekciją ir naudojamas naujam elementui sukurti. Taigi, jei siunčiate identifikatorių (manau, kad tai nėra gera idėja), turėtumėte pakeisti kolekciją, t. Y. Pakeiskite elementą, tačiau tai paini.

Naudokite jį pridėti elementą be ID. Tai yra geriausia praktika.

Jei norite nustatyti UNIQUE apribojimą (ne identifikatorių), galite atsakyti į 409, kaip galite padaryti PUT užklausose. Bet ne identifikatorius.

7
30 сент. Atsakyti Alfonso Tienda 30 rugsėjis 2014-09-30 13:12 '14, 12:12 pm 2014-09-30 13:12

Manau, kad REST jums reikia priimti sprendimą dėl šios konkrečios sistemos elgesio, ir šiuo atveju manau, kad „teisingas“ atsakymas būtų vienas iš dviejų čia pateiktų atsakymų. Jei norite, kad prašymas būtų sustabdytas ir elgtųsi taip, tarsi klientas padarė klaidą, kurią jis turi ištaisyti prieš tęsdamas, naudokite 409. Jei konfliktas tikrai nėra toks svarbus ir jis nori išsaugoti užklausą, tada atsakykite peradresuodami klientą į rastą į objektą. Manau, kad teisingi REST API turėtų nukreipti (arba bent suteikti vietos antraštę) šiam ištekliui GET galutiniam taškui po POST, taigi šis elgesys suteiks nuoseklią patirtį.

EDIT: Taip pat verta paminėti, kad turėtumėte apsvarstyti PUT, nes pateikiate identifikatorių. Tada elgesys yra paprastas: „Man nerūpi, kas ten yra dabar, įdėkite šį dalyką ten“. Vertė, jei nieko nėra, bus sukurta; jei yra kažkas, tai bus pakeista. Manau, kad POST yra tinkamesnis, kai serveris valdo šį identifikatorių. Abiejų sąvokų atskyrimas iš esmės nurodo, kaip ją spręsti (t. Y. PUT yra idempotentas, todėl visada turėtų dirbti tol, kol bus patikrinta naudingoji apkrova, todėl POST visada sukuria, jei yra identifikatorių susidūrimas, tada 409 aprašys konfliktą).

3
27 окт. atsakymas duotas Sinaesthetic 27 spalis. 2016-10-27 07:51 '16 at 7:51 am 2016-10-27 07:51

Kaip apie 418 grąžinimą?

Kadangi klientas prašo išsaugoti serverio jau egzistuojantį objektą, serveris pagaliau supyksta ir manys, kad tai yra arbatinukas ir grąža: 418 I'm a teapot .

Literatūra:

3
20 июля '17 в 23:39 2017-07-20 23:39 Atsakymą pateikė „ Ruffp “ liepos 17 d. 17 val. 23:39 2017-07-20 23:39

Kodėl ne 202 Priimta ? Tai yra OK užklausa (200 sekundžių), kliento klaidų nebuvo (400).

Nuo 10 valstybės kodo apibrėžimų :

"202 gautas. Prašymas priimtas apdoroti, tačiau apdorojimas nėra baigtas."

... nes ji neturėjo būti baigta, nes ji jau egzistavo. Klientas nežino, kad jis jau egzistuoja, jie nieko nepadarė.

Aš linkiu mesti 202 ir grįžti panašaus turinio, kurį GET /{resource}/{id} sugrįš.

2
18 марта '16 в 1:12 2016-03-18 01:12 atsakymą pateikė „ Phillip Harrington“ kovo 18 d. 16 d. 1:12 2016-03-18 01:12

Kitas galimas gydymas yra PATCH naudojimas. PATCH yra apibrėžiamas kaip kažkas, kuri keičia vidinę būseną ir neapsiriboja vien pridėjimu.

PATCH išsprendžia problemą leisdama jums atnaujinti jau esamus elementus. Žr. RFC 5789: PATCH

2
07 сент. Atsakymą pateikė Martin Kersten 07 Sep 2015-09-07 14:33 '15 - 14:33 2015-09-07 14:33

Pasiklydo šiuo klausimu, patikrindamas teisingą kodą dviem egzemplioriams.

Atsiprašau, mano nežinojimas, bet nesuprantu, kodėl visi ignoruoja kodą „300“, kuris aiškiai reiškia „daugialypį pasirinkimą“ arba „dviprasmišką“

Mano nuomone, tai būtų idealus kodas norint sukurti nestandartinę ar specifinę sistemą savo reikmėms. Aš taip pat blogai!

https://tools.ietf.org/html/rfc7231#section-6.4.1

1
02 янв. Atsakymas pateiktas Hitinui 02 Jan. 2017-01-02 17:01 '17, 17:01 pm 2017-01-02 17:01

Ką apie 208 - http://httpstatusdogs.com/208-already-reported ? Ar tai yra galimybė?

Mano nuomone, jei vienintelis dalykas, kad yra pasikartojimo šaltinis, tada klaidos neturėtų būti keliamos. Galų gale, kliento pusėje ar serveryje nėra klaidų.

1
31 июля '15 в 21:07 2015-07-31 21:07 atsakymas pateikiamas Fernando Ferreira liepos 15 d. 15:07 2015-07-31 21:07

Kiti klausimai apie „ žymes arba „ Užduoti klausimą“