RESTful search / filter yaratmaq üçün necə?

Hal-hazırda PHP-də RESTful API hazırlayır və həyata keçirirəm. Ancaq mən orijinal dizaynımı həyata keçirə bilmədi.

 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 

Hələ olduqca standart, sağ?

Mənim problemim ilk GET /users bağlıdır. Siyahı süzgəc üçün istək orqanına parametr göndərmə imkanı nəzərdən keçirdim. Bu, məsələn, çox uzun bir URL almadan kompleks filtreler belirtebilmek isteyebileceğimden kaynaklanmaktadır:

 GET /users?parameter1=value1> 

Bunun əvəzinə mənə bir şey istədim:

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

daha çox oxunan və kompleks filtre qurmaq üçün böyük imkanlar təmin edir.

Hər halda, file_get_contents('php://input') , GET istekleri üçün istek gövdesini geri vermedi. Mən də http_get_request_body() , lakin istifadə etdiyim paylaşılan hosting üçün pecl_http yoxdur. Hər halda kömək etdiyinə əmin deyiləm.

Mən bu sualı tapdım və GET-in ehtimal ki, bir istək orqanına malik olmadığını başa düşdüm. Bu bir az inandırıcı idi, lakin ona məsləhət vermədi.

İndi mən nə edəcəyinə əmin deyiləm. RESTful search / filterng funksiyasını necə yaradırsınız?

Hesab edirəm ki, POST istifadə edə bilərəm, amma bu, RESTBOX kimi görünmür.

267
16 февр. Erik B tərəfindən 16 Fevralda təyin olundu. 2011-02-16 21:45 '11 saat 21:45 'də 2011-02-16 21:45
@ 7 cavab

RESTful axtarışın həyata keçirilməsinin ən yaxşı yolu axtarışın özü bir resurs hesab etməkdir. Sonra bir axtarış yaratdığınız üçün POST fiilini istifadə edə bilərsiniz. POST istifadə etmək üçün verilənlər bazasında sözündən bir şey yaratmaq lazım deyil.

Məsələn:

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

Bir istifadəçi baxımından axtarış yaratmaq. İcra məlumatları əhəmiyyətsizdir. Bəzi RESTful API'lər hətta davamlılığı tələb edə bilməz. Bu bir tətbiq təzahürüdür.

304
21 сент. 21 Sentyabrda Jason Harrelson'a cavab verin 2013-09-21 17:39 '13 at 17:39 2013-09-21 17:39

GET sorğusunda bir istək orqanı istifadə edirsinizsə, GET sorğunuzun önbelleklenemediği üçün REST prinsipi pozulur, çünki caching sistemi yalnız URL istifadə edir.

Və daha da pisdir, URL URL-yə zəng edilə bilməz, çünki URL-də istifadəçini bu səhifəyə yönləndirmək üçün lazım olan bütün məlumatlar yoxdur.

Istədiyiniz orqan parametrləri yerinə URL və ya istək parametrlərini istifadə edin.

məsələn:

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

Əslində, HTTP RFC 7231 belə deyir:

GET tələb mesajında ​​yükün xüsusi semantikası yoxdur; GET tələbində bir payload orqanı göndərilməsi bəzi mövcud tətbiqlərin istəkləri rədd etməsinə səbəb ola bilər.

Daha ətraflı məlumat üçün buraya baxın.

50
23 февр. cavab cfcorugedo tərəfindən verilir 23 fevral. 2015-02-23 14:53 '15 at 14:53 2015-02-23 14:53

Göründüyü kimi, filtrasiya / resursları axtarış RESTİCİ şəkildə həyata keçirilə bilər. Fikir, /filters//api/filters/ adlı yeni bir son nöqtəni təqdim etməkdir.

Bu son nöqtə süzgəsinin istifadəsi resurs kimi qəbul edilə bilər və bu səbəbdən POST üsulu ilə yaradılır. Bu üsul əlbəttə ki, bütün parametrləri ötürmək üçün istifadə edilə bilər və kompleks axtarış / filtr strukturları yaradıla bilər.

Belə bir filtr yaratdıqdan sonra, axtarış nəticəsini / filtrini almaq üçün iki imkan var.

  • Unikal identifikatoru olan yeni bir qaynaq 201 Created status kodu ilə birlikdə qaytarılacaq. Daha sonra, bu identifikatordan istifadə etməklə, GET tələb oluna bilər /api/users/ , məsələn:

     GET /api/users/?filterId=1234-abcd 
  • POST vasitəsilə yeni bir filtre yaratdıqdan sonra POST 201 Created istifadə edərək cavab verməyəcək, ancaq 303 SeeOther ilə yerləşdiyi mövzu ilə birlikdə /api/users/?filterId=1234-abcd . Bu redaktə avtomatik baz bazası vasitəsilə işlənəcəkdir.

Hər iki senaryoda, filtrelenen nəticələr əldə etmək üçün iki sorguya ehtiyacınız var - bu xüsusilə mobil tətbiqlər üçün əlverişsiz sayılır. Mobil tətbiqlər üçün, /api/users/filter/ üçün bir POST zəngini istifadə edirəm.

Yaradılmış filtrləri necə saxlamaq olar?

Onlar verilənlər bazasında saxlanıla və sonra istifadə edilə bilər. Onlar həmçinin müvəqqəti saxlanılır, məsələn, saxlanıla bilər. redis və bəzi TTL var, sonra onlar sona çatacaq və silinəcəkdir.

Bu fikirin üstünlükləri nədir?

Filtreler, filtreleme nəticəsində önbelleğe alınmış və hatta yer işareti ola bilər.

24
26 нояб. Cavab Opal 26 Noyabrda verilir. 2015-11-26 23:46 '15 at 11:46 pm 2015-11-26 23:46

İstədiyiniz parametrlər ilə getməyiniz lazım olduğunu düşünürəm amma yalnız istədiyiniz bir şeyi etmək üçün uyğun bir HTTP başlığı var. HTTP spesifikasiyası , GET'in bədənə sahib ola bilməyəcəyini açıqca deyir. Ancaq bu yazıda belə deyilir:

Konvensiya ilə, GET metodu URI-də kodlanmış qaynağı müəyyən etmək üçün lazım olan bütün məlumatlardan istifadə edir. Konvensiya HTTP / 1.1-də təhlükəsiz ünsiyyət üçün (məsələn, axtarış) HTTP / HTTP obyektində olan serverə verilmiş və URI tələbinin bir hissəsi deyildir. Bu təhlükəsiz bir əməliyyat üçün URI'lar uzun ola bilər.

11
16 февр. Cavab Daff 16 fevralda verilir. 2011-02-16 22:02 '11 at 10:02 pm 2011-02-16 22:02

Başlanğıc API tamamilə RESTful və ya olmasaydı (xüsusilə də alfa səhnələrində olduğunuzda) çox narahat olmayın. Birincisi, daxili santexnika qurun. Siz həmişə hər şeyi göstərmək üçün URL-lərin bəzi transformasiyasını / rewritingini edə bilərsiniz, yayılmış test ("beta") üçün kifayət qədər sabit bir şey alana qədər iterativ şəkildə təmizlənirsiniz.

Parametrləri URI-lərin mövqeyi və simvolu ilə kodlanmış URI-lərini müəyyənləşdirə bilərsiniz, bildiyiniz bir prefikslə həmişə bir şeydə göstərilir. PHP'yi bilmirəm, amma belə bir alət var (digər dillərdə olduğu kimi veb çərçivələri ilə mövcuddur):

.ie. # 1 (dəyər 1, dəyər 2, dəyər 3, ... URI istək parametrləri üçün bir kısaltma kimi) ilə i = 1..4 parametresiyle [i] = dəyər [i] parametresiyle "xüsusi" axtarış növü edin:

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

və ya

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

və ya aşağıdakı kimi (baxmayaraq ki, mən bunu məsləhət görmürəm, daha sonra bu barədə)

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

Seçim 1 ilə store1 (eşdeğeri /search?location=store1> .) 'Deki resursları axtarmaq üçün default /store1/search/user bağlı olaraq) axtarış işleyicisi /search?location=store1> .

API tərəfindən sənədləşdirilmiş və icra edilən konvensiya ilə 1-dən 4-ə qədər parametr dəyərləri virgüllə ayrılır və bu qaydada təqdim olunur.

Variant 2 axtarış mövqeyini (bu vəziyyətdə, user ) mövqeləri bir parametr kimi # 1 əlavə edir. Hər hansı bir seçim yalnız kosmetik seçimdir.

Variant 3 də mümkündür, amma bunu sevəcəyəm deyə düşünmürəm. Hesab edirəm ki, müəyyən resurslarda axtarış qabiliyyəti axtarışın özündən əvvəl URI-də öz əksini tapmalıdır (URI-də axtarışın resursda xüsusi olduğunu göstərmişdir).

Parametrləri bir URI-ə keçirərkən bu üstünlük URI-nin bir hissəsidir (beləliklə axtarışın resurs kimi işləndiyi, məzmunu vaxtında dəyişə biləcək bir qaynaq). Dezavantaj əmr parametrinin məcburidir.

Bu kimi bir şey etdiyinizdən sonra GET istifadə edə bilərsiniz və bu yalnız oxunan bir qayda olacaq (POST və ya PUT istifadə edə bilməzsiniz - bu GET'ed zaman yenilənir). Həm də çağırıldıqda görünən bir qayda olacaq.

Nəticələri müəyyən bir müddət üçün önbelleğe alaraq və ya DELETE istifadə edərək, bunun nəticəsində cache silinəcək əlavə semantik əlavə edə bilərsiniz. Bununla birlikdə, bu, insanlar üçün DELETE üçün istifadə etdiyinə zidd ola bilər (və insanlar adətən önbellek başlığı ilə önbelleğe nəzarət etdilər).

Bu barədə getdiyinizdə, bu dizayn qərarı olacaq, amma bunu edəcəyəm. Bu ideal deyil və mən əminəm ki, bu, xüsusən də çox yaxşı nəticə verməyən zaman olacaq (xüsusilə çox mürəkkəb axtarış meyarları üçün).

8
16 февр. Cavab luis.espinal tərəfindən verilir 16 fevral. 2011-02-16 22:13 '11 at 10:13 pm 2011-02-16 22:13

FYI: Bir az gec olduğunu bilirəm amma maraqlı olan hər kəs üçün. HTTPS-nin dəqiqləşdirilməsi çox aydın deyil, çünki RESTful olmağınızdan asılı olaraq, öz filtreleme strategiyalarınızı həyata keçirməlisiniz. Mən, məsələn, bütün filter parametrlərini URL kodlaşdırmağı təklif edərdim.

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

Mən bu çirkin olduğunu bilirəm, amma bu bunu etmək üçün ən RESTFUL yoludur və server tərəfini ayırmaq üçün asan olmalıdır :)

0
21 апр. cavab verildi 2017-04-21 14:02 '17 at 2:02 pm 2017-04-21 14:02

Mən laravel / php backend istifadə etdiyim üçün bu kimi bir şey ilə getməyə meyl edirəm:

Filtreler [şəhər] = Sidney page = 2 include = relatedResource

PHP avtomatik olaraq [] parametrlərini bir sıra halına çevirir, beləliklə, bu nümunədə filter array / obyektini ehtiva edən $ filter dəyişənini, həmçinin yükləmək istədiyiniz səhifəni və əlaqədar qaynaqları da alıram.

Başqa bir dil istifadə etsəniz, bu yaxşı bir şey ola bilər və siz [] bir sıra halına gətirmək üçün bir ayrıştırıcı yarada bilərsiniz.

-1
20 июня '17 в 11:53 2017-06-20 11:53 cavab 20 iyun 'da saat 11:53' də 2017-06-20 11:53 'a gedəcək

əlaqədar digər suallar və ya soruşun