使用 json 类型提供程序急切加载所有分页数据

Eagerly loading all paginated data with json type provider

考虑一个 API 的回复总是这种结构:

{
    "pagination": {
        "limit": int,
        "offset": int,
        "count": int,
        "total": int
    },
    "data": [
        {...some obj...}
    ]
}

因此有效载荷仅在数据对象的结构上有所不同。

理想情况下,我想告诉 F# 从样本构建的所有类型都有一些共同的部分 - 分页信息,因此我可以使用一种通用方法来读取所有页面。

是否可能,或者我是否必须使用两种类型的提供程序分别提取 pagination 对象和 data 数组?我看到每个响应主体有一个提供程序的好处,因为它支持从流中读取数据。

我会定义两种不同的提供类型,一种用于解析分页数据,另一种用于解析实际数据,即如下所示:

type Pagination = JsonProvider<"""{ 
  "pagination": { "limit": 1, "offset": 2, 
    "count": 3, "total": 4 } 
  }""">
type OneDataType = JsonProvider<"""{
    "data": [ {"a": 1} ]
  }""">

如果你想避免两次解析同一个 JSON 文件(例如,通过在同一个字符串上调用 Pagination.ParseOneDataType.Parse),你实际上可以只解析一次数据,然后然后将解析的 JsonValue 传递给另一种类型:

let odt = OneDataType.Load("/some/file")
let pg = Pagination.Root(odt.JsonValue)
pg.Pagination.Count

如果您想使用单一提供的类型执行此操作,则可以为多种不同类型的数据定义多个不同的字段 - 但您必须以不同的方式命名它们。然后您需要进行一些操作才能正确读取数据。我不会这样做,因为我觉得它很混乱,但它看起来像这样:

type AnyData = JsonProvider<"""{ 
  "pagination": { "limit": 1, "offset": 2,
      "count": 3, "total": 4 },
  "data": [],
  "one_data_type": [ {"a":1} ],
  "another_data_type": [ {"b":"xx" }]
}""">

let a = AnyData.Load("/some/file")
// Access pagination data
a.Pagination
// Access data as if it was OneDataType
let oneData = [| for d in a.Data -> 
  AnyData.OneDataType(d.JsonValue) |]