Wednesday, June 25, 2014

Amazing (FSharp.Data) Data Access Library for F#

Last few days I spent on a working with data stored in JSON and XML files. I tried to download a file with audio metadata (e.g. [1]), and get some useful informations about a track (e.g. recording's author or release types). My GSoC's mentor, Andrés G. Aragoneses, recomended me an amazing library for this purpose; FSSharp.Data [2].

A Few Words About FSharp.Data

FSharp.Data is a library, which allows you work with data in a simple and convenience way. It offers to user easy access to particular elements of JSON, XML and CSV's through defined in the library providers. It supports also WorldBank and Freebase services.

Example code

An aim of code shown below is to parse simple JSON data (defined as a data) and displays it on a screen.
open FSharp.Data
type Vehicles = JsonProvider<""" 
[
    {
    "type" : "some-type", 
    "year" : 2000, 
    "photos": [
        {
        "location" : "some-location"
        }
    ]
    }
] """>

let data = """ 
[
    {
    "type" : "car", 
    "year" : 2005, 
    "photos": [
        {
        "location" : "img_001.jpg"
        },
        {
        "location" : "img_002.jpg"
        }
    ]
    },
    {
    "type" : "bike", 
    "year" : 2014, 
    "photos": [
        {
        "location" : "my_bike.jpg"
        }
    ]
    }
] """

let parse =
    let records = Vehicles.Parse(data);
    for vehicle in records do
        printfn "Type: %s" vehicle.Type
        printfn "Year: %i" vehicle.Year
        printfn "Photos: "
        for photo in vehicle.Photos do
            printfn "\t * %s" photo.Location
At the beginning, there is generation of a type(Vehicles) by parameterizing JsonProvider using one parameter - string. This parameter is a sample JSON data which has the same structure as another documents (which will be parsed using this type in the future) or a file contains JSON data. Type exposes properties (in a PascalCase) according to a nodes defined in a JSON sample data. Result:
loganek@loganek-cmp ~$ ./vehicles.exe 
Type: car
Year: 2005
Photos: 
  * img_001.jpg
  * img_002.jpg
Type: bike
Year: 2014
Photos: 
  * my_bike.jpg
loganek@loganek-cmp ~$ 

Follow the link [3] for more informations about JsonProvider.

Dynamic loading JSon data structure

In an example shown above JSON's data structure was known in compile-time. Usually we knows, what kind of document will be passed to our application, and there's no need to dynamic loading structure description. But there's a few situations (e.g. XML <-> JSON file converter), where structure is known only in runtime. In that case, JsonExtensions [4] (or CsvExtensions [5], depends on a data) might be used.
That's less convenient and less efficient way, and if it's possible, providers should be used instead of it.

Suggestions in MonoDevelop

The most amazing thing, which I discovered during work with FSharp.Data, is that, MonoDevelop suggest property's names (even with their types). Little thing, but made me happy :)



Links
[1] http://api.acoustid.org/v2/lookup?client=8XaBELgH&meta=recordings+releasegroups&trackid=9ff43b6a-4f16-427c-93c2-92307ca505e0
[2] http://fsharp.github.io/FSharp.Data/
[3] http://fsharp.github.io/FSharp.Data/library/JsonProvider.html
[4] http://fsharp.github.io/FSharp.Data/library/JsonValue.html 
[5] http://fsharp.github.io/FSharp.Data/library/CsvFile.html