REST API 的试运行策略 [英] Dry run strategy for REST API

查看:50
本文介绍了REST API 的试运行策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为 REST API 的试运行"操作寻找一些最佳实践.

I'm looking for some best practices for "dry run" operations for REST APIs.

假设我有一个端点可以将资金从账户 A 转移到账户 B.我可以像这样发起转账:

Say I have an endpoint that transfers money from account A to account B. I can initiate a transfer like so:

POST /transactions
{
  "amount": 1000,     // how much to transfer
  "source": "A",      // account to transfer from
  "destination": "B"  // account to transfer to
}

此操作创建一个交易",因此响应将是一个包含有效负载的交易对象:

This action creates a "transaction", so the response would be a transaction object with payload containing:

{
  "id": "txn-123",
  "amount": 1000,
  "source": "A",
  "destination": "B",
  "fees": 10,          // any fees that were charged
  "balance": 2500      // balance in source account AFTER transfer
}

出于以下几个原因,我希望能够进行试运行:

I'd like to be able to perform a dry run for a couple reasons:

  1. 判断转账是否成功(例如,如果账户A余额不足,可能会失败)
  2. 事先确定适用的费用

那么,试运行"概念的最佳实践是什么?我能想到几个选项:

So, what is the best practice for a "dry run" concept? I can think of a few options:

  1. 将标志传递到现有传输端点以指示试运行选项.该标志可以是查询字符串、有效载荷的一部分、标头等.确切的实现有待讨论,但从概念上讲,我喜欢这个,因为它提供了一个干净的界面,让您了解从单个执行传输所需的所有知识端点.
  2. 专用端点,专门用于执行转移试运行.这感觉"更安全,因为您不会无意中执行破坏性操作,因为实时和试运行端点是完全分开的.另一方面,如果您可以访问生产系统,您真的应该知道自己在做什么,所以我不是一个超级粉丝.
  3. 没有空运行的概念.只需使用一组完全不同的端点来计算费用、获取余额或任何其他可帮助您推断转账结果的操作.我不喜欢这样,因为您强制客户端复制传输端点中已包含的所有逻辑.
  1. Pass a flag to the existing transfer endpoint to indicate a dry-run option. The flag could be a querystring, part of the payload, a header, etc. The exact implementation is up for debate, but conceptually I like this because it gives a clean interface to know all you have to know about performing a transfer from a single endpoint.
  2. Dedicated endpoint specifically for performing a transfer dry run. This "feels" safer because you don't inadvertently perform a destructive action since the live and dry-run endpoints are completely separate. On the other hand, you really should know what you're doing if you have access to a production system, so I'm not a huge fan.
  3. No dry-run concept. Just have a completely different set of endpoints to calculate fees, or get balance, or any other operation that helps you infer the outcome of a transfer. I don't like this because you're forcing the client to replicate all the logic that is already contained in the transfer endpoint.

以上是我目前对此事的看法,但我很乐意听到其他人的想法.

These are my opinions on the matter so far, but I'd enjoy hearing other peoples' thoughts.

推荐答案

选项 3 显然是错误的.你会无缘无故地强迫客户做额外的工作.

Option 3 is clearly wrong. You'd be forcing the client to do extra work for no good reason.

在选项 1 和选项 2 之间进行选择取决于您的 API 的喜好和细节.目前尚不清楚将 /dry-run-transaction 视为一种独立于事务的事物是否合理.

Choosing between options 1 and 2 is a matter of taste and the specifics of your API. It's not clear how reasonable it is to consider a /dry-run-transaction to be a separate kind of thing than a transaction.

如果您选择选项 2,请考虑将 /dry-run-transaction 设为短期资源,或者根本不保留它.这样客户就可以通过 POST 查看费用并节省存储空间.

If you take option 2, consider making the /dry-run-transaction a short-lived resource, or don't persist it at all. That way clients can POST to see fees and you save on storage space.

如果您使用选项 1,我认为技术上最正确的选项是在有效负载中包含一个属性,例如 execute: false.这会将所有信息返回给客户端,并让他们使用 execute: true 对事务执行 PUT 以完全按原样提交它.这种方法的一个缺点是你将有一堆未执行的交易(永远?),因为人们会在看到结果后决定不执行它们.

If you use option 1, I think the most technically correct option would be to include a property in the payload, such as execute: false. This returns all the information to the client, and lets them do a PUT on the transaction with execute: true to submit it exactly as it is. A disadvantage to this approach is you're going to have a bunch of non-executed transactions sitting around (forever?) because people are going to decide not to execute them after seeing the results.

我认为根本不涉及安全问题.如果您真的很担心,只需将 execute: false 设为选项 1 的默认值即可.

I don't think safety comes into the discussion at all. If you're really worried about it, just make execute: false the default for option 1.

另一种方法可能是使用端点 /transactions/transaction-results.如果您发布到 /transaction,您将执行交易并获得永久交易结果的 ID/结果.如果你 POST 到/transaction-results,你会得到一个没有 id 的响应和交易的临时结果集.请注意,我已经考虑了整整 20 秒,因此可能存在我没有看到的明显问题.:-)

Another approach might be to have endpoints /transactions and /transaction-results. If you post to /transaction, you execute the transaction and get an id/result for a permanent transaction-result. If you POST to /transaction-results, you get a response with no id and a transient set of results for the transaction. Note I've thought about this for all of 20 seconds, so there might be a glaring problem with it I haven't seen. :-)

这篇关于REST API 的试运行策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆