【问题标题】:REST and "never delete anything" applicationsREST 和“从不删除任何内容”应用程序
【发布时间】:2013-07-10 12:16:56
【问题描述】:

在我见过的所有企业应用程序中,几乎没有任何东西实际上从持久存储中删除,它只是用标志或删除日期标记为已删除。如果我正在设计这样的应用程序,我应该使用DELETE 请求吗?如果应该使用它们,它们应该是什么样子?例如,如果我想说阻止信用卡,我会发出类似

POST /block_orders
card_number=123&reason=card_stolen

但如果应用程序不使用所有可用动词,它看起来就不是 RESTful。 DELETE在企业中有没有一席之地?

UPD:例如,如果您以后可以GET 该资源以查看操作历史记录,那么允许DELETE 资源是否是一个好的设计?

【问题讨论】:

    标签: rest architecture


    【解决方案1】:

    DELETE 在企业中占有一席之地。

    使用 DELETE 请求将记录标记为已删除,并从 GET 请求中隐藏这些记录:就客户端而言,这些记录被删除。

    不用担心那些记录会被恢复;即使您从数据库中删除它们,它们仍然可以从备份中恢复。现在什么都真正被删除了。 :-)

    【讨论】:

    • 问题是它们没有被删除,例如,客户仍然可以GET他们查看历史记录。
    • 我会将历史视为不同的资源,然后将GET 视为历史。在此之后,向实体历史记录发出 DELETE 是没有意义的。
    • @synapse:如果您的客户仍然可以获取已删除的记录,那么您做错了 (TM)。最好返回已删除的记录,并允许特权(例如“管理员”)用户选择指定是否要获取已删除的记录。我通常使用“is_deleted”参数,可能的值为 yes|no|all。然后,我的应用会为非特权用户忽略该参数(或将其强制设为“否”)。
    【解决方案2】:

    对我来说,这听起来像是 PATCH / PUT:

    如果您想更改信用卡的状态(被阻止),请使用 PATCH more info here

    PATCH /users/<user_id>/credit_cards/<creditcard_id>/
    JSON 
    {
      "reason": "stolen"
    }
    

    如果您通过请求提供所有资源,要在知道其标识符的情况下对其进行编辑,请使用 PUT。

    DELETE 与删除标志方法完美契合。只需在收到 DELETE 请求时更新该标志,如果用户尝试检索资源,只需向她/他提供该被阻止信用卡的可用信息。但是在您的情况下,我不会使用它来阻止信用卡...当用户想要取消该信用卡时,我会使用它,并且我会使用软删除(删除标志),因为也许您对统计过程或某事...公司有理由不删除数据... :)

    【讨论】:

    • 所以,因为几乎任何资源都可以在以后访问(至少由管理员),所以DELETE 几乎从来都不是一个合适的动词,对吧?
    • 这取决于您的业务逻辑:我会尝试使用 PATCH 方法将其状态更改为已阻止,并根据信用卡的状态在请求时检索信用卡信息。如果您使用删除,然后,您尝试获取资源......这对我来说有点“丑陋”......
    • 你不能只用简单的application/json 来使用 PATCH。该媒体类型没有修补语义。正如 rfc5789 解释的那样,您需要使用描述目标资源需要如何修补的媒体类型。这就是 'application/json-patch+json' 的用途。 tools.ietf.org/html/rfc6902 并且使用补丁来改变状态这样简单的事情是矫枉过正的恕我直言。
    • 我认为您在谈论 JavaScript Object Notation (JSON) Patch (tools.ietf.org/html/rfc6902),我的链接是关于 HTTP 的 PATCH 方法 (tools.ietf.org/html/rfc5789),问题中提到的 HTTP 方法. RFC 5789 不代表内容类型。正如我在 (iana.org/assignments/media-types/application/json-patch+json) 中看到的,application/json-patch+json 用于“使用此媒体类型的应用程序:操作 JSON 文档的应用程序”,但您无需修改​​ JSON 文档...
    【解决方案3】:

    DELETE HTTP 方法传达了客户端删除资源的意图。服务器不需要实际物理删除它。随意标记它。

    如果您不使用所有方法,REST 也不在乎。它只在乎你是否使用不正确。

    【讨论】:

    • 是的,显然资源比数据库中的简单行更复杂。但是,如果某人可以查看资源的历史记录,则允许他删除资源是否合适?
    • @synapse 你可以做DELETE /orders/234GET /historical/orders/234,现在你确实删除了第一个资源,你只是为了查看而创建了一个新资源。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-30
    • 1970-01-01
    • 2022-11-18
    • 2018-11-08
    • 2015-12-13
    • 2011-05-27
    相关资源
    最近更新 更多