Suprasti REST: veiksmažodžiai, klaidų kodai ir autentifikavimas

Ieško būdų API apvynioti aplink numatytas funkcijas mano žiniatinklio programose, duomenų bazėse ir PHP pagrindu.

Aš apsižvalgiau ir radiau keletą skeletų. Be atsakymų į mano klausimą Tonic , man patinka REST struktūros, nes tai labai lengva.

Man patinka tai, kad REST geriausiai tinka jo paprastumui, ir norėčiau sukurti API architektūrą. Stengiuosi suprasti pagrindinius principus ir vis dar nesuprantu. Todėl kelis klausimus.

1. Ar tai teisingai suprantu?

Tarkime, turiu išteklių "naudotojus". Galėčiau konfigūruoti kelis URI, pavyzdžiui:

 /api/users when called with GET, lists users /api/users when called with POST, creates user record /api/users/1 when called with GET, shows user record when called with PUT, updates user record when called with DELETE, deletes user record 

Ar tai yra teisingas „RESTful“ architektūros vaizdas iki šiol?

2. Man reikia daugiau veiksmažodžių

Teoriškai gali pakakti sukurti, atnaujinti ir ištrinti, bet praktiškai reikės daug daugiau veiksmažodžių. Suprantu, kad tai yra dalykai, kuriuos galima integruoti į atnaujinimo užklausą, tačiau jie yra konkretūs veiksmai, galintys turėti tam tikrus grąžinimo kodus, ir aš nenoriu juos visus į vieną veiksmą mesti.

Kai kurie iš jų primena naudotojo pavyzdį:

 activate_login deactivate_login change_password add_credit 

Kaip galiu išreikšti tokius veiksmus kaip „RESTful URL architektūra“?

Mano instinktas būtų, pavyzdžiui, padaryti GET skambutį į URL

 /api/users/1/activate_login 

ir palaukite, kol bus grąžintas būsenos kodas.

Tai skiriasi nuo idėjos naudoti HTTP veiksmažodžius. Ką manote?

3. Kaip grąžinti klaidų pranešimus ir kodus

Didžioji dalis REST grožio atsiranda naudojant standartinius HTTP metodus. Jei įvyksta klaida, pateikiu antraštę su klaidos būsenos kodu 3xx, 4xx arba 5xx. Išsamus klaidos aprašymas, galiu naudoti kūną (dešinėje?). Viskas vyksta gerai. Bet kaip galėtumėte perduoti savo klaidos kodą , kuris išsamiau aprašo, kas negerai (pvz., „Negalėjo prisijungti prie duomenų bazės“ arba „neteisingas prisijungimas prie duomenų bazės“)? Jei jį įdėsiu į kūną kartu su pranešimu, vėliau turiu ją išardyti. Ar yra standartinė pozicija šiai medžiagai?

4. Kaip atlikti autentifikavimą

  • Kaip API pagrįstas autentifikavimas atrodo pagal REST principus?
  • Ar yra kokių nors stiprių prieš sesijų naudojimą, kai autentifikuojamas „REST“ klientas, išskyrus tai, kad tai yra akivaizdus „REST“ principo pažeidimas? :) (tik pusė čia esančių anekdotų, seanso pagrįstas autentifikavimas veiks gerai su mano esama infrastruktūra.)
544
04 янв. nustatė Pekka Jan 04 Jan 2010-01-04 22:55 '10 10:55 val. 2010-01-04 22:55
@ 10 atsakymų

Šį klausimą pastebėjau po poros dienų, bet manau, kad galiu pridėti šiek tiek įžvalgų. Tikiuosi, kad tai gali būti naudinga jūsų atsipalaidavusiai įmonei.


1 punktas: ar aš teisingai suprantu?

Jūs teisingai supratote. Tai teisingas RESTful architektūros vaizdas. Šią matricą iš Vikipedijos galite rasti labai naudinga nustatant jūsų daiktavardžius ir veiksmažodžius:


Dirbant su URI kolekcija : http://example.com/resources/

  • GET . Suraskite kolekcijos narius su savo URI nariais tolesniam navigavimui. Pavyzdžiui, išvardykite visus parduodamus automobilius.

  • PUT . Reikšmė apibrėžiama kaip „visą kolekciją pakeičianti kita kolekcija“.

  • POST . Kolekcijoje sukurkite naują įrašą, kuriame rinkinys automatiškai priskiria identifikatorių. Gautas identifikatorius paprastai įtraukiamas kaip dalis šios operacijos grąžintų duomenų.

  • Išimkite . Reikšmė apibrėžiama kaip „ištrinti visą kolekciją“.


Dirbant su narių URI: http://example.com/resources/7HOU57Y

  • GET : Gaukite gavėjo vaizdą kolekcijos elementui, išreikštam atitinkamu MIME tipu.

  • PUT . Atnaujinkite kolekcijos adreso elementą arba sukurkite jį su nurodytu ID.

  • POST . Jis apdoroja adresuotą elementą kaip atskirą rinkinį ir sukuria naują pavaldinį.

  • REMOVE : ištrinkite kolekcijos adreso elementą.


2 punktas: man reikia daugiau veiksmažodžių

Apskritai, kai manote, kad jums reikia daugiau veiksmažodžių, tai iš tikrųjų gali reikšti, kad reikia iš naujo nustatyti jūsų išteklius. Atminkite, kad REST jūs visada veikia pagal išteklių ar išteklių rinkinį. Tai, ką pasirinkote kaip išteklius, yra labai svarbus jūsų API apibrėžimui.

Įjunkite / išjunkite įvestį . Jei kuriate naują sesiją, gali tekti apsvarstyti „sesiją“ kaip šaltinį. Jei norite sukurti naują seansą, naudokite POST, skirtą http://example.com/sessions/ su kredencialais kūno viduje. Jei norite baigti, naudokite PUT arba DELETE (galbūt priklausomai nuo to, ar norite išsaugoti sesijos istoriją) prieš http://example.com/sessions/SESSION_ID .

Keisti slaptažodį: Šį kartą šaltinis yra „vartotojas“. Jums reikės PUT už http://example.com/users/USER_ID su senais ir naujais kūno slaptažodžiais. Jūs elgiatės su naudotojo ištekliu, o slaptažodis, kurį norite pakeisti, yra tik atnaujinimo užklausa. Tai labai panaši į UPDATE pareiškimą reliacinėje duomenų bazėje.

Mano instinktas būtų skambinti GET į URL, pvz., /api/users/1/activate_login

Tai prieštarauja pagrindiniam REST principui: tinkamas HTTP veiksmažodžių naudojimas. Bet koks GET prašymas neturėtų palikti šalutinio poveikio.

Pavyzdžiui, GET užklausa niekada neturėtų sukurti duomenų bazėje seanso, grąžinti slapuką su nauju sesijos ID arba palikti balansus serveryje. Žodis GET yra panašus į duomenų bazės variklio SELECT pareiškimą. Atminkite, kad atsakymas į bet kurį užklausą naudojant „GET“ veiksmažodį turi būti išsaugotas talpykloje, kai reikalaujama, naudojant tuos pačius parametrus, kaip ir paprašius statinio tinklalapio.


3 punktas. Kaip grąžinti klaidų pranešimus ir kodus

Apsvarstykite HTTP 4xx arba 5xx būsenos kodus kaip klaidų kategorijas. Kūno viduje galite sukurti klaidą.

Nepavyko prisijungti prie duomenų bazės: / Klaidingas prisijungimas prie duomenų bazės . Paprastai šių klaidų tipams turėtumėte naudoti klaidą 500. Tai serverio pusės klaida. Klientas nieko blogo nepadarė. 500 klaidų paprastai laikomos pakartojamomis. tai yra, klientas gali pakartoti tą patį tikslią užklausą ir tikėtis, kad jis bus sėkmingas ištaisius su serveriu susijusias problemas. Įdėkite detales į kūną, kad klientas galėtų mums pateikti tam tikrą kontekstą.

Kita klaidų kategorija yra 4xx šeima, kuri paprastai rodo, kad klientas padarė kažką neteisingo. Visų pirma, ši klaidų kategorija klientui paprastai nurodo, kad nereikia pakartoti prašymo taip, kaip ji yra, nes ji ir toliau nepavyks. tai yra, klientas turi ką nors pakeisti prieš pakartodamas šį prašymą. Pavyzdžiui, į šią kategoriją patenka „Resource not found“ (HTTP 404) arba „Failed request“ (HTTP 400) klaidos.


4 punktas. Kaip atlikti autentifikavimą

Kaip nurodyta 1 veiksme, vietoj vartotojo autentifikavimo galbūt norėsite apsvarstyti galimybę sukurti sesiją. Jums bus išsiųstas naujas „Sesijos ID“ kartu su atitinkamu HTTP būsenos kodu (200: prieiga leidžiama arba 403: prieiga neleidžiama).

Tada paprašysite savo „RESTful“ serverio: „Ar galite gauti išteklių šiai sesijos ID?“.

Nėra patvirtinto režimo. REST neturi būsenos: sukuriate sesiją, prašote iš serverio išteklių, naudodami šį seanso identifikatorių kaip parametrą, o kai atsijungiate, nutraukiate arba nutraukiate sesiją.

569
07 янв. Atsakyti Daniel Vassallo 07 Jan 2010-01-07 22:13 „10, 10:13 PM 2010-01-07 22:13

Paprasčiau tariant, jūs darote viską atgal.

Jūs neturėtumėte kreiptis į tai iš URL, kurį turėtumėte naudoti. Po to, kai nuspręsite, kokie ištekliai reikalingi jūsų sistemai, ir kaip atstovausite šiuos išteklius, taip pat išteklių ir programos būsenos sąveiką, URL bus efektyviai „nemokamai“.

Cituoti Roy Fieldingą

„REST“ API turėtų išleisti beveik visas aprašomas pastangas, kad nustatytų, kokio tipo laikmenos naudojamos atstovauti ištekliams ir taikomosioms programoms, arba apibrėžti išplėstinius ryšių pavadinimus ir (arba) hiperteksto žymėjimą esamiems standartiniams laikmenų tipams. Visos pastangos, apibūdinančios, kaip naudoti dominančius URI, turėtų būti visiškai apibrėžtos laikmenos tipo tvarkymo taisyklėje (ir daugeliu atvejų jau nustatytų laikmenų tipų). [Atsakomybės apribojimas čia reiškia, kad informacija, susijusi su juosta, veda prie sąveikos vietoj hiperteksto.]

Žmonės visada pradeda nuo URI ir tiki, kad tai yra sprendimas, ir tada jie linkę praleisti pagrindinę koncepciją REST architektūroje, visų pirma, kaip minėta pirmiau: "Klaida čia reiškia, kad informacija, susijusi su dažnių juosta, sukelia hiperteksto sąveiką."

Sąžiningai, daugelis žmonių mato nemažai URI ir kai kurių GET, PUT ir POST ir pastebi, kad REST yra lengva. REST nėra lengva. RPC per HTTP yra paprasta: judantys duomenų blokai pirmyn ir atgal yra per HTTP naudingąją apkrovą. Tačiau REST viršija tai. REST yra protokolo agnostikas. HTTP yra labai populiarus ir tinkamas REST sistemoms.

REST gyvena daugialypės terpės tipuose, jų apibrėžimuose ir kaip programa valdo šių išteklių veiksmus per hipertekstą (nuorodos, efektyviai).

REST sistemose yra skirtingas žiniasklaidos tipų supratimas. Kai kurie iš jų renkasi specialiąsias programas, o kiti mėgsta pakelti esamas žiniasklaidos rūšis prie programų tinkamų vaidmenų. Pavyzdžiui, viena vertus, jūs turite tam tikras XML schemas, skirtas jūsų programai, užuot naudodami kažką panašaus į XHTML kaip savo pristatymą, galbūt per mikroformatus ir kitus mechanizmus.

Abu būdai turi savo vietą, manau, kad XHTML labai gerai veikia scenarijuose, kurie sutampa su žmogaus valdomomis ir mašinų valdomomis mašinomis, o pirmieji konkretesni duomenų tipai, kurie, manau, geriau palengvina mašinos ir mašinos sąveiką. Manau, kad gerinant produktų formatą gali būti sunku susitarti dėl turinio. „application / xml + yourresource“ yra daug specifiškesnis kaip medijos tipas, nei „application / xhtml + xml“, nes pastarasis gali būti taikomas daugeliui naudingųjų apkrovų, kurios gali būti arba gali būti, kad mašinos klientas tikrai domina, ir negali nustatyti be introspekcijos.

Tačiau „XHTML“ veikia gerai (žinoma) žiniatinklyje, kurioje žiniatinklio naršyklės ir atvaizdavimas yra labai svarbūs.

Jūsų paraiška padės jums priimti tokius sprendimus.

„REST“ sistemos kūrimo proceso dalis yra pirmos klasės išteklių aptikimas jūsų sistemoje ir išvestiniai paramos ištekliai, reikalingi operacijoms su pagrindiniais ištekliais paremti. Kai ištekliai bus atrasti, tada šių išteklių reprezentacija, taip pat valstybės diagramos, rodančios išteklių srautą per hipertekstą pateikimuose, nes kita užduotis.

Prisiminkite, kad kiekvienas šaltinis, esantis hiperteksto sistemoje, apjungia tiek faktinį išteklių vaizdą, tiek išteklius naudojamus būsenos perėjimus. Apsvarstykite kiekvieną resursą, kuris yra grafikas, ir nuorodos yra eilutės, kurios palieka šį mazgą kitoms valstybėms. Šios nuorodos informuoja klientus ne tik apie tai, kas gali būti padaryta, bet ir dėl to, ko jiems reikia (nes gera nuoroda jungia URI ir reikiamą medijos tipą).

Pavyzdžiui, galite:

 <link href="http://example.com/users" rel="users" type="application/xml+usercollection"/> <link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/> 

Jūsų dokumentuose bus „rel“ laukas, vadinamas „naudotojais“, ir laikmenos tipas „application / xml + youruser“.

Šios nuorodos gali pasirodyti nereikalingos, jos bendrauja su tuo pačiu URI. Bet tai ne.

Taip yra dėl to, kad ryšiui „naudotojai“ ši nuoroda susijusi su naudotojų kolekcija, o jūs galite naudoti vieną sąsają, kad galėtumėte dirbti su kolekcija (GET, kad galėtumėte juos išgauti, DELETE, jei norite ištrinti visus, ir tt)

Jei siunčiate POST į šį URL, turėsite pateikti dokumentą "application / xml + usercollection", kuriame tikriausiai bus tik vienas naudotojo egzempliorius dokumente, kad galėtumėte pridėti vartotoją arba ne, galbūt pridėti keletą kartų. Galbūt jūsų dokumentuose daroma prielaida, kad galite tiesiog perkelti vieno tipo vartotoją vietoj kolekcijos.

Galite matyti, kokia programa turi atlikti paiešką, kaip apibrėžta „paieškos“ nuorodoje ir jos laikmenos tipe. Paieškos laikmenos tipo dokumentacijoje bus nurodyta, kaip tai atsitiks ir ką tikėtis.

Tačiau čia pateiktos išvados yra pačios URI, dažniausiai nesvarbios. Programa valdo URI, o ne klientus. Be kelių „įėjimo taškų“, jūsų klientai turi pasikliauti URI, pateiktais paraiškoje dėl jos veikimo.

Klientas turi žinoti, kaip manipuliuoti ir interpretuoti žiniasklaidos tipus, tačiau jis neturi jaudintis, kur jis eina.

Šios dvi nuorodos yra aktualios klientų akyse:

 <link href="http://example.com/users?search" rel="search" type="application/xml+usersearchcriteria"/> <link href="http://example.com/AW163FH87SGV" rel="search" type="application/xml+usersearchcriteria"/> 

Taigi, sutelkkite dėmesį į savo išteklius. Sutelkite dėmesį į savo valstybės perėjimus programoje ir kaip tai geriausiai pasiekiama.

74
08 янв. Atsakymą pateikė Will Hartung Jan 08 2010-01-08 05:39 '10, 5:39, 2010-01-08 05:39

re 1 : nes dabar tai nuostabu. Nepamirškite grąžinti naujai sukurtą vartotojo URI į Vietos: antraštę kaip dalį POST atsakymo, kartu su 201 sukurtu būsenos kodu.

re 2 : GET aktyvinimas yra bloga idėja, įskaitant veiksmažodį URI yra dizainerio kvapas. Galbūt norėsite grįžti į GET formą. Žiniatinklio programoje tai bus HTML forma su pateikimo mygtuku; jei naudojate API, galbūt norėsite grąžinti vaizdą su URI, kad būtų galima įjungti PUT. Žinoma, šį URI galite įtraukti į naudotojų POST. Naudojant PUT užtikrina, kad jūsų prašymas yra idempotentas, ty jis gali būti saugiai išsiųstas, jei klientas nėra tikras sėkmės. Apskritai, pagalvokite, kokius išteklius galite paversti savo verbais (pvz., „Išplauti veiksmažodžius“). Paklauskite savęs, kokiu būdu jūsų veiksmai yra labiausiai susiję. Pavyzdžiui. change_password → PUT; išjungti → galbūt DELETE; add_credit → POST arba PUT įmanoma. Nukreipkite klientą į atitinkamus URI, įtraukdami juos į savo pareiškimus.

re 3. Nenustatykite naujų būsenos kodų, jei manote, kad jie nėra tokie universalūs, kad jie nusipelno standartizacijos visame pasaulyje. Pabandykite naudoti tinkamiausią būsenos kodą (perskaitykite visus RFC 2616). Į atsakymo instituciją įtraukite papildomą informaciją. Jei tikrai įsitikinote, kad norite pateikti naują būsenos kodą, pagalvokite dar kartą; jei vis dar tikite, įsitikinkite, kad bent jau pasirinkite norimą kategoriją (1xx → OK, 2xx → informacinis, 3xx → peradresavimas, 4xx-> kliento klaida, 5xx klaida → serveris). Ar paminėjau, kad naujų būsenos kodų kūrimas yra bloga idėja?

4. Jei įmanoma, naudokite autentifikavimo sistemą, kuri yra integruota į HTTP. „GData“ patikrinkite „Google“ autentifikavimo metodą. Paprastai nepridėkite API raktų į savo URI. Stenkitės išvengti sesijų, kad padidintumėte mastelį ir palaikykite talpyklą - jei atsakymas į užklausą skiriasi dėl to, kas įvyko anksčiau, paprastai esate susietas su konkrečiu serverio pavyzdžiu. Seminaro būseną daug geriau įterpti į kliento būseną (pvz., Paversti ją vėlesnių užklausų dalimi) arba padaryti ją aiškia, paverčiant ją išteklių (serverio) būsena, t. Pateikite ją su savo URI.

29
04 янв. Atsakymą pateikė Stefan Tilkov 04 sausis 2010-01-04 23:39 '10, 11:39, 2010-01-04 23:39

1. Turite tinkamą idėją, kaip sukurti savo išteklius, IMHO. Aš nieko nekeičiau.

2. Užuot bandę išplėsti HTTP su daugybe veiksmažodžių, apsvarstykite, kuriuos siūlomus veiksmažodžius galima sumažinti iki pagrindinių HTTP metodų ir išteklių. Pavyzdžiui, vietoj veiksmažodžio activate_login galite konfigūruoti tokius išteklius kaip: /api/users/1/login/active , kuris yra paprastas loginis. Norėdami įjungti prisijungimo duomenis, tiesiog PUT dokumentą, kuriame jis sako „tiesa“ arba 1 ar kažką kitą. Norėdami išjungti, PUT dokumentas yra tuščias arba sako 0 arba false.

Panašiai, norėdami pakeisti ar nustatyti slaptažodžius, tiesiog iš PUT į /api/users/1/password .

Kai jums reikia kažką pridėti (pvz., Kreditą), pagalvokite apie POST s. Pvz., Galite sukurti išteklių, pvz., /api/users/1/credits , POST , su įstaiga, kurioje yra pridėtų kreditų. Tą patį išteklių PUT galima naudoti norint perrašyti vertę, o ne pridėti. POST , kurio kūno skaičius neigiamas, atimamas ir pan.

3. Labai patartina neplatinti pagrindinių HTTP būsenos kodų. Jei nerandate tokio, kuris tiksliai atitiktų jūsų padėtį, pasirinkite artimiausią ir padėkite klaidos duomenis į atsakymo įstaigą. Taip pat atminkite, kad HTTP antraštės yra išplėstos; Jūsų programa gali nustatyti visas jums tinkamas antraštes. Pavyzdžiui, viena paraiška, kuriai aš dirbo, keliomis aplinkybėmis sugrįžo į 404 Not Found . Vietoj to, kad priverstumėte klientą analizuoti atsakymo įstaigą dėl šios priežasties, mes tiesiog pridėjome naują „ X-Status-Extended antraštę, kurioje buvo mūsų patentuoti būsenos kodo plėtiniai. Taigi galite matyti atsakymą kaip:

 HTTP/1.1 404 Not Found X-Status-Extended: 404.3 More Specific Error Here 

Таким образом, HTTP-клиент, такой как веб-браузер, все равно будет знать, что делать с обычным кодом 404, а более сложный HTTP-клиент может выбрать заголовок X-Status-Extended для получения более подробной информации.

4. Для аутентификации я рекомендую использовать HTTP-аутентификацию, если это возможно. Но IMHO нет ничего плохого в использовании аутентификации на основе файлов cookie, если вам это проще.

20
ответ дан friedo 05 янв. '10 в 0:28 2010-01-05 00:28