Odata V4 Spec表示Actions可能有可观察到的副作用,应该使用HTTP POST调用。但我们确实有需要使用仅修改某些状态的操作的场景。
例如:
1.
您可能希望将标识为id的文档的状态标记为已锁定
端点 - ... / Documents({id})/ lock()。
由于我在这里做了部分更新,在我看来PATCH更合适。
你可能想提供两种删除文件的方法
a)只需隐藏终点 - ..... / Documents({id})
这是HTTP DELETE(无争议)
b)永久删除终点 - ..... / Documents({id})/ permanentDelete()
这作为ODATA操作。
在我看来,HTTP删除更合适这里没有HTTP POST。
从Odata的角度来看,推荐的方法是什么?非常感谢任何帮助。
以下是SPEC的信息。
SPEC 11.5.4行动
操作是由OData服务公开的操作,在调用时可能会产生副作用。动作可以返回数据,但不能进一步用其他路径段组成。 11.5.4.1调用操作
要调用绑定到资源的操作,客户端会向操作URL发出 POST 请求。可以从先前返回的实体表示获得动作URL,或者通过将名称空间或别名限定的动作名称附加到URL来标识动作URL,该URL标识类型与绑定参数的类型相同或源自的绑定参数的类型。那个行动。绑定参数的值是在附加操作名称之前由URL标识的资源的值,并且根据特定格式在请求主体中传递任何非绑定参数值。
提前致谢
--ksp
答案 0 :(得分:1)
从OData的角度来看,你总是要用POST来调用一个动作,而其他任何动词都不行。
你的两个例子都是我个人认为不适合某个动作的东西,因为已经有办法用OData做这些事情,并且他们使用你提到的动词。更新属性支持一个DELETE支持PATCH和删除对象。你提到你有两种不同类型的删除操作,这更难,但你可以使用自定义标题来区分它们。
操作往往不适合普通的CRUD操作,因此并不总是清楚应该使用哪个HTTP谓词。
在您的示例中,感觉确实想要使用DELETE和PATCH。然而,问题的出现是因为我们需要遵循一个标准,请记住,OData操作都可以通过元数据发现,因此客户可以使用它而不知道实际操作的内容,在这种情况下,我们需要有定义的东西。既然我们知道动作会以某种方式影响服务器,对我而言,POST似乎是对所有操作都一致的最不好选择。
答案 1 :(得分:0)
最后,作为作者,您可以命令自己的API。正如我们不应在C#类设计中使用会在其他属性中引起副作用的属性一样,这并不意味着我们做不到,而且这很普遍。
从OData的角度来看,
PATCH
类似于使用属性访问器,而 actions 或POST
用于访问方法。
在PATCH
或POST
之间做出决定以影响更改,因此在使用属性 mutators (使它们可写)或强制调用者设置其属性之间,存在相同的设计决策。通过相关的方法值。
- 您可能希望将ID标识的文档的状态标记为已锁定 端点-... / Documents({id})/ lock()。 由于我在这里进行了部分更新,因此我认为PATCH更合适。
如果您的资源具有名为Locked
的属性,而您当前的lock()
Action 仅将Locked
属性设置为{ {1}},那么您可以可以简单地使用true
来更新该PATCH
字段。
一些专门用于 lock 进程的 Action 的常见原因:
Locked
时执行特定的逻辑,并且希望在其自己的方法中维护此逻辑,而不是在修补程序处理程序中使用复杂的条件逻辑。lock()
供所有人使用 ,大概只是锁定该资源的用户可以释放锁或其他需要满足的条件。
unlock()
的访问限制为某些安全组,但是您希望所有用户都具有对lock()
状态字段的读取访问权限。Locked
,甚至还有LockedBy
。虽然所有这些逻辑 都可以在控制器的单个DateLocked
端点逻辑中进行管理,但我无法强调这将如何使您的解决方案随着时间的推移难以管理。资源的复杂性会增加。
更重要的是::已记录并接受的约定是PATCH
将不具有副作用,因此无需执行{{ PATCH
之后的1}},因为服务器上已接受客户端的相同更改。相反,由于GET
MAY 具有副作用,因此,如果来自{{的响应,则客户可以期望执行PATCH
以获取所有相关更改,这是合理的。 1}}不包含更新的资源。
在POST
与GET
的情况下,现在事情变得个人化/自以为是了……
按照惯例,对POST
的期望是双重的:
Delete
的集合查询结果中PermanentlyDelete
出现在项目请求中从服务器的角度来看,如果我的资源具有 soft 删除,则只需设置一个标志,而 permanent 删除则从基础存储中删除记录,那么按照惯例,我将对{em> soft 删除使用称为DELETE
的{{1}},而对 permanent 删除应该使用GET
http动词。
GET
的讨论相同。但是,如果 soft 与 permanent 删除的目的是拦截客户端的标准删除工作流程,则永久删除概念将被隐藏或以某种方式抽象化而不是通常的工作流程的一部分(用户必须去其他地方,例如回收站以查看已删除的记录并还原或永久删除),在这种情况下,请使用HTTP动词{{ 1}}进行软删除,并进行特定的,可能是集合绑定的 Action 来接受永久删除的请求
Action
返回Delete()
,那么我们将无法真的希望DELETE
执行...