在一般的REST架构中,基本概念是资源。 在资源之后,下一步是为这些资源开发一个统一接口,这在HTTP领域通常意味着:
- 创建为POST
- 阅读就是GET
- 更新为PUT(或部分更新为PATCH)
- 删除已删除
在现实世界中,不可避免地某些操作不会很好地映射到资源。 通常这是少数操作,例如重置密码。 可以将它们建模为
- / password /上的PUT
或作为
- 控制器端点和到/ resetpassword的POST
后者可能被认为比纯REST更接近于程序化REST,但是有时客户和客户希望您务实。 本文提供了有关何时考虑使用Controller选项的建议。
动作是否映射到CRUD?
现实应用程序中的几个动作无法很好地映射到CRUD。 例如,贝宝的取消计费协议API是:
POST /v1/payments/billing-agreements/agreement_id/cancel
取消动作很少能很好地映射到资源的CRUD。 它可以解释为:
- 一些资源被创建(取消记录)
- 一些资源被更新(某些状态列可能被设置为取消)
- 或某些资源被删除(订单请求被删除)。
客户为什么要关心取消的处理方式? 难道它总是会改变吗? 在某些情况下,使用HTTP隧道的API不能很好地映射到CRUD问题。 在取消帐单协议中,这将是:
POST /v1/payments/billing-agreements/agreement_id
与身体:
{"operation":"cancel"
}
这被认为是反模式,决不能使用。 而是应使用控制器端点。
资源状态或工作流程?
在REST体系结构中,客户端或服务器之间的每个请求通常都会更改资源状态(写操作)或应用程序状态(查询或读操作)。 但是,在现实世界中,工作流是不可避免的。 例如,重置密码流程通常包括:
- 向用户询问userId(通常是电子邮件)
- 系统检查系统上是否存在电子邮件
- 向用户发送包含重置密码链接的电子邮件
- 确保用户只有一定时间才能单击链接
- 当用户单击链接时,他们可能会被问到一系列问题
- 他们将被要求重新输入新密码,以确保没有错字
当客户端操作是复杂工作流的一部分时,资源状态和应用程序状态更改可能不容易建模。 它们可能不会同步发生,并且可能会根据工作流的建模方式或工作流何时需要添加额外的步骤进行更改。 在这种情况下,请考虑使用控制器端点。
无需PUT的REST
在某些情况下,可以设置参数以避免使用PUT,而可以使用POST到另一个表示意图的端点。 例如,要更改地址而不是将PUT调用到/ address /,客户端将调用POST到/ changeaddress并完全避免使用PUT。 这里的想法是使命令/查询分离更严格。 有关更多信息,请参见https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling。 通常,建议使用PUT / PATCH进行更新/部分更新,并且仅在前两个原因之一适用时才使用控制器端点。
那么,为什么何时使用控制器样式终结点可能涉及主观性。 以上至少可以帮助您做出决定。 请记住,在您考虑采用这种方法的情况下,它应该永远只是少数API。 您在常规的Uniform Interface之外,无法进行独特的样式操作,但是您仍然希望使它们对API的客户来说很直观。
翻译自: https://www.javacodegeeks.com/2018/05/rest-using-a-controller-endpoint.html