使用替代查询选项命名 GET

Naming a GET with alternative query options

假设您有一个 REST 服务已经通过 ID 获取用户,所以 url 看起来像

GET /users/{userId}

但是您想创建一个通过电子邮件获取用户的重复 Web 服务,因此:

GET /users/{email}

哪个更好?

方法一:

同样的方法:

  /users/{input}
  ...
  if(isEmail(input)) queryByEmail(input);
  else queryById(input);

方法二:

不同的方法:

GET /users/{userId}

GET /usersByEmail/{email}

我个人的偏好是,

GET /users/id/{id}
GET /users/email/{email}

但这完全取决于您的其他端点的外观。

因为电子邮件地址和 ID 之间没有实际重叠。我只会对两者使用相同的端点。特别是如果 GET /users/{id} 已经是一个 已发布的 接口。

所以,我会选择第一种方法。

GET /users/{identifier}

然后在 API 服务器上你必须添加一个小检查,检查 {identifier} 是否是一个数字。

我还想指出,"pretty URLs" 不能让它成为 REST :) 你可能会想看这个讲座:https://www.youtube.com/watch?v=pspy1H6A3FM

Which is better?

REST 不关心;从客户端的角度来看,URI 是不透明的。客户关注的是 links/submitting forms/completing 模板。

编码到 URI 中的信息由服务器自行决定并仅供其自己使用。

所以你可以使用任何你喜欢的拼写。通常,遵循本地拼写约定是个好主意(这与代码中的变量名应遵循编码约定的方式大致相同)。但是您的客户不需要知道这些约定的细节。

/users/{input}
...
if(isEmail(input)) queryByEmail(input);
else queryById(input);

请注意,您不一定完全致力于一种方法;这是将标识符与表示分离的 的一部分。例如,您的实现可以很容易地看起来像

/users/{input}
...
if(isEmail(input)) redirectTo(/users/email/{input});
else redirectTo(/users/id/{input});

它允许已为原始 URI 添加书签的客户端到达正确的资源。