RESTful设计:何时使用子资源? [英] RESTful design: when to use sub-resources?

查看:176
本文介绍了RESTful设计:何时使用子资源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在设计资源层次结构时,应该何时使用子资源?



我曾经认为,当资源不能存在时,它应该被表示为其子资源。我最近遇到了这个反例:




  • 员工在所有公司中都是唯一可识别的。

  • 员工的访问控制和生命周期取决于公司。



我将其建模为: /公司/ {companyName} / employee / {employeeId}



注意,我不需要查找公司才能找到员工我应该怎么办?如果我这样做,我付出代价来查找我不需要的信息。如果我没有,这个URL会错误地返回HTTP 200:



/ Companies / {nonExistingName} / employee / {existingId}


  1. 我应该如何将资源归属于另一个?

  2. 我应该如何表示资源无法识别的事实?

  3. 子资源意味着什么关系,而不是意味着什么一个年以后,我结束了以下妥协(对于数据库行,它包含唯一的标识符):


    1. 将所有资源分配给根目录中的规范URI(例如 / companies / id} / employees / {id} )。

    2. 如果资源不能存在,它应该被表示为其子资源;但是,将操作视为搜索引擎查询。意思是,不要立即执行操作,只需返回指向规范URI的 HTTP 307(Temporary redirect)。这将导致客户端针对规范的URI重复操作。

    3. 您的规范文档应仅公开与您的概念模型相匹配的根资源(不依赖于实现细节)。实施细节可能会改变(您的行可能不再是唯一可识别的),但您的概念模型将保持不变。在上面的例子中,您可以告诉客户关于 / company 而不是 / employees

    这种方法有以下好处:


    1. 它消除了需要做不必要的数据库查找。

    2. 它将每个请求的理智检查数量减少到一个。最多的是,我必须检查员工是否属于公司,但我不再需要对 / Companies / {companyId} / employees / {employeeId} / computers / {computerId}进行两次验证检查

    3. 它对数据库可扩展性有不同的影响。一方面,您通过在较短的时间内锁定较少的表来减少锁争用。但另一方面,您正在增加死锁的可能性,因为每个根资源必须使用不同的锁定顺序。我不知道这是否是净损益,但是我仍然安慰,因为无法阻止数据库死锁并且所得到的锁定规则更容易理解和实现。如有疑问,请选择简单。

    4. 我们的概念模型保持原样。通过确保规范文档仅暴露我们的概念模型,我们可以随时删除包含实现细节的URI,而不会破坏现有客户端。请记住,只要您的规范将其结构声明为未定义,任何事情都不会阻止您在中间URI中公开实施细节。


    When designing resource hierarchies, when should one use sub-resources?

    I used to believe that when a resource could not exist without another, it should be represented as its sub-resource. I recently ran across this counter-example:

    • An employee is uniquely identifiable across all companies.
    • An employee's access control and life-cycle depend on the company.

    I modeled this as: /companies/{companyName}/employee/{employeeId}

    Notice, I don't need to look up the company in order to locate the employee, so should I? If I do, I'm paying a price to look up information I don't need. If I don't, this URL mistakenly returns HTTP 200:

    /companies/{nonExistingName}/employee/{existingId}

    1. How should I represent the fact that a resource to belongs to another?
    2. How should I represent the fact that a resource cannot be identified without another?
    3. What relationships are sub-resources meant and not meant to model?

    解决方案

    A year later, I ended with the following compromise (for database rows that contain a unique identifier):

    1. Assign all resources a canonical URI at the root (e.g. /companies/{id} and /employees/{id}).
    2. If a resource cannot exist without another, it should be represented as its sub-resource; however, treat the operation as a search engine query. Meaning, instead of carrying out the operation immediately, simply return HTTP 307 ("Temporary redirect") pointing at the canonical URI. This will cause clients to repeat the operation against the canonical URI.
    3. Your specification document should only expose root resources that match your conceptual model (not dependent on implementation details). Implementation details might change (your rows might no longer be unique identifiable) but your conceptual model will remain intact. In the above example, you'd tell clients about /companies but not /employees.

    This approach has the following benefits:

    1. It eliminates the need to do unnecessary database look-ups.
    2. It reduces the number of sanity-checks to one per request. At most, I have to check whether an employee belongs to a company, but I no longer have to do two validation checks for /companies/{companyId}/employees/{employeeId}/computers/{computerId}.
    3. It has a mixed impact on database scalability. On the one hand you are reducing lock contention by locking less tables, for a shorter period of time. But on the other hand, you are increasing the possibility of deadlocks because each root resource must use a different locking order. I have no idea whether this is a net gain or loss but I take comfort in the fact that database deadlocks cannot be prevented anyway and the resulting locking rules are simpler to understand and implement. When in doubt, opt for simplicity.
    4. Our conceptual model remains intact. By ensuring that the specification document only exposes our conceptual model, we are free to drop URIs containing implementation details in the future without breaking existing clients. Remember, nothing prevents you from exposing implementation details in intermediate URIs so long as your specification declares their structure as undefined.

    这篇关于RESTful设计:何时使用子资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆