我正在开发我的第一个RESTful api,(不幸的是)该API在已经存在的系统上完成,其想法是允许第三方访问此系统。
一切都很好,直到我意识到我可以通过多种方式访问相同的资源。我将尝试使用系统的一部分来解释它。该系统是使用Laravel 5.8构建的,除其他外,还具有以下数据库表:
每个用户可以有许多电子邮件,并且每封电子邮件仅属于一个用户。短信也是如此。
我已经“忽略了”所有当前代码,因为它不是基于使它成为RESTful api的正确方法而建立的,所以我创建了一个新文件夹WHERE REPLACE(d.value, '-', '') = '1234'
,所有代码都在那里
我认为拥有以下端点是有意义的
Api
通过这种方式,我可以拥有用户列表,获得用户的所有详细信息,获得电子邮件/文本的列表以及获得特定电子邮件/文本消息的所有详细信息。但是,其中一项要求是要有一个包含电子邮件/短信列表的页面,因此开始具有以下意义:
/api/v1/users
/api/v1/users/1
/api/v1/users/1/emails
/api/v1/users/1/emails/1
/api/v1/users/1/sms
/api/v1/users/1/sms/1
为了避免有2个端点获取相同的资源(/api/v1/emails
/api/v1/emails/1
/api/v1/sms
/api/v1/sms/1
和/api/v1/users/1/emails/1
将返回ID为1的电子邮件),我正在考虑摆脱深层端点/api/v1/emails/1
和将它们更改为/api/v1/users/1/emails
。
这是否违反RESTful原则?我无法得出有关有2个端点访问同一资源的结论,但这并不“正确”。另一方面,拥有/api/v1/emails?user_id=1
可能会引起一些安全性/隐私问题(例如,我需要确保用户1只能访问/api/v1/emails?user_id=1
而不能访问/api/v1/emails?user_id=1
),但似乎更多之所以具有灵活性,是因为我可以单独使用它来获取所有资源,也可以使用user_id过滤器来仅获取特定资源。
这种情况有约定吗?
答案 0 :(得分:1)
回顾一下我们如何了解REST context.中的“资源”可能会有所帮助
任何可以命名的信息都可以是资源:文档或图像,临时服务(例如“洛杉矶今天的天气”),其他资源的集合,非虚拟对象(例如人),等等。换句话说,任何可能成为作者超文本引用目标的概念都必须符合资源的定义。
/api/v1/users/1/emails
/api/v1/emails?user_id=1
/66eb6757-254e-49b4-bc8a-d04330f4482e
REST将标识符视为语义上不透明的对象-通用客户端不使用标识符的拼写来理解正在发生的事情。考虑一个网络浏览器-它知道http://example.org/cat.jpg
是图像,不是因为jpg
,而是因为img
。
这意味着服务器可以使用喜欢的任何拼写-编码到URI本身的任何信息都由服务器自行决定并供其自己使用。
这并不是说使用“可猜测的”拼写没有优势;只是REST完全不知道标识符是否应该是可猜测的。
选择使您的实现更简单的标识符的拼写完全在界限之内。