【问题标题】:REST API - Best practice for "exists in" [closed]REST API - “存在于”的最佳实践 [关闭]
【发布时间】:2020-10-26 13:53:39
【问题描述】:

假设我有一个教室,教室里有很多学生。 我想公开一个 API,告诉每个学生他的教室是什么(学生可以有多个教室)。

要公开的明显 API 是这样的:

GET https://my.app/api/students/{student_id}/classrooms

但是 - 由于教室里有我的 DB 上的学生 我必须去每个教室检查是否有学生,这可能需要很长时间(我可能有数百万个教室)

由于在我的用例中用户应该已经熟悉教室我想公开一个“存在于” API。 (当然限制该列表)

我考虑了两个选项,但都有点违反直觉。

选项 1

GET https://my.app/api/students/{student_id}/classrooms?classrooms=1,2,3...

选项 2

GET https://my.app/api/students/{student_id}/classrooms
BODY- {"classrooms": [1,2,3...]}

是否有任何选项直观/有意义,或者是否有任何其他选项?

【问题讨论】:

  • GET 的规范不支持请求正文 IIRC,因此实际上选项 2 可能是不可能的。
  • 嗨@esqew - 我已经查过了,确实不推荐,但该协议确实支持GET with body

标签: java api rest


【解决方案1】:
GET https://my.app/api/students/{student_id}/classrooms

{"classrooms": [1,2,3...]}

越界 - 我会立即拒绝代码审查,无需进一步阅读。这里的问题是它与RFC 7231

定义的GET的语义不一致

GET 请求消息中的有效负载没有定义的语义;在 GET 请求上发送有效负载正文可能会导致某些现有实现拒绝该请求。

特别是 - 通过获取资源的标识信息并将其从 URI 移动到消息正文,您实际上是从通用缓存中隐藏了该信息。您需要巨大的补偿利益才能使这种权衡值得,而我在这里看不到这种补偿。

该协议确实支持带有正文的 GET

是的,但不是有用的方式。协议允许带有正文的 GET 是绝对正确的,请参阅 RFC 7230。

请求消息框架独立于方法语义,即使该方法没有定义消息体的任何用途。

但在 GET 的情况下,主体并不意味着任何东西;就通用组件而言,GET 请求的主体只是噪音。

GET https://my.app/api/students/{student_id}/classrooms?classrooms=1,2,3...

更好。在这里,您符合 GET 的语义,缓存包含正确存储和获取表示所需的所有信息。

在您的资源设计中需要考虑的一件事是:您是否希望为每个可能的教室编号组合使用不同的文档,或者您是否希望拥有一些可在不同房间组合中重复使用的少量文档。

这是一种权衡:粗粒度资源允许您的读取更好地利用缓存,但也需要客户端代码进行更多工作。

也就是说:

由于教室里有我的 DB 上的学生,我必须去每个教室检查是否有学生,这可能需要很长时间

如果这是一个重要问题,那么也许您应该设计您的数据模型以更有机地支持它(例如能够直接通过学生 ID 获取教室)。

【讨论】:

    猜你喜欢
    • 2021-01-30
    • 2020-12-24
    • 2013-10-23
    • 2018-10-27
    • 2019-10-21
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    相关资源
    最近更新 更多