functional-programmingf#type-providersfsharp.data.typeproviders

How are F# Type Providers used on a changing Rest/JSON Endpoint?


I am trying to use F# type providers to include weather data in my application. I am using OpenWeatherMap.org to get current weather data. https://openweathermap.org/current

Sometimes the OpenWeatherMap response does not show any JSON for rain (Eg. There is no rain for a 1 hour window).

So if I do something like this:

type WeatherForecast= JsonProvider<"http://api.openweathermap.org/data/2.5/weather?lat=39.64&lon=-74.28&appid=MyKeyICantSharePublicly">
...
let mydata = WeatherForecast.Load("http://api.openweathermap.org/data/2.5/weather/?lat=12&lon=12&appid=MyKeyICantSharePublicly)

printf "%s" (string mydata.Rain.``1h``)

The printf statement will fail because it doesn't always know what mydata.Rain is because the type provider does not provide the Rain information anymore.

Depending on when I try to compile my application, the build will fail because of the type provider.

How can I use type providers with a changing Rest/Json Endpoint like this?

Example data.

{
  "coord": {
    "lon": -74.28,
    "lat": 39.64
  },
  "weather": [
    {
      "id": 701,
      "main": "Mist",
      "description": "mist",
      "icon": "50d"
    },
    {
      "id": 721,
      "main": "Haze",
      "description": "haze",
      "icon": "50d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 7.71,
    "pressure": 1012,
    "humidity": 93,
    "temp_min": 7,
    "temp_max": 9.4
  },
  "visibility": 4023,
  "wind": {
    "speed": 5.7,
    "deg": 2...

Solution

  • Instead of a url, you should provide some samples with and without rain:

    type People = JsonProvider<""" 
      [ { "name":"John", "age":94 }, 
        { "name":"Tomas" } ] """, SampleIsList=true>
    
    for item in People.GetSamples() do 
      printf "%s " item.Name 
      item.Age |> Option.iter (printf "(%d)")
      printfn ""
    

    The samples above have two records one includes age the other one doesn't. That makes the age field an int option.

    From the documentation: http://fsharp.github.io/FSharp.Data/library/JsonProvider.html