【问题标题】:REST API response depending on who made the requestREST API 响应取决于发出请求的人
【发布时间】:2021-07-20 15:52:40
【问题描述】:

我正在开发一个公共和私有 REST API,我想问一些关于非/登录用户的问题。

我们使用以下 gem 来Serialize 每个对象。

案例A:

我网站的公共部分显示了一些书籍详细信息。我的端点是 GET /api/books/{book_id}。假设 book_id 为 1。 对于未登录的用户,响应如下:

{
  id: 1,
  name: "Harry Potter and the philosopher's stone"
}

对于登录用户,我想要这样的东西:

{
  id: 1,
  name: "Harry Potter and the philosopher's stone",
  author: "J. K. Rowling"
}

如您所见,作者详细信息仅适用于登录用户(我不关心用户角色)。

案例 B:

取决于用户角色。

假设我想通过 GET /api/users/{user_id} 查询一些用户信息。假设 user_id 也是 1。

作为登录用户和非管理员用户,我会收到以下回复:

{
 id: 1,
 name: "John"
}

但作为管理员,我希望收到:

{
 id: 1,
 name: "John",
 address: "9th street in the East Village, Manhattan"
}

作为非登录用户,它应该返回 401 错误。未授权。

请注意,本例中的地址信息仅供管理员用户使用。

我想知道这个逻辑是应该在两个不同的端点中,还是在同一个端点中。我不想在同一个 URL 中使用任何查询参数。

对我来说,根据提出请求的人而拥有一个具有多个返回的端点真的很令人困惑。我看过一些关于基于 rol 的 REST API 的文章,但有时似乎不是很清楚,这取决于你。

另外,我的疑问与 POST 请求有关。知道将接收哪个参数真的很令人困惑。我在想如果你有 6/7 个角色,你需要根据一些业务逻辑有不同的结果。

【问题讨论】:

标签: ruby-on-rails rest permissions user-roles clean-architecture


【解决方案1】:

有一个选项if 可以传递给attribute 方法:

案例A:

class BookSerializer < ActiveModel::Serializer
  attribute :id
  attribute :name
  attribute :author, if: :user_signed_in?

  def user_signed_in?
    scope.present?
  end
end

案例 B:

class UserSerializer < ActiveModel::Serializer
  attribute :id
  attribute :name
  attribute :address, if: -> { scope.admin? }
end

详情见official documentation on GitHub

就我个人而言,我宁愿在这两种情况下都使用一个端点,因为它是一种更简单的解决方案,无需重复代码。

【讨论】:

  • 感谢您的评论。那是我的 B 计划。我知道 Serializer 的这些功能,但我相信在 Serializer 中编写一些业务逻辑并不是真正“干净”的。最后,序列化器只是将数据转换为 JSON,在我看来它不应该有任何逻辑。这就是我打开这个讨论的原因。
  • @rails95 我不认为这是序列化程序中的业务逻辑。在案例 A 中,我们添加一个方法 user_signed_in?,它是一个 应用程序 逻辑,在案例 B 中,我们只使用 User 模型附带的业务逻辑。
猜你喜欢
  • 1970-01-01
  • 2014-09-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-17
  • 2018-04-30
  • 1970-01-01
  • 1970-01-01
  • 2018-03-26
相关资源
最近更新 更多