You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ruby 3.1.3+Faraday 2.7.5:response.body为何始终是JSON字符串而非解析对象?

问题

在Ruby 3.1.3与Faraday 2.7.5环境下,已配置Faraday启用JSON响应解析(faraday.response :json),但调用接口后response.body始终是JSON格式的字符串,而非解析后的Ruby哈希对象,必须手动执行JSON.parse才能得到预期结果。

客户端代码

def connection
  @connection ||= Faraday.new(
    url: url,
    headers: headers
  ) do |faraday|
    faraday.response :json
    faraday.request :json
  end
end

def headers
  { content_type: 'application/json',
    accept: 'application/json' }
end

def send_request
  connection.send(method) do |req|
    req.body = body
  end
end

执行现象

调用接口后查看响应体:

[1] pry(#<App>)> response.body
=> "{\"data\":{\"date\":\"some_data\"}}"

必须手动解析才能得到Ruby哈希:

[2] pry(#<App>)> JSON.parse response.body
=> {"data"=>{"date"=>"some_data"}}

测试代码

let(:response_body) { { data: { date: 'some_data' } }.to_json }
 
...

stub_request(:post, url)
  .with(
     body: body.to_json,
     headers: custom_headers
   ).to_return(status: status, body: response_body, headers: {})
end

it 'POSTS to a url' do
  subject
  expect(a_request(:post, url)).to have_been_made
 end
end

疑问:是测试代码存在问题,还是客户端代码的配置无法实现自动返回解析后的JSON对象?


分析与解决

问题出在测试代码的响应头配置,客户端代码本身的配置是正确的。

  • Faraday的json响应中间件默认仅在响应的Content-Type头为application/json时,才会自动将JSON字符串解析为Ruby哈希。
  • 你的测试代码中,to_return方法的headers参数为空,没有设置Content-Type: application/json,导致Faraday无法识别这是JSON响应,因此不会触发自动解析逻辑。

修复测试代码

在to_return中添加正确的响应头即可解决:

stub_request(:post, url)
  .with(
     body: body.to_json,
     headers: custom_headers
   ).to_return(
     status: status,
     body: response_body,
     headers: { 'Content-Type' => 'application/json' } # 新增响应头配置
   )

可选优化:增强客户端兼容性

如果担心实际服务端返回的Content-Type不标准(比如返回text/json),可以修改客户端的json响应中间件配置,让它匹配更多类型的JSON响应:

faraday.response :json, content_type: /\bjson/ # 匹配任何包含"json"的Content-Type
# 或者强制解析所有响应(不推荐,但极端场景可用)
# faraday.response :json, content_type: '*/*'

内容的提问来源于stack exchange,提问作者I. Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 15:17:35