首页 > 解决方案 > RESTful api 及相关资源

问题描述

我正在开发我的第一个 RESTful api,(不幸的是)是在一个已经存在的系统上完成的,其想法是允许第三方访问这个系统。

一切都很好,直到我意识到我有多种方法可以访问相同的资源。我将尝试使用系统的一部分来解释它。该系统是使用 Laravel 5.8 构建的,其中包括以下数据库表:

每个用户可以有很多封邮件,每封邮件只属于一个用户。这同样适用于短信。

我已经“忽略”了所有当前代码,因为它没有建立在使其成为 RESTful api 的正确方法上,所以我创建了一个新文件夹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

通过这种方式,我可以获得用户列表,获取用户的所有详细信息,获取电子邮件/短信列表,还可以获得特定电子邮件/短信的所有详细信息。但是,其中一个要求是拥有一个包含电子邮件/短信列表的页面,因此拥有以下内容开始变得有意义:

/api/v1/emails
/api/v1/emails/1
/api/v1/sms
/api/v1/sms/1

为了避免让 2 个端点获取相同的资源(/api/v1/users/1/emails/1并将/api/v1/emails/1返回 id 为 1 的电子邮件),我正在考虑摆脱深层端点/api/v1/users/1/emails并将它们更改为类似/api/v1/emails?user_id=1.

这是否违反 RESTful 原则?我无法就我的研究得出关于让 2 个端点访问同一资源的结论,但它“感觉”不正确。另一方面,/api/v1/emails?user_id=1可能会引起一些安全/隐私问题(例如,我需要确保用户 1 只能访问/api/v1/emails?user_id=1而不能访问/api/v1/emails?user_id=2),但似乎更灵活,因为我可以单独使用它来获取所有资源或使用user_id 过滤器仅获取特定资源。

这种情况有约定吗?

标签: phplaravelrest

解决方案


回顾一下我们如何理解REST 上下文中的“资源”可能会有所帮助。

任何可以命名的信息都可以是资源:文档或图像、时间服务(例如“洛杉矶今天的天气”)、其他资源的集合、非虚拟对象(例如人)等等. 换句话说,任何可能成为作者超文本参考目标的概念都必须符合资源的定义。

/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 完全不知道标识符是否应该是可猜测的。

为您的标识符选择拼写以使您的实现更简单是完全在范围内的。


推荐阅读