【问题标题】:How to design RESTful API URI when you can't have user ID on the URI当 URI 上没有用户 ID 时如何设计 RESTful API URI
【发布时间】:2021-10-20 17:37:17
【问题描述】:

化妆场景:

假设我正在构建一个 RESTful Web API 后端来管理会员的付款计划:

  • 它是为会员准备的,所以您必须向我们注册。每个成员在内部都有一个成员 ID。
  • 有多种付款计划:6 个月的 0% 利息、12 个月的 0% 利息等。每个付款计划都有一个内部 ID。
  • 会员和付款计划之间的关系是多对多的。
  • 每个成员一次也有 1 个活动计划。您可以更改它,但会员只能使用 1 个有效计划。

现在,如果我想设计一个 API 端点来返回有关会员有效付款计划的信息,我通常会这样做:

/members/{member-id}/plans/active

我知道可能是a bad idea to put state on the URI(我对此有一个单独的问题),但请多多包涵。

现在是棘手的部分:公司的政策规定我不能在 URI 中包含成员 ID。他们将在 HTTP 标头中包含某种令牌,这是访问 RESTful API 端点所必需的,其中包含成员 ID。

顺便说一句,我的 API 应用程序是 ASP.NET Core Web API,在代码中创建过滤器来解析该令牌并将其转换为成员 ID 没有问题。只是我的 API URI 不能再有成员 ID。

在这种情况下你会如何设计 URI?

如果没有 URI 上的成员 ID,我的会是这样的

/plans/active

现在数据将全部由该成员 ID 驱动/过滤,并在 API 后端安全地进行。这正常吗?

【问题讨论】:

  • 即使您的会员 ID 是 Guid 代表?你不能在你的 Uri 上使用 memberId?

标签: rest http design-patterns restful-url


【解决方案1】:

现在数据将全部由该成员 ID 驱动/过滤,并在 API 后端安全地进行。这正常吗?

在我看来,事情好像在横向发展;好像人们不了解 REST,或者人们不了解他们试图实现的目标并不适合 REST。

为了获得统一的接口,需要多个架构约束来指导组件的行为。 REST 由四个接口约束定义:资源的标识...... -- Fielding, 2000

REST 使用资源标识符来标识组件之间交互所涉及的特定资源。 REST 连接器提供了一个通用接口,用于访问和操作资源的值集,而不管成员函数是如何定义的或处理请求的软件类型如何。分配资源标识符的命名机构,使得引用资源成为可能,负责随着时间的推移维护映射的语义有效性(即,确保成员函数不会改变)。 -- Fielding, 2000

网络基于统一资源标识符标识资源的共同理解工作。 URI 是键/值存储的键。当您开始将识别信息移动到请求的其他部分时,您将选择退出由其他所有人共享的“统一界面”。这会给互操作带来风险。

另一方面,大部分网络也假定标识符已发布,并且通常没有太多的纪律来限制它们的复制。因此,您当然不希望包含机密和/或敏感信息。

REST 中的答案是使用另一层间接。规则是我们应该使用一个 URI,并且每个标识符都应该映射到一个资源。但是并没有规定 URI 的拼写必须与资源的语义相匹配。

换句话说:网址缩短器有效!

GET /99bfb1e3-89a4-4a44-a6d7-0e70c209f447 HTTP/1.1

就 REST 而言,这是一个完全有效的请求,具有完全令人满意的标识符。只要您的服务器了解如何使用该密钥查找秘密,就可以了。

当然,您可以将语义信息添加到不敏感的 URI 中,以帮助人们定位上下文

GET /members/99bfb1e3-89a4-4a44-a6d7-0e70c209f447/plans/active HTTP/1.1
GET /members/plans/active/99bfb1e3-89a4-4a44-a6d7-0e70c209f447 HTTP/1.1
GET /members/plans/active?99bfb1e3-89a4-4a44-a6d7-0e70c209f447 HTTP/1.1

这些也都很好(再次假设您可以使用提供的信息来发现您需要生成/修改相应资源的敏感信息)。


另一方面,如果您的组织担心泄露标识符本身......那么有资历的人真的应该挑战 REST/HTTP 是解决问题的正确答案的假设。

随着您进一步偏离 HTTP 消息的“标准”,您增加了某些通用组件无法理解正在发生的事情的风险,如果这导致重大财产损失,您的律师不会不会快乐的。

【讨论】:

  • 谢谢!你的回答对我来说很有意义。在您看来,如果我们发现 REST 不是问题的正确答案,我们还能使用什么? RPC 样式是唯一剩下的吗?
【解决方案2】:

在我看来,这很正常。例如,当您使用 JWT 令牌进行身份验证时,通常会出现这种情况。令牌不仅对用户进行身份验证,还包含有关用户的相关信息。

在这些情况下,您还会看到具有此类端点的 API,但路径中没有明确显示有关用户的任何信息(如 ID 或其他内容)。

只是我的建议或观点,我实际上会将members 部分保留在路径中:/members/plans/active。

【讨论】:

  • 您介意说出您为什么要将成员部分保留在 URI 中的原因吗?
  • 除非你的 API 只处理会员的数据,否则我会添加它只是为了让它更清楚一点。
猜你喜欢
  • 1970-01-01
  • 2021-09-30
  • 1970-01-01
  • 2011-07-14
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多