javascript - 如果端点既删除资源又创建资源,它仍然是惯用的 POST 吗?
问题描述
我一直在尽最大努力编写 RESTful API 端点,最近遇到了一个我不知道如何处理的场景。我创建了一个模型,该模型具有有效性时间限制和一个端点,该端点应该:
- 如果资源不存在,则为用户创建资源,或者
- 删除旧资源,如果它确实存在并且已过期,则创建一个新资源
我当前的实现是一个在资源创建期间处理此逻辑的端点,但是在 POST 请求期间同时进行删除和创建的一些事情感觉不对。发出多个请求来处理同一个任务也感觉不对,因为如果用户最终获得两个资源,或者如果创建请求失败、删除请求和请求请求过于冗长,这似乎会引入错误的可能性再次创作。解决此问题的惯用且稳健的方法是什么?
解决方案
首先回答标题问题,POST 行为的删除部分不是惯用的,因为 POST 通常不用于替换,但我不认为这是严格禁止的,所以根据您的情况(如下所述),POST 或 PUT都是可以接受的方法。
当您的案例应该使用 PUT 时:
如果您知道 ID,那么最好的办法是:
PUT /your/resource/path/<id>
原因: POST更严格地用于创建新资源。在我看来,PUT 更多地用于您想要“创建或替换”的情况,这与您的要求一样接近。
这是一个很好的来源,可以讨论并支持我所说的:
和一个很好的摘录:
PUT 方法请求将封闭的实体存储在提供的 Request-URI 下。如果 Request-URI 引用了一个已经存在的资源,封闭的实体应该被认为是在源服务器上的一个修改版本。如果 Request-URI 不指向现有资源,并且该 URI 能够被请求用户代理定义为新资源,则源服务器可以使用该 URI 创建资源。”
当您的案例应该使用 POST 时:
如果您的 ID 是在后端生成的和/或您不知道如何在创建时识别资源,那么出于所有相关目的,就您对 REST 的使用而言,您正在创建一个新资源,因此您应该使用 POST。您最终可能会遇到一些古怪的后端行为,有些人会争辩说这违反了 REST,但在这种情况下,除了从核心重新考虑您的解决方案之外,没有更好的选择。
最后注:
如果您在创建时不知道 ID,那么您甚至不能退回到 DELETE → (re)POST,因为要删除,您应该按 ID 定位。如果您在没有 ID 的情况下删除,那么您还有其他“这是惯用的”问题要回答。
推荐阅读
- typescript - 如何键入函数表达式及其内部对象 - TypeScript 3
- reporting-services - 如何检查架构更改对 SSRS 服务器上所有报告的影响?
- git - 无法在 Azure DevOps 上完成拉取请求
- python - 在 python 中验证 Github 私有仓库
- python - 硒中的 NoSuchFrameException(frame_reference)
- java - JsonDeserialize 可选字段设置为 Optinal.empty 的 Java 构建器类。JsonDeserialize 时设置默认值
- c - API 调用 libssh2_userauth_publickey_fromfile() 失败
- android - 如何在没有 BT Classic(BR) 的情况下在 Android 和 Windows 10 之间配对 BLE
- javascript - Ajax:将 ajax 调用重新加载到表后,自定义样式将消失
- node.js - 我们无法从 /proc/uptime 中找到正常运行时间,使用 os.uptime() 值,Pm2 3.5 错误