Kaip sukurti atnaujinamą paiešką / filtrą?

Šiuo metu kuriu ir diegiu „RESTful API“ PHP. Tačiau aš negalėjau suprasti savo originalaus dizaino.

 GET /users # list of users GET /user/1 # get user with id 1 POST /user # create new user PUT /user/1 # modify user with id 1 DELETE /user/1 # delete user with id 1 

Vis dar gana standartinis, tiesa?

Mano problema susijusi su pirmuoju GET /users . Aš apsvarstiau galimybę siųsti parametrus užklausos įstaigai filtruoti sąrašą. Taip yra dėl to, kad noriu, kad galėčiau nurodyti sudėtingus filtrus, nesulaukus labai ilgo URL, pavyzdžiui:

 GET /users?parameter1=value1> 

Vietoj to norėjau turėti kažką panašaus:

 GET /users # Request body: { "parameter1": "value1", "parameter2": "value2", "parameter3": "value3", "parameter4": "value4" } 

kuris yra lengviau skaitomas ir suteikia puikių galimybių įdiegti sudėtingus filtrus.

Bet kuriuo atveju file_get_contents('php://input') nepateikė užklausos įstaigos GET užklausoms. Aš taip pat bandžiau http_get_request_body() , bet bendrai naudojamam prieglobui naudoju, nėra pecl_http . Nežinote, ar tai padėjo.

Radau šį klausimą ir supratau, kad GET turbūt neturėtų turėti užklausos įstaigos. Tai buvo šiek tiek neįtikinantis, bet jie jam nepranešė.

Taigi dabar aš nesu įsitikinęs, ką daryti. Kaip sukuriate atnaujinamą paieškos / filterng funkciją?

Manau, galiu naudoti POST , bet tai neatrodo labai atgailinga.

267
16 февр. nustatė Erikas B. vasario 16 d. 2011-02-16 21:45 '11, 21:45, 2011-02-16 21:45
@ 7 atsakymai

Geriausias būdas įgyvendinti RESTful paiešką yra apsvarstyti paiešką kaip šaltinį. Tada galite naudoti POST veiksmažodį, nes kuriate paiešką. Jums nereikia tiesiog kurti nieko duomenų bazėje, kad galėtumėte naudoti POST.

Pavyzdžiui:

 Accept: application/json Content-Type: application/json POST http://example.com/people/searches { "terms": { "ssn": "123456789" }, "order": { ... }, ... } 

Jūs sukuriate paiešką naudotojo požiūriu. Įgyvendinimo detalės nesvarbu. Kai kurios „RESTful“ API gali net nereikalauti patvarumo. Tai yra įgyvendinimo detalė.

304
21 сент. Atsakyti Jason Harrelsonui rugsėjo 21 d 2013-09-21 17:39 '13, 17:39, 2013-09-21 17:39

Jei GET užklausoje naudojate užklausos įstaigą, jūs pažeidžiate REST principą, nes jūsų GET užklausos negalima išsaugoti talpykloje, nes talpykloje naudojama tik URL.

Ir dar blogiau, jūsų URL negali būti pažymėtas, nes URL nėra visos informacijos, kurios reikia norint nukreipti vartotoją į šį puslapį.

Vietoj užklausos kūno parametrų naudokite URL arba užklausos parametrus.

pavyzdžiui:

border=0
 /myapp?var1=xxxx /myapp;var1=xxxx/resource;var2=xxxx 

Iš tikrųjų HTTP RFC 7231 sako, kad:

GET užklausos pranešimo naudingoji apkrova neturi konkrečios semantikos; siunčiant naudingosios apkrovos kūną GET užklausoje, kai kurie esami diegimai gali atmesti prašymą.

Daugiau informacijos rasite čia .

50
23 февр. atsakymą pateikė jfcorugedo 23 vasaris. 2015-02-23 14:53 '15, 14:53, 2015-02-23 14:53

Atrodo, kad filtravimas / išteklių paieška gali būti įgyvendinamas ramiai. Idėja yra įvesti naują galutinį parametrą, vadinamą /filters/ arba /api/filters/ .

Šio parametro filtro naudojimas gali būti laikomas ištekliumi, todėl jis sukuriamas naudojant POST metodą. Šis metodas, žinoma, gali būti naudojamas visiems parametrams perduoti, o kompleksinės paieškos / filtro struktūros gali būti sukurtos.

Sukūrus tokį filtrą, yra dvi galimybės gauti paieškos rezultatą / filtrą.

  • Kartu su 201 Created būsenos kodu bus grąžinamas naujas šaltinis, turintis unikalų identifikatorių. Tada, naudojant šį identifikatorių, GET gali būti paprašyta /api/users/ , pavyzdžiui:

     GET /api/users/?filterId=1234-abcd 
  • Sukūrus naują filtrą per POST jis neatsako naudojant „ 201 Created , bet iš karto su 303 SeeOther kartu su „ Location antrašte, nurodančia /api/users/?filterId=1234-abcd . Šis peradresavimas bus automatiškai apdorojamas per bazinę biblioteką.

Abiejuose scenarijuose turite atlikti dvi užklausas, kad gautumėte filtruotus rezultatus - tai gali būti laikoma nepalankia padėtimi, ypač mobiliosiose programose. Mobiliosioms programoms naudoju vieną „ POST skambutį /api/users/filter/ .

Kaip išsaugoti sukurtus filtrus?

Jie gali būti saugomi duomenų bazėje ir naudojami vėliau. Jie taip pat gali būti laikomi tam tikroje laikino saugojimo vietoje. redis ir turėti tam tikrą TTL, po kurio jie baigiasi ir bus ištrinti.

Kokie yra šios idėjos privalumai?

Filtrai, filtravimo rezultatai gali būti išsaugoti talpykloje ir gali būti net pažymėti.

24
26 нояб. atsakymas pateiktas Opal, lapkričio 26 d. 2015-11-26 23:46 '15, 11:46 pm 2015-11-26 23:46

Manau, kad turėtumėte eiti su užklausos parametrais, bet tik tol, kol yra tinkama HTTP antraštė, kad galėtumėte daryti tai, ką norite daryti. HTTP specifikacija aiškiai nenurodo, kad GET negali turėti kūno. Tačiau šiame straipsnyje nurodyta:

Pagal susitarimą, kai GET metodas naudoja visą informaciją, reikalingą URI koduotam ištekliui nustatyti. Konvencijoje nėra HTTP / 1.1 saugiam ryšiui (pvz., Paieškai), kur klientas pateikia duomenis į serverį HTTP objekte, o ne URI užklausos dalyje. Tai reiškia, kad saugiam darbui URI gali būti ilgas.

11
16 февр. Atsakymas duotas Daff 16 vasario mėn. 2011-02-16 22:02 '11 10:02 val. 2011-02-16 22:02

Nesijaudinkite per daug, jei pradinė API yra visiškai atsipalaidavusi (ypač kai esate tik alfa scenose). Visų pirma, atlikite vidaus vandentiekį. Jūs visada galite atlikti tam tikrą URL keitimą / perrašymą, kad būtų rodoma viskas, rafinuotai iteratyviai, kol gausite pakankamai stabilų, kad galėtumėte plačiai išbandyti („beta“).

Galite nustatyti URI, kurių parametrus koduoja pačios URI pozicija ir simbolis, su žinomu prefiksu visada bus rodomas kažkas. Nežinau PHP, bet manau, kad tokia priemonė egzistuoja (kaip ji egzistuoja kitomis kalbomis su žiniatinklio sistemomis):

.ie. Padarykite „pasirinktinį“ paieškos tipą su parametru [i] = reikšmė [i] i = 1..4 saugykloje Nr. 1 (vertė 1, vertė 2, vertė 3, ... kaip URI užklausos parametrų santrumpa):

 1) GET /store1/search/user/value1,value2,value3,value4 

arba

 2) GET /store1/search/user,value1,value2,value3,value4 

arba taip (nors aš to nerekomenduosiu, daugiau apie tai vėliau)

 3) GET /search/store1,user,value1,value2,value3,value4 

Pasirinkus 1 parinktį, visus URI susieti su /store1/search/user prefiksu su paieškos tvarkytoju (arba priklausomai nuo PHP tikslo), kad ieškotumėte išteklių parduotuvėje1 (lygiavertė /search?location=store1> .

Pagal susitarimą, dokumentais ir vykdoma API, parametro reikšmės nuo 1 iki 4 yra atskirtos kableliais ir pateikiamos šioje eilutėje.

2 galimybė prideda paieškos tipą (šiuo atveju user ) kaip pozityvų parametrą # 1. Bet kuri parinktis yra tik kosmetinis pasirinkimas.

3 galimybė taip pat yra įmanoma, tačiau nemanau, kad man tai patiks. Manau, kad galimybė ieškoti tam tikruose ištekliuose turėtų būti atstovaujama pačiame URI, prieš pačią paiešką (tarsi būtų aiškiai nurodyta URI, kad paieška yra specifinė ištekliai.)

Šio privalumo, kai parametrai perduodami URI, privalumas yra tai, kad paieška yra URI dalis (tokiu būdu apdorojant paiešką kaip išteklius, išteklius, kurio turinys gali ir bus laikui bėgant). Trūkumas yra tas, kad užsakymo parametras yra privalomas.

Kai tai padarysite, galite naudoti „GET“ ir tai bus tik skaitymo šaltinis (nes negalite naudoti „POST“ arba „PUT“ - jis atnaujinamas, kai jis yra „GET“). Jis taip pat bus išteklius, kuris pasirodys tik tada, kai jis vadinamas.

Taip pat galite pridėti papildomą semantiką, spustelėję rezultatus tam tikrą laiką arba naudodami DELETE, dėl to talpykla bus ištrinta. Tačiau tai gali prieštarauti tam, ką žmonės paprastai naudoja DELETE (ir todėl, kad žmonės paprastai valdo talpyklą su spartinimo įrašais).

Kaip jūs einate, tai bus sprendimas dėl dizaino, bet tai padarytu. Tai nėra tobula, ir aš tikiu, kad bus kartų, kai tai nėra geriausia daryti (ypač labai sudėtingų paieškos kriterijų atveju).

8
16 февр. Atsakymą pateikė luis.espinal 16 vasaris. 2011-02-16 22:13 '11 10:13 val. 2011-02-16 22:13

FYI: aš žinau, kad tai šiek tiek vėlai, bet visiems, kurie domisi. Priklausomai nuo to, kaip norite būti RESTful, turėsite įgyvendinti savo filtravimo strategijas, nes HTTP specifikacija nėra labai aiški. Norėčiau pasiūlyti URL kodavimo visus filtrų parametrus.

 GET api/users?filter=param1=value1¶m2=value2 

Aš žinau, kad tai bjaurus, bet manau, kad tai yra labiausiai pasitenkinantis būdas tai padaryti ir turėtų būti lengva analizuoti serverio pusėje :)

0
21 апр. atsakymas suteiktas shanks balandžio 21 d 2017-04-21 14:02 '17 at 14:02 pm 2017-04-21 14:02

Kadangi naudoju „laravel / php“ backendą, aš linkiu eiti su tokiu dalyku:

Filtrai [city] = Sidnėjus ir puslapis = 2 include = relatedResource

PHP automatiškai perjungia [] params į masyvą, todėl šiame pavyzdyje gaunu $ filtro kintamąjį, kuriame yra filtrų masyvas / objektas, taip pat puslapį ir visus susijusius išteklius, kuriuos noriu įkelti.

Jei naudojate kitą kalbą, tai gali būti geras dalykas, ir galite sukurti analizatorių, kad konvertuoti [] į masyvą.

-1
20 июня '17 в 11:53 2017-06-20 11:53 atsakymas į „a-traukinį“ pateikiamas birželio 20 d. 17 val. 11:53 2017-06-20 11:53