web-dev-qa-db-fra.com

REST - prendre en charge plusieurs identificateurs possibles

Pour le site sur lequel je travaille, nous sommes en train d’améliorer nos URL pour un type de ressource, en particulier l’abandon des identificateurs numériques au profit de chaînes descriptives uniques. Un exemple similaire consisterait à ne plus identifier les utilisateurs par ID de base de données numérique pour les identifier par nom d'utilisateur (pas notre cas spécifique, mais notre analyse). Donc, une URL pour accéder aux informations d'un utilisateur ressemblait à ceci:

/users/48573

Et maintenant on dirait

/users/thisisausername.

Le seul problème est que nous devons encore pouvoir les récupérer via des identifiants numériques, pour les anciens utilisateurs de l'API. Il n'est pas nécessaire que les URL REST _ soient redirigées (par exemple, /users/48573 ne doit pas rediriger vers /users/thisisausername), nous avons simplement besoin d'une méthode pour obtenir les bonnes données à l'aide de l'ancien identifiant. La solution doit fournir un autre moyen d'accéder aux informations de l'utilisateur (qui comprend le nouvel identifiant, nom d'utilisateur) par identifiant, ou d'accéder uniquement au nom d'utilisateur par identifiant. Certaines solutions possibles pourraient être:

  • Utilisation d'un nœud pour spécifier une autre méthode d'identification, par ex. /users/byid/48573
  • Utilisation d’un paramètre de requête pour spécifier une autre méthode d’identification, par ex. /users/48573?fetchby=id ou /users/48573?byid=true
  • Traiter nom d'utilisateur par identifiant comme une autre ressource, par exemple /identifiers/username/48573

Lequel de ces cas (le cas échéant) est le plus proche du bon REST? Comment régleriez-vous le problème?

49
Kelly Ellis

Je pense que l’ajout d’un segment/préfixe de chemin est la meilleure réponse. S'agissant de clés secondaires uniques, ce n'est pas la même chose que la recherche (qui renvoie un ensemble d'éléments), de sorte que l'utilisation de paramètres de requête (qui ne sont pas mis en cache) ne semble pas être le meilleur choix.

Personnellement, je prévois d’utiliser un préfixe de segment de chemin délimité par "=", comme "name =" ou "email =":

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

Cela équivaut fonctionnellement à l’ajout d’un segment de chemin (par exemple, "utilisateur/nom/john.doe"), mais j’ai l’impression que cela correspond plus étroitement au modèle conceptuel. Bien entendu, il s'agit d'un détail insignifiant, car les API RESTful ne devraient de toute façon pas spécifier une structure d'URI fixe.

Ne pas utiliser de paramètres de requête permet également d'accéder aux sous-ressources naturellement:

user/name=john.doe/inbox/df87bhJXrg63

Les cadres tels que JAX-RS de Java prennent en charge le délimiteur souhaité:

@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

Votre première option est probablement la meilleure.

Recherche d'utilisateurs par ID:

/users/id/48573

Recherche d'utilisateurs par nom abrégé:

/users/name/thisisausername

S'ils omettent ce paramètre de chemin, vous pouvez toujours utiliser par défaut votre nouveau format d'utilisateur abrégé.

Une autre option que j'ai souvent vue consiste à utiliser des paramètres de requête tels que:

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

Je pense que le premier est un peu plus propre et plus lisible.

15
Chris Dail

Une question assez ancienne mais j'avais la même chose et ai finalement trouvé la solution: Utilise regex dans votre chemin param.

Voici comment j'ai codé ce cas d'utilisation

@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