【问题标题】:Howto restfully expose related-parent-child resources?如何从容地暴露相关父子资源?
【发布时间】:2010-10-09 17:48:05
【问题描述】:

我正在设计一个 api,我希望允许用户和组保存搜索,但不确定如何最好地公开此信息。我想出了一些 URI 来公开它们:

# These are for CRUD the search definitions, not running the searches
1. /users/{username}/searches # lists the searches for a user
2. /users/{username}/searches/{search-name} # CRUD a specific user search
3. /groups/{groupname}/searches # lists the searches for a group
4. /groups/{groupname}/searches/{search-name} # CRUD a specific group search
5. /searches/{search-id|search-name}
6. /searches/group/{groupname}/{search-name}
7. /searches/user/{username}/{search-name}

我认为没有权利公开所有这些 URI。这意味着有两种方法可以更新或列出对用户和组的搜索:通过 /groups/search 或通过 /search/group。这也意味着更多的支持,我担心会产生细微的差异。

搜索可以是数据库中的独立记录,与特定用户或组无关(例如,默认系统搜索或上下文相关搜索)。

因为搜索可以是独立的,所以将它们公开为/users/searches/groups/searches 感觉不对。同时,如果我在想,“鲍勃的搜索是什么?”我首先会想到/users/bob/searches,因为从逻辑上讲,它的bob's 搜索。同样,如果我想备份 bob 的帐户,他的所有个人信息都应该在 /users/bob 下。

那么,有没有人建议哪种方式更受欢迎,和/或对他们来说效果很好(或效果不佳)?

【问题讨论】:

    标签: api rest


    【解决方案1】:

    我倾向于坚持

    5. /searches/{search-id|search-name}
    6. /searches/group/{groupname}/{search-name}
    7. /searches/user/{username}/{search-name}
    

    可以通过创建一个新资源来解决备份问题,该资源包含指向整个系统中 Bob 信息的链接,例如

    GET /AccountData/Bob
    
    <div class="AccountData">
       <link rel="searches" href="/Searches/User/Bob"/>
       <link rel="options" href="/Options/User/Bob"/>
       <link rel="usagehistory" href="/History/User/Bob"/>
    </div>
    

    我的经验是,如果您尝试创建一个满足您所有使用场景的单一层次结构,您将会发疯。你就是做不到。这就是 Wiki 运行良好的原因,它们使用链接而不是层次结构来提供对信息的访问。

    我建议您更多地关注将在表示中返回的链接。

    例如

    GET /Groups/{GroupName}
    
    <div class="group">
      <div class="name">AGroup</div>
      <link rel="searches" href="/Searches/Group/AGroup"/>
    </div>
    

    使用这种方法,您不太关心 URL 结构的外观。正如罗伊所说here

    REST API 不得定义固定的 资源名称或层次结构(一个 明显的客户端和服务器耦合)

    我意识到这似乎是一个极端的立场,考虑到 SO 上的每个人似乎都在关注你的 url 需要什么样的外观才能拥有一个 RESTful API,但你考虑得越多,它就越有意义。

    附:请不要纠结于我选择 HTML 作为表示的媒体类型,我只是提请注意您并不总是需要使用自定义 XML 词汇表这一事实。

    【讨论】:

    • 我喜欢 /AccountData 用于备份帐户的想法。我对 REST 的一个疑虑是,“正确的 RESTful 设计”似乎意味着很多额外的请求。 /users/bob/searches 应该返回 303 See Other with Location: /searches/users/bob.
    • 您对附加请求是正确的。这是罗伊几周前在休息讨论中引用的一段话,似乎很合适。 “是的,RESTful 系统至少与强耦合系统有一层间接性。”
    • 客户端和服务器端缓存是 HTTP 对“大量额外请求”问题的回答。 (尽管如果您使用的不是主流网络浏览器,说起来容易做起来难。)
    • @ladenedge 你说得对,缓存绝对是避免冗余请求的最佳方式。使用 Windows 机器上的 WinINetCache 和 Java 中的 HttpCache4J,对常规的非浏览器客户端进行客户端缓存并不难。
    【解决方案2】:

    我倾向于划分查询类型(例如,一种查询是“列表搜索”查询。然后我会提出论据。例如 /searchlist?user=john。除非您尝试让这些东西被机器人和搜索引擎索引,应该可以正常工作。

    【讨论】:

      【解决方案3】:

      搜索是功能而不是资源,因此您不必在资源中使用它 URI 可能在参数中,例如

      /users/{username}?q={query string}
      /groups/{groupname}?q={query string}
      

      那么对于这个查询字符串,你有 2 个选项

       "RQL" (Resource Query Language)
      

      "FIQL" (Feed Item Query Language)
      

      【讨论】:

        猜你喜欢
        • 2019-05-25
        • 2015-02-10
        • 1970-01-01
        • 2016-08-02
        • 2011-11-06
        • 2018-12-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多