2017-02-28 5 views
0

Ich versuche, eine API zu erstellen, die REST-Best-Practices folgt, intuitiv ist und Übereinstimmungen mit den Mustern, die Entwickler von anderen (gut gestalteten) APIs sehen. Ich glaube, dass ich die verschiedene Mapping der HTTP-Verben zu den typischen Ressourcen zu verstehen, die mit den Antworten in diesen beiden Fragen in Zeile ist:Handle CRUD in REST API Wenn Read benötigt ein POST

Which HTTP methods match up to which CRUD methods?

Understanding REST: Verbs, error codes, and authentication

Wo ich Probleme habe, ist, dass Aufgrund der Art unseres Geschäfts und der zum Abrufen von Daten erforderlichen Daten, die normalerweise ein GET wären, müssen wir einen POST verwenden. Dies liegt sowohl an der Größe der Anfrage als auch daran, was wir weitergeben, um die Suche durchzuführen.

When do you use POST and when do you use GET?

Also, es gibt ein paar Ansätze ich auf denken, wie CRUD am besten handhaben, und ich habe die Liebe einige Vorschläge:

  1. Verwenden Abfrageparameter in der POST für CREATE differenzier vs READ, andere Verben als normal. Ich mag diese Idee nicht.
  2. Haben Sie einen separaten Endpunkt für jede Aktion, z./baseUrl/lookup,/baseUrl/create. Folgt nicht dem richtigen Muster der Verwendung von Substantiven anstelle von Verben.

EDIT: Im Interesse der Klarheit, das erfundene Beispiel in meinen Kommentaren eines Bild Lookup-Service, wo ein Anrufer suchen, wenn ein Bild bereits in der Datenbank vorhanden ist, um ein neues Bild hinzufügen, aktualisieren Sie das Bild (zB Metadaten hinzufügen) oder löschen Sie das Bild.

Erstellen:Was sollen wir hier tun? POST/image/Erstellen und aktualisieren Sie den Lese-Endpunkt nach/image/search?

lesen: POST/Bild {imagedata = someBase64EncodedImage}

Update: PUT/image/{imageId}

Löschen: DELETE/image/{imageId}

+0

Wir brauchen ein eher bodenständiges Beispiel. Das heißt, das Problem, POST zu verwenden, wenn GET offensichtlich ist, klingt wie Sie eine Liste einer Ressource mit expliziten Informationen in der Abfragezeichenfolge (Zeug wie IDs) abrufen, die mit Paginierung – JSelser

+0

Als ein Beispiel für etwas Ähnliches gelöst wird, lassen Sie uns sagen Sie die Google Reverse Image Suche, obwohl es in unserem Fall nur das beste Spiel zurückgibt. Sie müssen also ein Bild POST einreichen, um zu sehen, ob es ein Bild gibt, das sehr nah ist (innerhalb eines Grenzwerts), sonst wird nichts zurückgegeben. Sie können auch ein Bild zu der Datenbank hinzufügen, das zu einem späteren Zeitpunkt abgerufen werden soll. IT ist nicht wirklich ein Problem der Seitenumbruch, oder zu viele Daten zurückgegeben werden. Es ist unordentlich, POST sowohl für die Erstellung als auch für den Abruf zu verwenden. – Matt

+0

Sie können Ihre Frage mit einem Beispiel aktualisieren, das Ihrem Problem am ähnlichsten ist, um bessere Antworten zu erhalten. Insbesondere kann ich nicht ausschließen, welches deine Ressource durch Kontext ist, sind es dann Bilder? – JSelser

Antwort

1

Ich denke, dass es ein Missverständnis über die Verwendung von POST zum Abrufen von Ressourcen gibt. Von einem hohen Standpunkt aus, geben Sie ein Problem wie folgt an:

Ich muss eine Liste der Entitäten vom Server abrufen, die eine Vielzahl von Parametern entsprechen. Wie kann ich das erreichen?

So ist die tempation, ein POST als ein Mittel für das Anfordern eines READ zu sehen, stark. Und gleichzeitig ist es irreführend. Überall hören Sie REST-Evangelisten schwören, dass ein READ über eine GET implementiert werden sollte und Tunneling-Operationen mit POST ist ein REST Antipattern.

Die Lösung des Problems ist sehr einfach und es geht darum, unseren Ansatz zu ändern. Es ist nicht POST ing für READING.Es geht darum, ein Anfrageticket an den Server zu senden und auf eine Antwort zurück zu warten. Und in der Tat ist es definitiv, was wir tun, mit einem POST. A POST, erstellt eine Subresource, Zeitraum (ja, es kann auch für die Aktualisierung verwendet werden, aber ich will nicht in Details verloren gehen).

Wenn Sie also einen Server nach einer komplexen Ressource abfragen möchten, legen Sie einfach ein Ticket ab und warten auf eine Antwort. Lassen Sie uns einen Anwendungsfall prüfen:

Sie haben eine car durch die folgende URI identifizierte Ressource

http://authority/api/cars/{id}

und, sagen wir, wollen Sie den Server in einer sehr komplexen Weise abgefragt werden, indem ein POST Ausgabe.

Welchen Endpunkt verwenden Sie? Auf jeden Fall kann man nicht gehen mit

POSThttp://authority/api/cars

, denn wenn Sie das tun, was Sie erwarten nichts anderes als ein Auto Schöpfung zu erhalten ist, ist es nicht? Die Lösung ist wiederum sehr einfach. Sie versuchen, ein Abfrageticket an den Server zu senden, also sollten Sie diese Ressource ablehnen. Sie könnten mehr kreativ sein, aber vielleicht könnte dies

POSThttp://authority/api/tickets/cars

POST ing eine Abfrage Ticket zu diesem Endpunkt arbeiten können Sie erwarten eine Antwort zurück mit einem location Header haben, um eine Liste der Fahrzeuge beziehen (a Autos Ressource), die Ihrer Anfrage entsprechen (Statuscode 201 = Creted oder 202 = akzeptiert, das Ergebnis ist so schnell wie möglich verfügbar). Wenn die Berechnung schnell genug ist, ist es keine Todsünde, das Ergebnis in die HTTP-Antwort (persönliche Meinung) aufzunehmen.

Für eine umfassendere Dissertation finden Sie in diesem brillanten Artikel: How to GET a Cup of Coffee.

+0

Mein Beispiel wurde explizit in der ursprünglichen Frage hinzugefügt . Der Artikel, den Sie verlinkt haben, ist für mich sinnvoll, und ich denke, ich habe ihn schon vor einer Weile wiedergefunden, aber Sie und der Artikel gehen davon aus, dass der POST eine neue Ressource erstellt. In meinem Fall erstellt der POST keine Ressource, aber aus Sicherheitsgründen kann das Caching und die Abfragegröße kein GET sein.Ich bin konzeptionell in Ordnung mit einem POST als eine READ-Operation, ich möchte nur herausfinden, was ist die beste Vorgehensweise hier. Nach Ihrer Antwort scheint es, als wären Sie im Lager, um den Endpunkt zu erweitern. Ich würde es vorziehen, die Ressource als eine gemeinsame Basis (z. B. Bilder) zu halten – Matt

+0

Nach meinem besten Wissen trägt POST eine sehr spezifische Semantik. Es erstellt/aktualisiert eine Sub-Ressource. Sie können einen POST nicht dazu zwingen, eine andere Bedeutung zu vermitteln (POST ist per Definition weder sicher noch idempotent. Denken Sie zweimal darüber nach, ob Sie ihn sicher oder idempotent verwenden). Meiner Meinung nach, Ihr Beispiel für eine rev. Bildsuche reduziert sich auf meine Lösung: "* Hey Server, finde dieses Bild * = * hey gib mir Ergebnisse basierend auf dem Ticket, das ich einreiche *". Ihr Zwang, keine neuen Ressourcen zu entwickeln, lässt wenig Platz für die korrekte Nutzung des POST zum Lesen, ich befürchte, dass Sie auf diese Weise nicht sehr RESTful sein können, – MaVVamaldo