sts*_*ler 1 rest asp.net-web-api
我想知道如何在 RESTful API 中建立事务安全性,其中一切都围绕单个实体构建。
数据库模型:
用户在浏览器中执行的步骤:
提出的要求:
PATCH/PUT发票数据/订单号。POST 物品。DELETE 物品。PATCH/PUT项。如果在上述任何请求之后发生错误,进一步的调用可能会破坏数据完整性。此外,必须撤销先前的请求。例如,如果删除项目失败,则必须重新执行步骤 1 和 2,以使整个发票与以前一样。
另一个可能出现的问题是浏览器崩溃、互联网连接中断、服务器故障或其他任何问题。
如何确保在某种事务中执行某些操作以维护数据完整性和安全性?
因此,使用 REST 时要记住的是“状态转移”位。您不是告诉服务器更新资源所需的步骤,而是告诉服务器更新后资源应该处于的状态,因为您已经在客户端更新了它,现在只是将这个新状态转移到服务器。
因此,假设您在服务器上有一个 Invoice 项目,它在服务器上看起来像这个 JSON
{
invoice_id: 123,
invoice_description: "Some invoice",
invoice_items: [
{item_id: 10, item_desc: "Large item", order_amount: 34},
{item_id: 11, item_desc: "Small item", order_amount: 400}
]
}
Run Code Online (Sandbox Code Playgroud)
并且用户希望将该发票作为单个原子交易进行编辑。首先,他们从服务器获取发票。这基本上是说“给我发票的当前状态”
GET /invoices/123
Run Code Online (Sandbox Code Playgroud)
然后,用户可以随意编辑该发票。他们决定大项目的数量应该是 40,而不是 34。他们决定完全删除小项目。最后,他们决定在发票中添加另一项“超小”项目。用户编辑发票后,客户有以下发票
{
invoice_id: 123,
invoice_description: "Some invoice",
invoice_items: [
{item_id: 10, item_desc: "Large item", order_amount: 40},
{item_id: 30, item_desc: "Extra small item", order_amount: 5}
]
}
Run Code Online (Sandbox Code Playgroud)
因此,客户端的发票与服务器的状态不同。用户现在想要将其发送回服务器以进行存储,因此它将发票的新状态发送到服务器。
PUT /invoices/123
Run Code Online (Sandbox Code Playgroud)
本质上说“这是该资源的新状态”。
现在,根据您希望验证的花哨程度,服务器可以简单地接受发票原样的新状态,或者它可以对每次更改进行大量验证。你想做多少取决于你。
当用户在其客户端上编辑发票副本时,您至少要检查是否没有其他客户端将更新的发票放入服务器。您可以通过检查 HTTP 请求的各种标头(例如 etag 标头http://en.wikipedia.org/wiki/HTTP_ETag)来做到这一点
如果由于任何原因服务器决定此更新无效,它只会使整个 PUT 请求失败。这就是为您提供 HTTP 事务的原因。一个要求要么工作要么失败。如果失败,服务器有责任确保资源没有受到失败请求的影响。从服务器上植入的角度来看,您可能会对新 JSON 进行一些验证,然后尝试将新数据保存到数据库事务中的数据库中。如果出现任何故障,则数据库将保持原始状态,并告知用户 PUT 不起作用。
如果请求失败,应向用户返回一个 HTTP 状态代码和响应,以解释 PUT 要求失败的原因。这可能是因为其他人在用户考虑其更改时编辑了发票。这可能是因为用户试图将发票置于无效状态(假设用户试图将发票放入没有项目的发票,这破坏了公司的业务逻辑)。
您当然可以开发一个 URI 方案,允许编辑发票中的单个项目,例如
GET /invoices/123/items/10
Run Code Online (Sandbox Code Playgroud)
会从发票 ID 123 中为您提供项目 ID 10。但是如果您这样做,您必须允许彼此独立地编辑这些资源。如果我通过发送删除命令删除项目 10
DELETE /invoice/123/items/10
Run Code Online (Sandbox Code Playgroud)
该操作必须是一个独立的事务。如果其他请求依赖于此,您必须按照上面的详细说明进行操作,方法是在单个请求中更新发票本身。您永远不能通过单个 HTTP 请求将资源置于无效状态,或者换句话说,它永远不应该需要多个 HTTP 请求才能使资源进入有效状态(因此永远不需要一串 HTTP 请求工作才能有效)
希望有帮助
| 归档时间: |
|
| 查看次数: |
908 次 |
| 最近记录: |