英文:
API Design: How to ensure commands are called in a specific sequence
问题
我们正在为我们制造的手持传感器设计一个API,以便我们的客户可以将其集成到他们的机器人上。
传感器上的功能要求用户按照一系列步骤来实现最终结果。当用户将我们的设备用作手持设备时,我们能够强制用户按照这个顺序进行操作,因为我们的图形用户界面会引导他们完成每个步骤。然而,对于我们的API来说,情况稍微复杂一些,因为集成商可以以任何顺序调用API。目前,我们依赖文档来确保API调用按顺序进行。
但是,我的问题是:是否可以通过API完成这个任务?
例如,我尝试了以下方法,但最终放弃了这种方法,因为我觉得它变得太主观,最终无法强制执行。
用户向我们的传感器API发出以下请求
{
"command": "do_step_one"
}
当传感器响应说它已经完成时,它会建议下一步的操作以及取消选项,如下所示:
{
"respondingToCommand": "do_step_one",
"date": "2023-04-03T19:23:23.000000",
"message": "Successfully completed step one",
"nextStep": [
{
"name": "Continue to step two",
"command": "do_step_two"
},
{
"name": "Cancel",
"command": "cancel_sequential_process"
},
],
"status": "done"
}
英文:
we're designing an API for our handheld sensor that we manufacture so that our customers can integrate it onto their robots.
The functionality on the sensor requires a user to go through a sequence of steps to achieve a final result. When a user is using our device as a handheld, we're able to force the user to follow this sequence because our GUI walks them through each step. However, with our API it's a little more difficult since the integrators can make calls in no particular order. Currently we're relying on documentation to make sure the API calls are made sequentially.
But, my question to you is: can this be done via the API?
For example, I tried the following but I ended up backing out of this approach because I felt it was becoming too opinionated and, in the end, not enforceable.
The user makes the following request to our sensor's API
{
"command": "do_step_one"
}
When the sensor responds that it's "done", it suggests a next step and the option to cancel, like so:
{
"respondingToCommand": "do_step_one",
"date": "2023-04-03T19:23:23.000000",
"message": "Successfully completed step one",
"nextStep": [
{
"name": "Continue to step two",
"command": "do_step_two"
},
{
"name": "Cancel",
"command": "cancel_sequential_process"
},
],
"status": "done"
}
答案1
得分: 1
对于这个简短的回答,我会忽略关于API设计的“严格爱护”思想,其中不遵循文档中的操作方式的用户将得到他们所得到的。考虑一个重要的客户,他找到了一种奇怪的方法来使某些事情起作用,但你的下一个内部修复却破坏了他们的工作流程 - “为什么我们应该修复我们的代码,你们才是破坏它的人!”
你可以通过要求仅从先前的响应中获得的资源来强制执行请求的特定顺序。作为一个通用示例,你的步骤可能是:
- 登录,返回身份验证令牌
- 使用身份验证令牌启动硬件会话,返回会话标识
- 使用会话标识列出可用传感器,返回传感器标识列表
- 使用会话标识和传感器标识打开传感器,返回会话特定的传感器句柄
- 使用传感器句柄轮询传感器状态
- 使用会话标识关闭会话
每个步骤建立在先前步骤的基础上。用户仍然有自由 - 例如,对于传感器标识可能在会话之间是持久的,所以也许他们可以直接跳到步骤4而不经过步骤3,并且只需重复使用他们从先前会话中存储的传感器标识。
根据特定的目标,API用户应该能够确定他们需要的先前步骤,而实现这一点的好方法是通过关联的资源 - 即使它们只是证明他们已经完成了先决任务的标识。
最好的API会引导你走上花园小径,而不是把你送到一个充满隐藏陷阱的黑暗森林中。
英文:
For this brief answer I'll ignore the "tough love" school of thought about API design, in which users who disregard the documented way of doing things get what they get. Consider a big customer who finds a weird way to make something work, but your next internal fix breaks their workflow – "why should we fix our code, you're the ones who broke it!"
You can enforce a certain order of requests by requiring resources that are only available from previous responses. As a generic example, your steps might be:
- Login, which returns an authentication token
- Start a hardware session using the auth token, which returns a session id
- List available sensors using the session id, which returns a list of sensor ids
- Power on sensor using the session id and a sensor id, which returns a session-specific sensor handle
- Poll sensor status using the sensor handle
- Close the session using the session id
Each step builds on previous steps. The user still has freedom – for instance, it might make sense for the sensor ids to be persistent between sessions, so maybe they can go straight to step 4 without step 3, and just re-use a sensor id that they have stored from a previous session.
Given a particular goal, the API user should be able to determine the previous steps that they require, and a good way of doing that is by having associated resources – even if they're just ids proving that they've done prerequisite tasks.
The best APIs lead you down a garden path, rather than send you into a dark wood with bear-traps hidden about the place.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论