将复杂对象传递给REST服务的删除方法

将复杂对象传递给REST服务的删除方法,rest,complextype,http-delete,http-put,Rest,Complextype,Http Delete,Http Put,我有REST服务来管理资源EASYPAY。。此时,此服务公开了3种不同的方法: 获取EasyPay请求(Get) 插入Easypay请求(POST) 更新Easypay请求(PUT) 当我插入或更新请求时,我还必须在数据库的跟踪表中插入一行 现在,我必须删除Easypay请求,还必须在跟踪表中添加一行。 我想使用DELETEHTTP动词,但我发现使用DELETE时,我不能传递复杂的对象,只能传递要删除的请求的ID。 我不能使用PUTHTTP动词,因为我已经使用过它,而且在任何情况下,它在概念上都

我有REST服务来管理资源
EASYPAY
。。此时,此服务公开了3种不同的方法:

  • 获取EasyPay请求(
    Get
  • 插入Easypay请求(
    POST
  • 更新Easypay请求(
    PUT
  • 当我插入或更新请求时,我还必须在数据库的
    跟踪
    表中插入一行

    现在,我必须删除Easypay请求,还必须在跟踪表中添加一行。 我想使用
    DELETE
    HTTP动词,但我发现使用DELETE时,我不能传递复杂的对象,只能传递要删除的请求的ID。 我不能使用
    PUT
    HTTP动词,因为我已经使用过它,而且在任何情况下,它在概念上都是不正确的。。。 我不想做更多的从客户端到服务器的调用(一个用于删除请求,另一个用于在跟踪表中添加行)。。 所以我不知道如何解决这个问题

    编辑

    我试图更好地解释。。。我有一个部署在两个不同服务器上的网站。一个用于前端,一个用于后端。后端仅为前端公开一些REST服务,它无法访问internet(仅访问intranet)。 访问该网站的客户可以通过一个名为XPAY的系统进行支付,其工作原理与paypal非常相似(XPAY只是另一个虚拟POS)。 因此,当客户尝试付款时,我会在数据库中保存一些信息,并跟踪付款尝试,然后将其重定向到XPAY。在那里,他可以付款。最后,请返回网站(前端),告知我们付款结果。 结果是在支付的URL,所以我必须采取的URL中的所有信息,并将其发送到后端。 根据结果,我必须更新(如果结果为ok)或删除(如果结果为ko)之前保存的信息,并在跟踪表上写一行

    你有什么建议


    谢谢

    实际上有几种方法可以解决您的问题。首先,REST只是一种架构风格,而不是协议。因此,REST并不规定URI的组成方式或传递的参数。它只需要一个唯一的资源标识符,并且可能应该是自描述性的,这意味着客户机可以根据返回的内容(HATEOAS,甚至包括到自身的链接和适当的内容类型规范)采取进一步的操作

    删除 由于您希望在其他一些表中保留已删除资源的跟踪,您可以将URI本身中的数据作为查询参数传递(甚至可以对JSON进行编码以作为查询参数传递),也可以使用自定义HTTP头将(元)信息传递到后端

    将复杂对象(不管是XML还是JSON)作为查询参数发送可能会导致某些问题,尽管某些HTTP框架限制了查询。因此,如果调用的URI超过此限制,后端可能难以满足请求

    尽管超文本传输协议没有定义头的最大数量(或大小)

    邮递 当然,您还可以向后端发送一个新的临时资源,该资源可用于删除挂起的付款请求并向跟踪表添加一个新条目

    根据报告:

    POST方法执行的操作可能不会产生可由URI标识的资源。在这种情况下,200(确定)或204(无内容)是适当的响应状态,这取决于响应是否包括描述结果的实体

    这使得
    POST
    请求对于短期临时资源是可行的,这会在服务器端触发一些处理。如果您想设计一些类似队列或侦听器的系统,在其中将要执行的操作放入系统中,这非常有用。由于
    POST
    请求可能包含正文,因此您可以在
    POST
    请求正文中发送POS响应。然后可以使用此操作请求删除挂起的POS请求,并将新条目添加到跟踪表中

    补丁是客户端指示服务器将一个或多个资源从状态1转换为状态2的一种方式。因此,当服务器尝试执行资源时,客户机负责分解服务器必须采取的必要操作,以将资源转换为所需状态。客户机总是在已知状态下工作(它在以前某个时间收集到该状态)。这允许客户端将当前状态修改为所需状态,从而了解转换所需的步骤。就其原子要求而言,要么所有指令都成功,要么没有成功

    适用于您的场景的示例可能如下所示:

    PATCH /path/to/resource HTTP/1.1
    Host: backend.server.org
    Content-lengt: 137
    Content-Type: application/json-patch+json
    If-Match: "abc123"
    
    [
        { "op": "remove", "path": "/easyPayRequest/12345" }
        { "op": "add", "path": "/trace/12345", "value": [ "answer": "POSAnswerHere" ] }
    ]
    
    其中,
    12345
    是实际easypay请求的ID,
    POSAnswerHere
    应替换为POS服务的实际响应或后端希望作为跟踪写入的内容

    示例中的头文件只是保证补丁请求在最新的已知状态下执行。如果同时另一个进程更改了状态(这也会生成一个新的If匹配值),请求将失败,前提条件为
    412失败

    讨论 虽然
    DELETE
    最初可能是首选,但在我看来,这并不是您的情况下的最佳解决方案,因为此请求实际上不是幂等的。实际的POS实体删除是幂等的,但跟踪的添加不是等幂的,因为同一请求的多个发送将为每个请求添加一个条目(->副作用)。然而,这在某种程度上与
    DELETE
    操作的幂等性要求相矛盾

    另一方面,
    POST
    是一种通用操作,不能保证幂等性(因为
    PATCH
    也不能保证)。而主要用于创建网元