REST:“动作”的另一个问题
我仍在尝试理解 REST 中的某些情况,其中使用由名称而不是动词定义的资源不如简单 CRUD 情况那么直观。
我有一个“更新”资源,用于后端的更新/插件,其 Json 表示如下:
{
"id": 1,
"name": "Update Example",
"description": "demo update , adds handling of basic arduio type devices",
"version": "0.0.4",
"link":
{
"rel": "self",
"uri": "http://demo.org/updates/1",
"type: application/json"
},
}
编辑: 为了澄清达雷尔·米勒(Darrel Miller)的回答后的一些事情:更新“更新”集合资源已经就位,它的工作原理如下:
- 后端根据从外部服务器(通过轮询)获取的更新列表来填充该集合(不使用休息,更新描述很少,纯文本)
- 使用API的用户无法添加更新,他所能做的就是获取更新列表,然后安装/卸载它们
现在的问题是:
我需要找到一个适当的、平静的通过 API 安装 更新的方法,我想出了几种方法来做到这一点,但它们对我来说似乎“不太正确”:
1- 添加更新资源的链接,添加安装资源并利用hateoas
将其添加到更新中:
"link":
{
"rel": "Installation",
"uri": "http://demo.org/updates/1/installation",
"type: "application/json"
}
安装资源:
{
"installing": false,
"installProgress": 0,
"link":
{
"rel": "self",
"uri": "http://demo.org/updates/1/installation",
"type: "application/json"
}
}
要启动安装过程,用户将发布到demo.org/updates/1/installation 将 "installing": false
更新为 "installing": true
这看起来可行,但是将“安装”添加为简单的布尔属性是个好习惯吗?
2- POST 到 demo.org/installations 这样的 uri,添加新的 Installation 资源,
从而启动安装过程,并且还需要在新创建的安装资源中添加正在下载的更新的链接:
{
"installProgress": 0,
"link":
{
"rel": "update",
"uri": "http://demo.org/updates/1",
"type: application/json"
},
}
虽然这可能会在逻辑上将安装资源集中到安装集合中,但我最初的反应是删除此集合中的一个项目以停止其安装。
在这种情况下,如果安装资源实例消失,则每次“导航”时使用更新上的“安装”链接是否都必须重新创建新的安装资源?
更一般地说,在更新本身中拥有“已安装”属性以整体有意义不是更好吗?
另外,如果用户想要暂停诸如安装之类的操作怎么办?
我查看了很多 类似 问题在各种文章和stackoverflow上,但我仍然不太确定解决此类问题的最佳方法是什么。 另外,我知道 REST 与动词无关(超出 HTTP 动词),但我仍然相信这是一个有效的问题。
所以,非常欢迎任何反馈!
提前致谢。
I am still trying to wrap my head around certain cases in REST where using resources defined by names instead of verbs is less intuitive than in simple CRUD cases.
I have an "Update" resource, for updates/addons of the backend, with a Json representation as follows:
{
"id": 1,
"name": "Update Example",
"description": "demo update , adds handling of basic arduio type devices",
"version": "0.0.4",
"link":
{
"rel": "self",
"uri": "http://demo.org/updates/1",
"type: application/json"
},
}
EDIT:
To clarify things a bit following Darrel Miller's answer: an updates "Updates" collection resource is already in place and it works like this:
- The back-end populates that collection based on a list of updates fetched (via polling) from an external server (that does not use rest, the update descriptions there are minimal, and pure text)
- The user using the API cannot add updates, all he can do is get the updates list, and install/ uninstall them
Now the problem is this:
I need to find a proper, restfull way to install updates via the API, and I came up with a few ways to do this, but they all seem "not quite right" to me:
1- Add a link to the Update resource, add an Installation resource and make use of hateoas
Add this to the update:
"link":
{
"rel": "Installation",
"uri": "http://demo.org/updates/1/installation",
"type: "application/json"
}
Installation resource :
{
"installing": false,
"installProgress": 0,
"link":
{
"rel": "self",
"uri": "http://demo.org/updates/1/installation",
"type: "application/json"
}
}
To start the installation process the user would then POST to demo.org/updates/1/installation to update "installing": false
to "installing": true
This seems like it would work but is it good practice to add the "installing" as a simple boolean attribute?
2- POST to a uri like demo.org/installations , to add a new Installation resource
Thereby starting the install process, and also requiring the addition of a link to the update being downloaded inside the newly created Installation resource :
{
"installProgress": 0,
"link":
{
"rel": "update",
"uri": "http://demo.org/updates/1",
"type: application/json"
},
}
While this may centralize the Installation resource logically into an Installations collections, my original reflex would have been to DELETE an item in this collection to stop its installation .
In that case if the Installation resource instance is gone , would the use of the "installation" link on the update have to recreate a new installation resource every time it is "navigated" ?
More generally, would it not be better to have an "installed" attribute in the Update itself to make sense overall ?
Also what if the user wants to pause something like an installation ?
I have looked at a lot of similar questions in various articles and here on stackoverflow, but i still am not quite sure what the best way to tackle these kinds of problems is.
Also , I know REST is not about verbs (beyond the HTTP ones) but I still believe this is a valid question.
So please, any feedback is very welcome !
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您发布到“更新”集合资源怎么样?这将返回一个 202,其中包含指向临时“安装”资源的位置链接。安装完成后,它将包含指向已部署的“更新”资源的链接。在某些时候,您可以对安装资源进行垃圾回收。
因此,对我来说,直观上您会向更新集合中添加更新,如果您想查看以前安装的更新,您可以获取此集合。纯粹在安装过程中可用的操作(例如暂停和取消)可以作为“安装”资源中的链接提供。
更新:
好的,如果用户无法 POST 到 /updates,那么另一种方法是创建一个名为“Installer”的处理资源。
暂停和取消条款是我将用于 rel 的条款。没有人应该为此为难你。对于这些 rels 使用什么 URI 有点棘手。取消肯定可以通过删除安装资源来完成。也许您可以通过对
/installation/345/status
执行 PUT 来暂停。要实施这些额外的操作几乎肯定需要创建某种其他类型的资源/子资源。没关系。在我看来,如果新资源可以简单地解决您的问题,您应该毫不犹豫地创建新资源。我们只有 HTTP 方法可以使用,因此对复杂行为进行建模需要我们利用新资源发挥创意。
How about if you POST to an "Updates" collection resource. That would return a 202 with a Location link to a "Installation" resource that is transient. When the installation finishes it would contain a link to the deployed "update" resource. At some point you can garbage collection the installation resources.
So for me, intuitively you would add an update to the updates collection and if you wanted to see previously installed updates you could GET this collection. Operations that are available purely during the installation process, like pause and cancel, they can be made available as links in the "installation" resource.
Update:
Ok, so if the user cannot POST to /updates then another approach is to create a processing resource called "Installer".
The pause and cancel terms are what I would use for the rel. Nobody should give you a hard time for that. What URI you use for those rels is a bit more tricky. Cancel could definitely be done by deleting the installation resource. Maybe you could do pause by doing a PUT to
/installation/345/status
.To implement those additional actions will almost certainly require creating some other kind of resource/sub-resource. That's fine. In my opinion you should never hesitate to create a new resource if it is a simple solution to your problem. We only have the HTTP methods to work with so modelling complex behaviour requires us to get creative with new resources.