Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing type definitions with JSONProvider?

I'm using the JSONProvider from FSharp-Data to automatically create types for a webservice that I'm consuming using sample responses from the service.

However I'm a bit confused when it comes to types that are reused in the service, like for example there is one api method that return a single item of type X while another returns a list of X and so on. Do I really have to generate multiple definitions for this, and won't that mean that I will have duplicate types for the same thing?

So, I guess what I'm really asking, is there a way to create composite types from types generated from JSON samples?

like image 918
monoceres Avatar asked May 25 '15 08:05

monoceres


Video Answer


1 Answers

If you call JsonProvider separately with separate samples, then you will get duplicate types for the same things in the sample. Sadly, there is not much that the F# Data library can do about this.

One option that you have would be to pass multiple samples to the JsonProvider at the same time (using the SampleIsList parameters). In that case, it tries to find one type for all the samples you provide - but it will also share types with the same structure among all the samples.

I assume you do not want to get one type for all your samples - in that case, you can wrap the individual samples with additional JSON object like this (here, the real samples are the records nested under "one" and "two"):

type J = JsonProvider<"""
  [ { "one": { "person": {"name": "Tomas"} } },
    { "two": { "num": 42, "other":  {"name": "Tomas"} } } ]""", SampleIsList=true>

Now, you can run the Parse method and wrap the samples in a new JSON object using "one" or "two", depending on which sample you are processing:

let j1 = """{ "person": {"name": "Tomas"} }"""
let o1 = J.Parse("""{"one":""" + j1 + "}").One.Value

let j2 = """{ "num": 42, "other": {"name": "Tomas"} }"""
let o2 = J.Parse("""{"two":""" + j2 + "}").Two.Value

The "one" and "two" records are completely arbitrary (I just added them to have two separate names). We wrap the JSON before parsing it and then we access it using the One or Two property. However, it means that o1.Person and o2.Other are now of the same type:

o1.Person = o2.Other

This returns false because we do not implement equality on JSON values in F# Data, but it type checks - so the types are the same.

This is fairly complicated, so I would probably look for other ways of doing what you need - but it is one way to get shared types among multiple JSON samples.

like image 176
Tomas Petricek Avatar answered Oct 11 '22 02:10

Tomas Petricek