577 Stimmen

Wie gestaltet man eine RESTful-Suche/Filterung?

Ich bin gerade dabei, eine RESTful API in PHP zu entwerfen und zu implementieren. Allerdings ist es mir nicht gelungen, meinen ursprünglichen Entwurf zu implementieren.

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

So weit, so normal, nicht wahr?

Mein Problem ist der erste Punkt GET /users . Ich habe in Erwägung gezogen, Parameter im Anfragetext zu senden, um die Liste zu filtern. Der Grund dafür ist, dass ich in der Lage sein möchte, komplexe Filter zu spezifizieren, ohne eine super lange URL zu erhalten, wie z. B.:

GET /users?parameter1=value1&parameter2=value2&parameter3=value3&parameter4=value4

Stattdessen wollte ich etwas haben wie:

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

die viel besser lesbar ist und Ihnen großartige Möglichkeiten bietet, komplexe Filter zu setzen.

Wie auch immer, file_get_contents('php://input') nicht den Request Body für GET Anfragen. Ich habe auch versucht http_get_request_body() aber das Shared Hosting, das ich benutze, hat keine pecl_http . Ich bin mir nicht sicher, ob es überhaupt etwas gebracht hätte.

Ich fand diese Frage und erkannte, dass GET wahrscheinlich keinen Request Body haben sollte. Es war nicht ganz schlüssig, aber sie rieten davon ab.

Jetzt bin ich nicht sicher, was ich tun soll. Wie entwirft man eine RESTful-Such-/Filterungsfunktion?

Ich nehme an, ich könnte die POST aber das scheint nicht sehr RESTful zu sein.

4voto

shanks Punkte 882

FYI: Ich weiß, dies ist ein bisschen spät, aber für jeden, der interessiert ist. Abhängig davon, wie RESTful Sie sein wollen, müssen Sie Ihre eigenen Filterstrategien zu implementieren, wie die HTTP-Spezifikation ist nicht sehr klar auf diese. Ich würde vorschlagen, dass man alle Filterparameter url-encodiert, z.B.

GET api/users?filter=param1%3Dvalue1%26param2%3Dvalue2

Ich weiß, es ist hässlich, aber ich denke, es ist die RESTful Weg, um es zu tun und sollte leicht zu parsen auf der Server-Seite :)

1voto

luis.espinal Punkte 10122

Machen Sie sich nicht zu viele Gedanken darüber, ob Ihre anfängliche API vollständig RESTful ist oder nicht (vor allem, wenn Sie sich noch in der Alphaphase befinden). Bringen Sie zuerst die Back-End-Kanäle zum Laufen. Sie können immer eine Art URL-Umwandlung/Umschreibung vornehmen, um die Dinge abzubilden, und diese iterativ verfeinern, bis Sie etwas haben, das stabil genug für breit angelegte Tests ("Beta") ist.

Sie können URIs definieren, deren Parameter durch Position und Konvention auf den URIs selbst kodiert sind, denen ein Pfad vorangestellt ist, von dem Sie wissen, dass Sie ihn immer auf etwas abbilden werden. Ich kenne PHP nicht, aber ich gehe davon aus, dass es eine solche Möglichkeit gibt (wie auch in anderen Sprachen mit Web-Frameworks):

.dh. Führen Sie eine "benutzerdefinierte" Suche mit param[i]=value[i] für i=1..4 in Speicher 1 durch (mit value1,value2,value3,... als Abkürzung für URI-Abfrageparameter):

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

oder

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

oder wie folgt (obwohl ich das nicht empfehlen würde, dazu später mehr)

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

Mit Option 1 bilden Sie alle URIs mit dem Präfix /store1/search/user an den Suchhandler (oder wie auch immer die PHP-Bezeichnung lautet), der standardmäßig nach Ressourcen unter store1 sucht (entspricht /search?location=store1&type=user .

Gemäß der von der API dokumentierten und erzwungenen Konvention werden die Parameterwerte 1 bis 4 durch Kommata getrennt und in dieser Reihenfolge dargestellt.

Option 2 fügt den Suchtyp hinzu (in diesem Fall user ) als Positionsparameter #1. Beide Optionen sind nur eine kosmetische Wahl.

Option 3 ist auch möglich, aber ich glaube nicht, dass sie mir gefallen würde. Ich denke, die Möglichkeit der Suche innerhalb bestimmter Ressourcen sollte in der URI selbst vor der eigentlichen Suche dargestellt werden (als ob in der URI klar angegeben würde, dass die Suche spezifisch innerhalb der Ressource ist).

Der Vorteil gegenüber der Übergabe von Parametern an den URI besteht darin, dass die Suche Teil des URI ist (so wird eine Suche als Ressource behandelt, eine Ressource, deren Inhalt sich mit der Zeit ändern kann - und wird). Der Nachteil ist, dass die Reihenfolge der Parameter obligatorisch ist.

Sobald Sie so etwas tun, können Sie GET verwenden, und es wäre eine schreibgeschützte Ressource (da Sie nicht POST oder PUT auf sie anwenden können - sie wird aktualisiert, wenn sie GET'ed). Es wäre auch eine Ressource, die nur existiert, wenn sie aufgerufen wird.

Man könnte auch mehr Semantik hinzufügen, indem man die Ergebnisse für eine gewisse Zeit zwischenspeichert oder mit einem DELETE den Cache löscht. Dies könnte jedoch im Widerspruch zu dem stehen, wofür DELETE typischerweise verwendet wird (und weil die Leute typischerweise die Zwischenspeicherung mit Caching-Headern steuern).

Wie man das macht, ist eine Design-Entscheidung, aber so würde ich es machen. Es ist nicht perfekt, und ich bin sicher, dass es Fälle geben wird, in denen dies nicht die beste Lösung ist (besonders bei sehr komplexen Suchkriterien).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X