【问题标题】:REST API Resource GranularityREST API 资源粒度
【发布时间】:2022-01-04 17:18:29
【问题描述】:

我想就资源粒度获得意见。比如说,我有一个名为“杂志”的域实体。但有不同类型的杂志,包括体育、自然、汽车、计算机和飞机等。 当我想创建一个新的“体育”杂志时,我应该使用以下结构:

  • PUT /杂志
  • PUT /体育杂志
  • PUT /杂志/体育

当我想获得特定的体育杂志时,我应该说:

  • GET /magazines/{id}
  • GET /sports-magazines/{id}
  • GET /magazines/sports/{id}

如果我想获得 2001 年的体育杂志,我应该使用:

  • GET /magazines?type=sports&year=2001
  • GET /sports-magazines?year=2001
  • GET /magazines/sports?year=2001

最后,如果我想返回 2001 年 1 月出版的每种类型杂志的页数,我该怎么做?我需要为此创建一个新的 pages 资源吗?或者提出两个独立的请求或其他什么?下面列出了其中的第一个:

  • GET /magazines/pages?type1=sports&type2=nature&year=2001&month=01
  • GET /sports-magazines/pages?type=nature&year=2001&month=01

鉴于这些场景,您将如何为您的资源建模?

【问题讨论】:

    标签: api rest api-design restful-url


    【解决方案1】:

    我有一个名为“杂志”的域实体。但有不同类型的杂志,包括体育、自然、汽车、电脑和飞机等。

    需要理解的重要一点:资源不是域实体。您的资源模型是位于域模型前面的外观。

    请注意,例如,此资源 (REST API Resource Granularity) 不仅描述了您的问题,还描述了我的答案。


    PUT 可能不是您想要的“创建新资源”,除非客户端已经知道应该为新资源使用什么 URI。 PUT 请求的目标 URI 与我们希望稍后用于获取数据的 URI 相同

    PUT /magazines/{id}
    GET /magazines/{id}
    

    如果我们不希望客户端知道 URI 将是什么......好吧,我们没有一个 HTTP 方法可以准确地表达这个意思,所以我们回退到使用 POST(参见Fielding, 2009)。

    POST /magazines
    
    201 Created
    Location: /magazines/12345
    

    请注意,机器并不关心所创建资源的 URI 是否与 POST 请求的目标 URI 匹配。


    REST 真的不关心您对资源标识符使用什么拼写约定(就像机器不关心您对变量名使用什么拼写约定一样)。

    GET /magazines?type=sports&year=2001
    GET /sports-magazines?year=2001
    GET /magazines/sports?year=2001
    GET /magazines/sports/year=2001
    GET /magazines/sports/2001
    

    这些都很好;有取舍。编码到查询字符串中的键值对可以更轻松地使用 HTML 表单创建 URI,使用路径段可以更轻松地进行相对解析。


    我想返回 2001 年 1 月出版时每种杂志的页数

    使用该信息创建一个新的 URI 很好。扩展现有资源的架构以包含该信息也可以。

    【讨论】:

    • 很好的答案。 “您的资源模型是位于您的域模型前面的外观。”这句话很好地总结了它。为了进一步扩展,这就是信息模型可以分层的方式。 * 持久模型(物理表和视图) * 域模型(根据您的功能和域边界)有帮助。
    猜你喜欢
    • 2011-09-24
    • 2016-05-23
    • 2015-11-18
    • 2021-12-09
    • 1970-01-01
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多