Magento 2 REST API 返回 400 Bad Request,请求体在 JSON 校验工具中完全合法,却仍提示输入异常。这里的“合法 JSON”只证明语法能解析,不代表结构符合 Magento 路由对应的 Service Contract。字段层级、参数名、数据类型和扩展属性只要有一处不匹配,都可能被输入处理器拒绝。

保留 Magento 返回的完整错误对象

响应中的 messageparameterstrace(仅开发环境)通常会指出无法处理的字段。先使用最小请求复现:

BASE_URL='站点地址'
TOKEN='访问令牌'
curl -i -X POST \
  -H \"Authorization: Bearer $TOKEN\" \
  -H 'Content-Type: application/json' \
  --data @payload.json \
  \"$BASE_URL/rest/V1/目标接口\"

不要把真实 Token 和客户数据贴到公共日志。检查实际发送的字节,而不是只看代码中构造 JSON 的对象;代理、SDK 或字符串拼接可能改变请求体。

最外层参数名必须匹配方法签名

如果接口方法是 save(ItemInterface $item),请求体通常需要以 item 为外层键;若方法参数不同,结构也随之变化。自定义接口在 webapi.xml 中绑定的 service method 必须与接口定义、实现和生成代码一致。

更新 Service Contract 后,应清理生成代码、重新编译依赖注入并验证接口 schema。只修改实现类而不修改 API 接口,Web API 输入映射仍可能沿用旧类型。

类型错误经常被 JSON 外观掩盖

数字字符串、布尔字符串、null、空对象和空数组在 PHP 转换中含义不同。接口期望数组却收到对象,或期望整数却收到带格式文本,会报类似“无法处理参数”。日期要符合接口接受的格式,金额不要带货币符号。

Extension Attributes 必须先在 extension_attributes.xml 声明,并通过对应数据接口暴露。随意把自定义字段塞进 extension_attributes 不会自动保存。字段名与生成的 getter/setter 映射也必须一致。

区分 400、401、403 和 404

400 主要指输入或业务校验;401 是认证失败;403 是资源权限;404 可能是路由或实体不存在。WAF、反向代理也可能返回自己的 400 HTML 页面,因此要检查 Content-Type 和响应来源,确认错误真的来自 Magento。

多商店上下文会改变校验结果

路径中的 store code 会影响网站、属性选项、货币、客户和库存上下文。同一个 SKU 在 default store 可处理,在另一个 store 报输入错误时,检查实体归属和作用域,而不是只比较 JSON。

修复后保存一组契约测试:最小合法请求应成功,缺少必填字段、错误类型和无权限令牌应返回预期错误。这样升级 Magento 或扩展后,能够在生产接口失败前发现 Service Contract 变化。