it-swarm.com.de

Wie kann eine Validierungs-API auf REST-gerechte Weise verfügbar gemacht werden?

Ich bin im Allgemeinen ein Fan von RESTful API-Design, aber ich bin mir nicht sicher, wie ich REST Prinzipien für eine Validierungs-API anwenden soll.

Angenommen, wir haben eine API zum Abfragen und Aktualisieren der Profilinformationen eines Benutzers (Name, E-Mail, Benutzername, Passwort). Wir sind der Ansicht, dass eine nützliche Funktion, die verfügbar gemacht werden kann, die Validierung ist, z. Abfrage, ob ein bestimmter Benutzername gültig und verfügbar ist.

Was sind die Ressourcen in diesem Fall? Welche HTTP-Statuscodes und/oder Header sollten verwendet werden?

Zu Beginn habe ich GET /profile/validate, Das Abfragezeichenfolgenparameter verwendet und 204 Oder 400 Zurückgibt, wenn dies gültig oder ungültig ist. Aber validate ist eindeutig ein Verb und kein Substantiv.

63
Aseem Kishore

Die Art von Dingen, die Sie beschrieben haben, ist in ihrer Semantik sicherlich eher RPC-artig, aber das bedeutet nicht, dass Sie Ihre Ziele nicht auf REST-artige Weise erreichen können.

Es gibt kein HTTP-Verb VALIDATE. Wie viel Wert können Sie also durch die Strukturierung einer gesamten API daraus erzielen? Ihre Geschichte dreht sich darum, Benutzern die Möglichkeit zu geben, zu bestimmen, ob ein bestimmter Benutzername verfügbar ist - das klingt für mich nach einer einfachen Überprüfung des Ressourcenabrufs - GET: /profile/username/... - Wenn das Ergebnis ein 404 ist, ist der Name verfügbar.

Was dies hervorhebt, ist, dass diese clientseitige Validierung genau das ist - clientseitig. Es ist ein Anliegen der Benutzeroberfläche, sicherzustellen, dass die Daten auf dem Client überprüft werden, bevor sie an den Server gesendet werden. Ein RESTful-Service gibt keinen Hinweis darauf, ob ein Client eine Validierung durchgeführt hat oder nicht. Es wird einfach eine Anfrage basierend auf seiner eigenen Validierungslogik annehmen oder ablehnen.

REST ist kein allumfassendes Paradigma, sondern beschreibt nur eine Methode zur Strukturierung der Client-Server-Kommunikation.

43
Josh E

Wir sind auch auf das gleiche Problem gestoßen. Wir hatten den Grund, den Client zur Validierung an den Server zu schicken, um zu verhindern, dass die Regeln nicht übereinstimmen. Der Server muss alles validieren, bevor er auf die Ressourcen einwirkt. Es war nicht sinnvoll, diese Regeln zweimal zu codieren und das Potenzial zu haben, dass sie nicht mehr synchron sind. Aus diesem Grund haben wir eine Strategie entwickelt, die anscheinend der Idee von REST entspricht und es uns gleichzeitig ermöglicht, den Server aufzufordern, die Validierung durchzuführen.

Unser erster Schritt war die Implementierung eines Metadatenobjekts, das von einem Metadatendienst angefordert werden kann (GET /metadata/user). Dieses Metadatenobjekt wird dann verwendet, um dem Client mitzuteilen, wie grundlegende clientseitige Überprüfungen durchgeführt werden sollen (Erforderlichkeit, Typ, Länge usw.). Die meisten davon generieren wir aus unserer Datenbank.

Der zweite Teil besteht aus dem Hinzufügen einer neuen Ressource, die als Analyse bezeichnet wird. Wenn wir zum Beispiel einen Service haben:

GET /users/100

Wir erstellen eine neue Ressource mit dem Namen:

POST /users/100/analysis

Die Analyseressource enthält nicht nur alle aufgetretenen Validierungsfehler, sondern auch statistische Informationen, die bei Bedarf relevant sein können. Eines der von uns diskutierten Probleme war, welches Verb für die Analyseressource verwendet werden sollte. Wir sind zu dem Schluss gekommen, dass es ein POST sein sollte, da die Analyse zum Zeitpunkt der Anforderung erstellt wird. Es gab jedoch auch starke Argumente für GET.

Ich hoffe, dies ist hilfreich für andere, die versuchen, dasselbe Problem zu lösen. Jegliches Feedback zu diesem Entwurf wird gebeten.

13
Leslie Hanks

Sie verwechseln REST mit Ressourcenorientierung, es gibt nichts in REST), das besagt, dass Sie keine Verben in URLs verwenden können. Wenn es um URL-Design geht, wähle ich normalerweise, was auch immer ist Am selbsterklärendsten ist, ob es sich um ein Substantiv oder ein Verb handelt.

In Bezug auf Ihren Dienst würde ich dieselbe Ressource verwenden, die Sie zum Aktualisieren verwenden, jedoch mit einem Parameter test querystring. Wenn also test=1 Der Vorgang wird nicht ausgeführt, aber Sie können ihn verwenden, um Überprüfungsfehler zurückzugeben.

PATCH /profile?test=1
Content-Type: application/x-www-form-urlencoded

dob=foo

... und die Antwort:

HTTP/1.1 400 Bad Request
Content-Type: text/html

<ul class="errors">
  <li data-name="dob">foo is not a valid date.</li>
</ul>
10
Max Toro

Es ist großartig, die Validierung in der REST API zu haben. Sie benötigen sowieso eine Validierung und möchten sie nicht auf der Clientseite verwenden. In meinem Fall habe ich nur eine Konvention in der API, die a Spezielle error_id repräsentiert Validierungsfehler und in error_details gibt es eine Reihe von Fehlermeldungen für jedes Feld, das Fehler in diesem PUT- oder POST Aufruf enthält. Zum Beispiel:

{
  "error": true,
  "error_id": 20301,
  "error_message": "Validation failed!",
  "error_details": {
    "number": [
      "Number must not be empty"
    ],
    "ean": [
      "Ean must not be empty",
      "Ean is not a valid EAN"
    ]
  }
}

Wenn Sie dieselbe REST API für Web - und Mobilanwendungen verwenden, wird es Ihnen gefallen, wenn Sie die Gültigkeitsprüfung in beiden Fällen nur durch Aktualisierung der API ändern können. Die Veröffentlichung von Updates für Mobilgeräte auf dem dauert mehr als 24 Stunden Shops.

Und so sieht es in der Mobile-Anwendung aus: enter image description here

Die Antwort des PUT oder POST wird verwendet, um die Fehlermeldungen für jedes Feld anzuzeigen. Dies ist der gleiche Aufruf von einer Webanwendung mit React: enter image description here

Auf diese Weise haben alle REST API-Antwortcodes wie 200, 404 die gewünschte Bedeutung. Ein PUT-Aufruf antwortet mit 200, auch wenn die Validierung fehlschlägt. Wenn der Aufruf die Validierung besteht, würde die Antwort aussehen so was:

{
  "error": false,
  "item": {
"id": 1,
"created_at": "2016-08-03 13:58:11",
"updated_at": "2016-11-30 08:55:58",
"deleted_at": null,
"name": "Artikel 1",
"number": "1273673813",
"ean": "12345678912222"
  }
}

Es gibt mögliche Änderungen, die Sie vornehmen könnten. Maby benutze es ohne eine error_id. Wenn es sich um Fehlerdetails handelt, schleifen Sie sie einfach und wenn Sie einen Schlüssel finden, der denselben Namen wie ein Feld hat, geben Sie seinen Wert als Fehlertext in dasselbe Feld ein.

0
Tarik Huber