it-swarm.com.de

REST - Unterstützung mehrerer möglicher Identifikatoren

Für die Website, an der ich gerade arbeite, sind wir dabei, unsere URLs für einen Ressourcentyp zu verbessern - insbesondere von numerischen IDs hin zu eindeutigen, beschreibenden Zeichenfolgen. Ein ähnliches Beispiel wäre das Umschalten von der Identifizierung der Benutzer anhand der numerischen Datenbank-ID zur Identifizierung durch den Benutzernamen (nicht in unserem speziellen Fall, sondern im analogen Fall). Eine URL für den Zugriff auf die Informationen eines Benutzers sah folgendermaßen aus:

/users/48573

Und jetzt sieht es so aus

/users/thisisausername.

Das einzige Problem ist, dass wir sie weiterhin irgendwie über numerische IDs abrufen können, für ältere Benutzer der API. Wir brauchen nicht die REST-URLs selbst, um umzuleiten (z. B. sollte /users/48573 nicht zu /users/thisisausername weitergeleitet werden), wir brauchen nur eine Methode, um die richtigen Daten mit dem alten Bezeichner zu erhalten. Die Lösung sollte entweder eine alternative Möglichkeit bieten, auf die Benutzerinformationen (die bequem den neuen Bezeichner und den Benutzernamen enthalten) nach ID oder auf den Benutzernamen nach ID zuzugreifen. Einige mögliche Lösungen könnten sein:

  • Verwenden eines Knotens, um eine alternative Identifikationsmethode anzugeben, z. /users/byid/48573
  • Verwenden eines Abfrageparameters zum Angeben einer alternativen Identifikationsmethode, z. /users/48573?fetchby=id oder /users/48573?byid=true
  • Behandeln von Benutzername-nach-ID als eine andere Ressource, z. /identifiers/username/48573

Welcher von diesen (wenn vorhanden) ist dem richtigen REST am nächsten? Wie würden Sie mit dem Problem umgehen?

49
Kelly Ellis

Ich denke, das Hinzufügen eines Pfadsegments/-präfixes ist die beste Antwort. Da es sich hierbei um eindeutige Sekundärschlüssel handelt, ist dies nicht das Gleiche wie Suchen (was eine Reihe von Elementen zurückgibt). Die Verwendung von Abfrageparametern (die nicht zwischengespeichert werden) scheint daher nicht die beste Wahl zu sein.

Ich persönlich plane, ein Pfadsegment-Präfix zu verwenden, das durch "=", wie "name =" oder "email =", getrennt ist:

user/123456
user/name=john.doe
user/[email protected]

Dies ist funktionell äquivalent zum Hinzufügen eines Pfadsegments (z. B. "user/name/john.doe"), fühlt sich aber für mich an, als würde es dem konzeptionellen Modell näher zugeordnet. Dies ist natürlich ein unbedeutendes Detail, da RESTful-APIs ohnehin keine feste URI-Struktur angeben sollten.

Wenn Sie keine Abfrageparameter verwenden, können Sie natürlich auch auf Unterressourcen zugreifen:

user/name=john.doe/inbox/df87bhJXrg63

Frameworks wie Javas JAX-RS-Unterstützung verwenden beliebige Trennzeichen, die Sie möchten:

@GET
@Path("user/{id}")
User getUser(@PathParam("id") UUID id);

@GET
@Path("user/name={name}")
User getUserByName(@PathParam("name") String name);

@GET
@Path("user/email={email}")
User getUserByEmail(@PathParam("email") String email);
30
Trevor Robinson

Ihre erste Option ist wahrscheinlich die beste.

Benutzer nach ID suchen:

/users/id/48573

Benutzer nach Kurznamen suchen:

/users/name/thisisausername

Wenn dieser Pfadparameter weggelassen wird, können Sie immer das neue Format für kurze Benutzernamen verwenden.

Eine andere Möglichkeit, die ich schon ziemlich oft gesehen habe, ist die Verwendung von Abfrageparametern wie folgt:

/users?id=48573
/users?name=thisisausername

Ich denke, der erste sieht etwas sauberer und lesbarer aus.

15
Chris Dail

Eine ziemlich alte Frage, aber ich hatte dasselbe und schließlich die Lösung gefunden: Verwenden Sie Regex in Ihrem Pfad Param.

So habe ich diesen Anwendungsfall codiert

@GET
@Path("/{id : \\d+}")
@Produces(APPLICATION_JSON)
public Response getById(@PathParam("id") long id) {
 <<your code>>
}

@GET
@Path("/{name}")
@Produces(APPLICATION_JSON)
public Response getByName(@PathParam("name") String name) {
 <<your code>>
}
0
Javathought