Search code examples
jsonf#json.net

F# Define Types for Json with nested list


Follow up question to this question, to parse json to deedle dataframe.

My json includes some list with nested lists:

apiResponse = {"data":
                    {"Shipments":
                               {"ErrorMessage":null,
                                 "Success":true,
                                 "ValidationResult":null,
                                 "TotalCount":494,
                                 "Data":[
                                         {
                                         "CompletedDate":"2021-04-12T10:13:13.436Z",
                                          "ItemId":"dd4520bb-aa0a-...",
                                          "Organization":{
                                                      "OrganizationId":"cac43a32-1f08-...",
                                                      "OrganizationName":"XXX"
                                                      },
                                          "ShipmentContent" : [
                                                           {
                                                             "MaterialId": "cac43a32-1f08-..",
                                                             "unit": "kg",
                                                             "quantity": 2.0, 
                                                             "labels" : ["A1", "A2", "A3"]
                                                            }, 
                                                            {
                                                             "MaterialId": "cac43333-1f08-",
                                                             "unit": "t",
                                                             "quantity": 0.4, 
                                                             "labels" : ["B1", "B2", "B3"]
                                                             }
                                                             ] 
                                     },
                                     {......,
                                     ....}]}}}

My code so far:

type ApiTypes = 
  {
    ItemId : Guid
    CompletedDate : Nullable<DateTime> 
    Organization: 
      {|
        OrganizationId : Guid
        OrganizationName : string
       |}
    ShipmentContent : // ? How to define the List
      {|
        MaterialId : Guid 
        Quantity : Nullable<decimal> 
        Unit : string
        Labels: List // ?
              
      |}
  }

How can I define these types? The next step would be:

let jsonObject = JObject.Parse(graphResponse)

let frame =
  jsonObject.["data"].["Shipments"].["Data"].Children()
      |> Seq.map (fun jtok -> jtok.ToObject<ApiTypes>())
      |> Frame.ofRecords

Can I define all in one type, or do I have to define a seperate type for ShipmentContents?

I realy apreciate your help!

Fiddle here (doesn't work, but for sharing the code)


Solution

  • This should work if you want to have it all in one type:

    type ApiTypes = 
      {
        ItemId : Guid
        CompletedDate : Nullable<DateTime> 
        Organization: 
          {|
            OrganizationId : Guid
            OrganizationName : string
          |}
        ShipmentContent :
          {|
            MaterialId : Guid 
            Quantity : Nullable<decimal> 
            Unit : string
            Labels: string[]
          |}[]
      }
    

    Note that I've defined the lists as arrays, since arrays are the collection type supported by JSON.