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

Gleam调用HTTP API解析JSON响应失败,示例JSON却正常

问题排查与解决

以下是几种最可能导致解码失败的原因及对应的排查、修复方法:

1. 响应结构不匹配(数组 vs 单个对象)

你手动构造的JSON可能是单个Product对象,但fakestoreapi.com/products返回的是Product对象数组。如果你的解码器是针对单个对象编写的,直接解码数组会失败。

排查方法:

打印API返回的原始响应体:

import gleam/io
import http

pub fn main() {
  case http.get("https://fakestoreapi.com/products") {
    Ok(response) -> io.println(response.body)
    Err(e) -> io.debug(e)
  }
}

如果输出是[{...}, {...}, ...]格式,说明是数组,需要调整解码器。

修复方法:

将解码器从单个对象改为列表解码器:

import json

// 原单个Product解码器
pub fn product_decoder() -> JsonDecoder(Product) {
  json.decode7(Product,
    json.int("id"),
    json.string("title"),
    json.float("price"),
    json.string("description"),
    json.string("category"),
    json.string("image"),
    rating_decoder(),
  )
}

// 修改后解码列表
pub fn decode_products(json_str: String) -> Result(List(Product), JsonDecodeError) {
  json.decode(json_str, json.list(product_decoder()))
}

2. 字段名/大小写不匹配

Gleam的JSON解码器默认严格匹配字段名的大小写和拼写。如果API返回的是蛇形命名(比如product_id),而你的自定义类型用的是驼峰(productId),或者字段名拼写有误(比如把rate写成rating),就会解码失败。

排查方法:

对比手动构造的JSON和API返回的字段名,比如API返回的Rating字段是:

"rating": { "rate": 4.5, "count": 100 }

确保你的解码器里用的键名是"rate"和"count",而不是其他拼写。

修复方法:

在解码器中明确指定API返回的字段名,比如:

pub fn rating_decoder() -> JsonDecoder(Rating) {
  json.decode2(Rating,
    json.float("rate"), // 严格匹配API返回的键名
    json.int("count"),
  )
}

3. 字段类型/可选性不匹配

API返回的字段可能存在以下情况,导致解码失败:

  • 字段值为null,但你的解码器定义为必填(未用optional包装)
  • 字段类型与预期不符(比如price返回字符串"19.99"而非浮点数19.99)

排查方法:

检查API返回的字段类型,比如某条Product的price是否是数字,rating是否始终存在(不会为null)。

修复方法:

  • 对可能为null的字段使用json.optional:
// 如果rating字段可能为null
json.optional(rating_decoder(), "rating")
  • 对类型不符的字段做转换,比如字符串转浮点数:
json.string("price") |> json.map(fn(s) { float.parse(s) |> result.unwrap(0.0) })

4. 响应体读取不完整或编码错误

极少数情况下,HTTP响应体可能未被完整读取,或者字符编码不匹配(比如API返回UTF-8以外的编码)。

排查方法:

打印响应体的长度,对比手动构造的JSON长度,确认是否完整。

修复方法:

确保使用http.get后正确获取响应体,Gleam的http库默认会完整读取响应体,若仍有问题可尝试手动处理编码:

import gleam/string

// 确保响应体是UTF-8编码
let body = string.from_bytes(response.body_bytes, "utf-8") |> result.unwrap("")

内容的提问来源于stack exchange,提问作者jwesonga

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 22:55:17