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:
/users/byid/48573
/users/48573?fetchby=id
oder /users/48573?byid=true
/identifiers/username/48573
Welcher von diesen (wenn vorhanden) ist dem richtigen REST am nächsten? Wie würden Sie mit dem Problem umgehen?
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);
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.
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>>
}