新闻详情

新闻详情

首页 / 资讯中心 / 详情

大厂API为何弃用PUT/DELETE?POST成为主流的工程权衡

发布时间:2026/9/28 12:40:11来源:尧图网络
大厂API为何弃用PUT/DELETE?POST成为主流的工程权衡
如果你对接过不同公司的开放平台肯定见过这种接口文档一水的 POST。创建是 POST更新是 POST删除也是 POST。别笑有些平台连查询都要求你用 POST理由是“避免 URL 太长”。这个时候很多刚看完 REST 教程的新人就会犯嘀咕说好的 DELETE /users/{id} 呢 PUT 和 DELETE 难道不是 HTTP 的基本动词吗为什么很多大厂 API 不再使用 PUT 和 DELETE甚至连 GET 都不太愿意用这篇文章不打算批判任何风格而是想以一线开发者的视角把这件事背后的工程权衡拆开讲清楚。你会看到大厂不用 PUT/DELETE不是因为他们不懂 REST而是因为他们要考虑的调用方、部署环境、网关策略和运维成本和你在本地写一个 Demo 完全不一样。适合正在设计接口的后端开发、对接外部 API 的客户端同学以及被“规范之争”困扰的团队参考。1. 先从现象说起那些只有 GET/POST 的接口文档1.1 你看到的“不按套路出牌”的 API 长什么样我最早遇到这种 API是很多年前对接一个云厂商的开放平台。文档里所有需要鉴权和写操作的接口都长这样POST /v1/resource/delete Content-Type: application/json { resource_id: abc-123 }当时我的第一反应是这算什么删除不应该是DELETE /v1/resource/abc-123吗后来接触多了才发现这不是某一家公司的特例。支付渠道、消息推送、企业 SaaS、大模型平台……很多对外开放接口都在走同一条路。有些甚至把所有操作统一成唯一一个 POST 入口路径里带一个action参数服务端根据参数路由到不同处理逻辑。你更常见到的是“动作路径”风格比如POST /v1/orders/123/cancel POST /v1/users/456/disable POST /v1/files/789/archive路径仍然可以标识资源但操作动词从 HTTP Method 挪到了路径的最后一个词。这种方式既保留了资源意识又避开了 PUT/DELETE 的语义负担。1.2 是 API 设计倒退还是我们误解了 REST教科书告诉我们RESTful API 应该用 HTTP 方法表达操作GET 查询、POST 新建、PUT 整体替换、PATCH 部分更新、DELETE 删除。这套理论当然没错但它有几个隐含前提资源可以被精确定义、网络环境足够开放、调用方愿意区分各种状态码和幂等语义。但在真实的开放平台上这些前提常常不成立。REST 是一种架构风格不是协议规范它对“资源”“表示”“状态转移”都有一定哲学要求。而大厂对外 API 的第一目标往往不是我优雅地表达资源模型而是让成千上万的第三方开发者能稳定、简单、安全地接入。说得直白一点大部分对外 API 本质上是“远程过程调用”你调用的是“完成某个业务动作”而不是“对某个资源做 CRUD”。RPC 风格天然适合用一个统一的动词来承载所有动作这个动词就是 POST。所以你在很多大厂文档里看到的不是设计倒退而是他们把 API 当作 RPC 在使用只不过用了 HTTP 作为传输层而已。2. 为什么 POST 成了“万能钥匙”四个现实原因2.1 URL 长度与复杂查询GET 装不下的参数GET 请求的参数要放在 URL 的 Query String 里。看着好像挺灵活但生产环境里URL 从来不是无限长的。常见的 Web 服务器、负载均衡器、CDN 对请求行的限制一般在 4KB 到 8KB 左右有些代理甚至更短。一旦查询条件多了比如时间范围、多字段筛选、坐标、标签、排序规则组合起来URL 分分钟超限。更麻烦的是GET 请求在语义上不允许带 body。虽然很多服务端能读到 GET body但你不能依赖中间代理帮你传。浏览器fetch对 GET 带 body 的处理也五花八门客户端 SDK 更不会默认支持。所以遇到复杂查询与其争论“GET 能不能带 body”不如直接用 POST把参数放在请求体里干净、不截断、不被代理乱改。我见过一个团队做导出功能筛选条件有十几个字段放在 URL 里直接爆掉最后只能改用 POST把所有筛选项放在 JSON 对象里。从那以后他们的接口规范就多了一条凡是不确定 URL 长度上限的查询一律 POST。2.2 幂等性与重试PUT/DELETE 的严格要求太“苛刻”HTTP 语义里PUT 和 DELETE 被设计成幂等操作。幂等的意思是“执行一次和执行多次结果一样”。PUT 要求整体替换资源所以重复提交同一个 body最终资源状态一致DELETE 重复删除同一个资源也应该返回 200/204 或 404而不应该产生副作用。理论很完美现实很骨感。很多业务接口根本不是这种“纯资源操作”。比如“删除订单”这件事除了把订单状态改成已删除还要发通知、释放库存、给财务记账甚至还可能触发退款流程。第二次请求过来难道要让这些副作用再执行一遍吗如果只在第一次执行第二次请求又应该返回什么你很难把一个异步、有副作用的删除操作硬塞进 DELETE 的幂等模型里。POST 的好处是没有幂等承诺。你可以自己设计幂等键通过Idempotency-Key之类的请求头来保证重试安全。这样既保留了重试能力又不会因为 HTTP 方法本身的语义约束而自缚手脚。很多支付平台就是这么做的客户端生成一个唯一的 request ID服务端在窗口期内对相同 ID 只处理一次。2.3 网关、防火墙与浏览器环境不是所有网络都认识 PUT本质上HTTP 协议支持 PUT、DELETE、PATCH但现实网络里存在大量中间设备比如企业防火墙、代理服务器、老旧负载均衡、嵌入式网关。我可以负责任地说很多传统企业客户的内网策略只放行 GET 和 POST其他方法被安全策略直接拦截连请求都到不了你的后端。这听起来像段子但在一线对接客户时太常见了。你写了一个完全符合 REST 规范的 DELETE 接口客户那边怎么调都超时或者 405最后查下来是他们中间那道网关把非 GET/POST 方法全丢了。遇到这种情况服务端代码根本没机会执行。除了企业环境浏览器也有自己的问题。HTML 表单历史上只支持 GET 和 POST这意味着很多老系统、低代码平台、嵌入式设备在发起非 POST 请求时各有各的“幺蛾子”。为了让最大范围的调用方都能接入大厂干脆只保留最通用、最容易穿透网络的 GET 和 POST。这不是技术能力不行这是对生态妥协的智慧。2.4 安全与审计方法越少规则越简单站在安全团队的角度看一个对外接口如果方法种类太多WAF 规则、审计日志、日志解析都要处理更多情况。比如要分析“哪些操作修改了数据”你可能需要同时关注 PUT、POST、PATCH、DELETE还得区分 DELETE 是软删还是硬删。如果写操作统一用 POST那审计逻辑就收敛了很多基本只要关注 POST 请求的路径和请求体。我也不想夸大这一点毕竟单靠方法判断危险度根本不靠谱。但“减少方法种类可以让安全策略更集中”确实是一些平台设计的考虑因素。特别是当你的 API 要通过海外 CDN、第三方网关时给对方一份“只开放 GET 和 POST”的清单比反复向对方解释 PUT 与 PATCH 的区别要省事得多。3. PUT 与 DELETE 的理想、现实与尴尬3.1 PUT 的“整体替换”语义和现代接口需求不太匹配RFC 7231 里PUT 表示“用请求里的表示完整替换目标资源”。也就是说客户端发送什么服务器就保存什么。这在早期静态文件管理、KV 存储场景下很自然但放到现代业务系统里就很别扭。比如一个用户对象有姓名、手机号、头像、地址、偏好设置等多个字段。客户端只是想更新头像按 PUT 的严格语义它应该把整个用户对象提交上来包括所有字段。可实际调用方根本不知道其他字段当前是什么强行 PUT 就会把没传的字段清空。于是很多团队私下把 PUT 实现成“部分更新”但一旦请求重试第一次把字段 A 更新了第二次可能把字段 B 也更新了行为变得不可预期还违背了 PUT 应该幂等的原则。正确的部分更新方法是 PATCH但 PATCH 的格式一直没有像 JSON 统一有人用application/merge-patchjson有人用application/json-patchjson客户端对接成本一下子变高。与其解释半天天不如约定一切写操作都走 POST服务端自己决定是更新还是合并。这样接口实现自由度高客户端也不容易踩坑。3.2 DELETE 的“瞬时移除”假设遇到软删除就失灵DELETE 的语义是“资源被移除之后再访问应该 404”。但现代系统几乎不可能真删除数据。用户注销账号你要保留交易记录订单作废你要留审计日志文件删除你还要在回收站里躺 30 天。于是你被迫做软删除标记一个deleted_at字段然后让查询过滤掉这些记录。表面上看起来是删了但实际数据还在。如果客户端对同一个资源调用多次 DELETE第一次返回 204第二次返回 404严格说这已经不符合 DELETE 的幂等预期了因为资源在第一个请求后就不存在了但第二个请求返回不同状态码。再加上删除操作常常伴随异步任务比如释放资源、回调通知、清理关联数据你很难在 DELETE 的同步响应里告诉客户端“删除正在处理中”。如果你返回 202 Accepted下一次调用可能还会拿到资源被删除之前的中间状态。这一类问题用 POST 表达“发起一个删除动作”会自然很多服务端返回 202 任务 ID客户端再查询任务状态整个生命周期清晰可控。3.3 很多接口本质是“动作”不是“资源”你平时写 API真的只有 CRUD 吗不是的。发送短信、转账、创建会话、调用模型、启动爬虫、导出报表……这些操作很难被强行拆成“创建/读取/更新/删除”四件套。它们更像是一个函数、一个动作、一次任务投递。如果用 REST 资源思维建模你可能要发明一堆“资源名称”来填空比如POST /smsTasks、PUT /transferRecords折腾半天也没让谁觉得更好用。反而用 RPC 风格直接一点POST /v1/transfers Content-Type: application/json { from: account_123, to: account_456, amount: 100 }这不叫懒惰这叫接口跟随业务。大模型平台的 API 也是这种思路对话接口几乎就是一个POST /v1/chat/completions你不可能用 GET 去“获取”一个对话也不太会用 DELETE 去“删除”一段上下文因为对话是一个持续性的活动过程不是一个躺在数据库里供增删改查的静态对象。4. 大厂 API 规范背后一致性、工具链与生态4.1 统一动词能降低 SDK 生成和客户端接入的复杂度如果你维护过 OpenAPI 规范会发现一个现象客户端 SDK 根据 HTTP 方法生成代码时RESTful 风格会生成很多零散方法比如getUserById、updateUserById、deleteUserById每个方法对应一个资源操作。如果采用动作风格方法名可以直接对齐业务语义例如cancelOrder、disableUser、archiveFile。对调用方来说这种 SDK 更好上手——不用记资源对应的动词只需要找“这个操作应该叫什么”。同时网关层要做限流、鉴权、路由、灰度如果所有写操作都是 POST规则就可以统一按路径前缀匹配不需要为不同方法准备不同的策略。表面上看是“失去语义”实际上换来了极强的可预测性新上线的接口团队成员看一眼路径就知道它属于哪类动作也大致能猜到请求体结构。4.2 “自定义方法”规范Google API 设计指南也在用 POST很多人不知道Google 的 API Design Guide 里明确推荐自定义方法custom methods用 POST 实现。比如你有一个资源集合除了标准 List/Get/Create/Update/Delete还需要“rename”“cancel”“undelete”这类动作时规范建议写成POST https://example.com/v1/users/user1:undelete路径用冒号引出动作名称。这就是大厂面对 PUT/DELETE 语义不足给出的官方解不是硬把动作塞进资源 CRUD而是保留资源标识用 POST 触发自定义方法。这套设计被很多云厂商和内部基础设施采纳我们今天看到很多接口不用 DELETE 或 PUT其实是遵循了一套比“教科书 REST”更加工程化的风格。当然Google 也明确保留标准方法的 GET/PUT/DELETE。真正的大厂不是不会用 PUT而是懂得该用的时候用不该用的时候不硬用。对自定义业务动作统一用 POST这才是他们“不用 PUT/DELETE”的真实语境。4.3 兼容旧客户端与中间件是现实世界的头等大事我见过一些创业公司早期为了打扫“政治正确”非常严格地使用 PUT/DELETE结果做海外客户接入时频繁出问题。客户侧使用的往往是旧版 HTTP 库、企业内部代理、定制 WAF。这些东西兼容 GET/POST 几十年了但对 PATCH 和 DELETE 的处理经常让人头大。站在甲方视角一个新平台如果对网络设备有额外要求企业内部要提交变更审批业务方很可能直接放弃接入转投一个“只要 POST 就能调”的竞品。这不是技术选型是商务问题。大厂 API 不做 PUT/DELETE很大一部分原因就是为了减少客户接入的阻碍降低成功对接的门槛。4.4 那大厂还有没有 DELETE有的但分工变了别误会不是说大厂彻底消灭了 PUT 和 DELETE。对纯资源的标准生命周期操作比如删除一个未绑定业务的图片、清空一个测试对象很多平台依然提供DELETE /v1/resource/{id}。但这种接口通常不是核心业务入口而是辅助能力。核心业务里凡是牵扯审批、回调、任务、账单、状态流转的操作基本都会设计成 POST。比如“删除一个客户”看似简单实际上可能引发计费停止、数据导出、关联权限回收。这种操作宁可让客户端先发一个POST /v1/customers/{id}/deactivate也不愿意用 DELETE 假装只是删一条记录。所以更准确地说大厂不是“不再使用 PUT 和 DELETE”而是把这两个方法收敛到了真正适合它们的场景。5. 什么时候你仍然应该用 PUT/DELETE以及怎么配套5.1 内部系统与标准 CRUDRESTful 依然舒适如果你的服务部署在完全可控的内网调用方都是自家后端服务网关也明确支持常见方法那么继续用 PUT 和 DELETE 没有任何问题。标准 CRUD 接口用 REST 风格可以给团队带来清晰的资源边界尤其是面对数据库表模型时一个资源对应一个表GET/POST/PUT/DELETE 的操作意图一目了然。内部系统还有一个优势你可以完全控制调用方 SDK不需要为第三方客户的奇怪网络环境妥协。这种情况下用 PUT 表示整体更新、PATCH 表示部分更新、DELETE 表示删除语义清晰也没有沟通负担。我不会因为外面流行“全 POST”就劝你改关键是看约束条件。5.2 只用 GET/POST 的接口需要九个配套设计如果你决定走大厂那种“对外接口以 POST 为主”的路线有一些配套设计不能省否则接口会变得一团糟路径里必须写清楚动作POST /v1/orders/{id}/cancel而不是POST /v1/cancelOrder资源模型能保留一半是好事。给写操作加幂等键用Idempotency-Key或X-Request-ID服务端记住已处理过的 key重复请求直接返回第一次的结果。明确的版本策略路径带/v1/、/v2/避免动作语义演进时破坏老调用方。统一错误结构比如code、message、trace_id让客户端不用靠 HTTP 状态码猜原因。复杂查询也要定义查询对象字段名固定别让客户端裸拼 JSON否则容易埋雷。区分响应时机同步操作返回 200/201异步操作返回 202 任务 ID别把所有响应都塞进 200。设置超时与重试策略POST 默认可能产生重复操作必须配合幂等键才能安全重试。在文档里明确“写操作不缓存”别让客户以为查询接口和写操作走同一套缓存策略。保留 GET 给无副作用操作能安全用 GET 查询的就用 GET别为了统一把检索也全改成 POST这对调试和 CDN 缓存都不友好。5.3 架构评审时可以问哪些问题被“该不该用 DELETE”这种问题卡住的团队其实需要回到更本质的问题。下次评审 API 设计时先问五件事调用方是谁浏览器、后端服务、低代码平台还是设备端请求要经过哪些网络节点有没有企业防火墙、CDN、自定义网关操作本身是资源 CRUD还是包含审批、回调、状态机的动作客户端是否会重试重试失败后需要保证幂等吗团队有没有能力维护一套严格的 REST 语义并约束所有调用方遵守这些问题比“用哪个 HTTP 动词”重要得多。只要有任何一个问题的答案是“第三方环境很复杂”你就有充分理由把动作操作统一收敛到 POST再配合幂等键和任务状态机制把逻辑做扎实。6. 典型问题、踩坑记录与快捷排查6.1 CORS 预检请求为什么 DELETE 会先冒出一个 OPTIONS如果你在浏览器环境调用带自定义 Header 的 DELETE 请求浏览器会先发一个 OPTIONS 预检确认服务器允许的Access-Control-Allow-Methods里是否包含 DELETE。如果后端网关没有响应 OPTIONS或者返回的允许方法列表里没有 DELETE实际请求根本不会发出。很多团队被这个问题折磨过之后就规定“统一用 POST”。不过注意POST application/json同样会触发预检并不是放弃 DELETE 就可以逃避 CORS。CORS 问题的根源在于“非简单请求”和“自定义 Header”而不是方法本身。该处理预检的还是要处理在网关层统一放行 OPTIONS 和配置允许方法即可。6.2 现场环境只放行 GET/POST405 和 501 的锅症状很典型本地用curl -X DELETE一切正常到了客户环境就返回 405 Method Not Allowed或者直接连接超时。你的服务端日志里根本没有这条请求记录说明请求在中间层就被拦截了。排查方法很简单先用curl -i -X DELETE https://your-api.example.com/v1/orders/123看返回内容再绕过域名直接访问后端服务 IP如果能比如用curl -H Host: your-api.example.com ...确认是应用服务的问题还是中间代理的问题。如果直连后端正常、过网关 405基本可以确定是网关白名单没放开 DELETE。这种时候业务上能回退就回退成POST /v1/orders/123/delete不能回退就要找运维开网络策略变更。6.3 “全 POST” 接口的隐患缓存、重复提交、爬虫误伤只用 POST 也有一堆新问题不是没有代价。最明显的是缓存失效HTTP 缓存主要面向 GET 请求POST 默认不会被 CDN 和浏览器缓存所以相同筛选条件的查询每次都要打到后端性能压力更大。其次是重复提交网络超时后客户端重试如果没有幂等键用户可能收到两次扣款、两条订单。还有一个容易被忽视的问题是爬虫和搜索引擎。GET 接口可以方便地被工具识别和收录全 POST 的接口对 SEO、文档站就特别不友好。有些团队最后会采用折中方案对只读操作保留 GET只有业务动作才用 POST保证性能和调试体验。6.4 一个快速的接口问题排查顺序我给自己总结了一套排查办法遇到“为什么 DELETE 调不通”这类问题按顺序走先用curl -v -X DELETE看握手、请求头、响应头判断请求有没有到达你的服务。检查服务端访问日志如果没有任何记录基本可以判断是网络中间层拦截。在服务端写一个临时 debug 接口把收到的 method、path、headers 全部打印出来一目了然。确认网关层的allow_methods配置是否包含 DELETE、PUT、PATCH。如果是浏览器调用先看 CORS 预检日志确认 OPTIONS 请求是否被正确响应。如果生产环境时间紧急最稳的 fallback 方案就是改为 POST 动作接口先恢复业务可用性再回头完善语义。这个顺序在绝大多数场景下都能帮你快速定位问题而不是在文山会海里争论“PUT 到底应不应该用”。我在实际对接中用过很多次尤其遇到第三方网络环境时几乎都是这套方法救场。说起来我自己刚开始写接口的时候也是个“方法原教旨主义者”总觉得不用 PUT/DELETE 的 API 都是业余设计。直到有一次做企业客户对接对方内部网络设备只放行 GET 和 POST生产环境里删除订单的接口怎么调都失败。最后我们连夜把所有状态变更接口改成POST /v1/orders/{id}/cancel这种动作风格第二天客户一次就调通了。从那时起我才明白HTTP 动词只是工具不是为了上课。选 GET 还是 POST说到底是在团队、客户、网络基础设施之间找一个最大公约数。下次你看到全是 POST 的大厂 API不用急着吐槽先想想他们的调用方是谁、部署环境在哪里你大概率就能理解这个决定了。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

SQLi-Labs靶场搭建实战:PHP版本、数据库初始化与启动排错 2026/9/29 2:08:53

SQLi-Labs靶场搭建实战:PHP版本、数据库初始化与启动排错

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
计算机组成原理课设报告怎么写?CPU核心考点与调试实战全解析 2026/9/29 2:08:53

计算机组成原理课设报告怎么写?CPU核心考点与调试实战全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
大豆种子质量检测数据集:6503张真实图像+YOLO/VOC双格式 2026/9/29 2:08:53

大豆种子质量检测数据集:6503张真实图像+YOLO/VOC双格式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
计算机视觉常用数据集全解析:从MNIST到COCO的选型与实践指南 2026/9/29 2:08:53

计算机视觉常用数据集全解析:从MNIST到COCO的选型与实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
PTA寻找大富翁题解:最小堆与Top K问题实战 2026/9/29 2:08:53

PTA寻找大富翁题解:最小堆与Top K问题实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
YOLOv11火灾预警系统实战:从模型训练到RTSP视频流部署全流程 2026/9/29 2:08:46

YOLOv11火灾预警系统实战:从模型训练到RTSP视频流部署全流程

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉