我已经阅读了一些有关RESTful API设计的有趣教程,其背后的概念非常清楚...但是现在让我们将其与Play一起实践。

假设我们要实现一个RESTful API,该API提供了与用户打交道的功能。让我们从模型开始。这是Address类:

case class Address(
  id: Int,
  street: String,
  zip: String,
  city: String,
  country: String
)

...这是User类:
case class User(
  id: Int,
  email: String,
  firstName: String,
  lastName: String,
  addresses: Array[Int]
  // addresses: Array[Address] would this option be better?
)

...最后是路线:
# Creates a new user
POST   /users                     controllers.users.create

# Gets the user identified by the specified id
GET    /users/:userId             controllers.users.find(userId)

# Modifies the user identified by the specified id
PUT    /users/:userId             controllers.users.update(userId)

# Deletes the user identified by the specified id
DELETE /users/:userId             controllers.users.delete(userId)

第一个问题是:如何通过电子邮件检索用户,使我的API投诉与REST规则保持一致?以下内容无效,因为它与GET users/:userId冲突:
# Gets the user identified by the specified email address
GET    /users/:email              controllers.users.findByEmail(email)

到目前为止,我想到的两个选项是:
GET    /users                     controllers.users.list(Option[email])

要么
GET    /users/:email/xxx          controllers.users.findByEmail(email)

其中xxx应该是一种虚拟资源。有什么建议吗?

我的第二个也是最后一个问题是:我应该如何管理用户地址?我应该获取User,将新的Address添加到User.addresses,然后使用PUT更新User吗?
PUT    /users/:userId             controllers.users.update(userId)

...还是我应该创建一个特定的 Controller 来管理这样的用户地址?
POST   /users/:userId/addresses/  controllers.addresses.create(userId)

我个人更喜欢第二种选择……但是也许有更好的选择。

最佳答案

第一个问题是:如何通过电子邮件检索用户,使我的API投诉与REST规则保持一致?

我想说的简单GET /users/email/:email controllers.users.findByEmail(email)如果存在具有给定电子邮件的用户,则返回200,否则返回404。

我可以看到景点,但我会为@Robin搏击他的想法。从技术上讲这是可行的,但是由于我对REST的Identification of Resources元素的解释,它对我来说并不是REST风格的。另外,合并两个或多个标识符在服务器上消除歧义的可能性使我感到震惊,因为脆弱的代码最终将迫使我在周末工作,因为用户标识符会随着需求的变化而来去去–迫使我在和过度。我也可能因看到规范方法名称(如findByNamefindByEmail等)而偏颇,但从未看到findByYourGuessIsAsGoodAsMine

我的第二个也是最后一个问题是:我应该如何管理用户地址?我应该获得一个用户,将新地址添加到User.addresses,然后使用PUT更新该用户吗?...还是应该创建一个特定的 Controller 来管理这样的用户地址?

显然,用户是有趣的资源,而不是电子邮件(请注意,我在使用电子邮件的地方使用地址来区分实际地址)。本质上,我的路线看起来像users/:userId/emails/,并在Users Controller 中进行管理。从软件工程角度或意识形态REST角度来看,我都没有理由增加额外的类的开销。

07-24 09:45
查看更多