Function Repository Resource:

EnsureJSON

Source Notebook

Convert data into a JSON-compatible form

Contributed by: Bob Sandheinrich

ResourceFunction["EnsureJSON"][data]

gives a JSON-compatible conversion of data.

ResourceFunction["EnsureJSON"][data,prop]

returns the specified property prop.

Details and Options

ResourceFunction["EnsureJSON"] attempts to convert each value in the expression to a JSON-compatible value. The only values supported by JSON are reals, integers, strings, booleans, lists, and rules.
Any value that can not be represented in a JSON-compatible form is removed from the data.
The supported properties for prop are:
"Raw"(default) list of rules compatible with JSON export
"JSON"JSON string
"CompactJSON"JSON string with whitespace removed
ExportFormExportForm expression
HTTPResponseHTTPResponse object
ResourceFunction["EnsureJSON"] supports the option "AdditionalRules". When a list of conversion rules is provided they are applied to the data before the standard rules.

Examples

Basic Examples (2) 

Convert a list of rules containing DateObject values to a JSON-compatible form:

In[1]:=
ResourceFunction[
 "EnsureJSON"][{"now" -> Now, "a while ago" -> DateObject[{1990, 1, 1}, "Day", "Gregorian", -6.`]}]
Out[1]=

Convert a nested Association containing Quantity expressions:

In[2]:=
ResourceFunction[
 "EnsureJSON"][<|"weight" -> Quantity[100, "Kilograms"], "measurements" -> <|"height" -> Quantity[1, "Meters"], "width" -> Quantity[10, "Centimeters"]|>|>]
Out[2]=

Scope (4) 

Convert data with Entity objects to a JSON-compatible form:

In[3]:=
ResourceFunction[
 "EnsureJSON"][<|
  "First" -> Entity["Person", "GeorgeWashington::7v7hm"], "Second" -> Entity["Person", "JohnAdams::66gr7"]|>]
Out[3]=

Export the data to JSON directly:

In[4]:=
ResourceFunction[
 "EnsureJSON"][<|
  "First" -> Entity["Person", "GeorgeWashington::7v7hm"], "Second" -> Entity["Person", "JohnAdams::66gr7"]|>, "JSON"]
Out[4]=

Use a more compact JSON formatting:

In[5]:=
ResourceFunction[
 "EnsureJSON"][<|
  "First" -> Entity["Person", "GeorgeWashington::7v7hm"], "Second" -> Entity["Person", "JohnAdams::66gr7"]|>, "CompactJSON"]
Out[5]=

Create an ExportForm expression:

In[6]:=
exform = ResourceFunction[
  "EnsureJSON"][<|
   "First" -> Entity["Person", "GeorgeWashington::7v7hm"], "Second" -> Entity["Person", "JohnAdams::66gr7"]|>, "ExportForm"]
Out[6]=

Deploy it to the cloud to create an active webpage:

In[7]:=
CloudDeploy[Delayed[exform]]
Out[7]=

Create an HTTPResponse object:

In[8]:=
http = ResourceFunction[
  "EnsureJSON"][<|
   "First" -> Entity["Person", "GeorgeWashington::7v7hm"], "Second" -> Entity["Person", "JohnAdams::66gr7"]|>, HTTPResponse]
Out[8]=

Deploy the http response to the cloud to make a live API:

In[9]:=
api = CloudDeploy[Delayed@http]
Out[9]=

Use the API:

In[10]:=
Import@URLRead[api]
Out[10]=

Options (2) 

Include additional custom rules in the conversion by using the AdditionalRules option:

In[11]:=
ResourceFunction["EnsureJSON"][{"myobj" -> MyObject["a", "b", "c"]}, "AdditionalRules" -> {ob_MyObject :> (StringJoin @@ ob)}]
Out[11]=

Rules given in "AdditionalRules" are applied before the standard conversion rules:

In[12]:=
ResourceFunction["EnsureJSON"][{"date" -> Now}]
Out[12]=
In[13]:=
ResourceFunction["EnsureJSON"][{"date" -> Now}, "AdditionalRules" -> {ob_DateObject :> DateString[ob, {"Year", "Month", "Day", " - ", "Hour"}]}]
Out[13]=

Properties and Relations (3) 

Some expressions are not readily converted to JSON-compatible forms. EnsureJSON removes those values from the data:

In[14]:=
ResourceFunction[
 "EnsureJSON"][<|
  "array" -> SparseArray[{{1, 1} -> 1, {2, 2} -> 2, {3, 3} -> 3, {1, 3} -> 4}], "randomexprs" -> {1, 0.1, Red, RandomImage[], Plot[Sin[x], {x, 0, Pi}]}|>]
Out[14]=

Non-string keys are also removed:

In[15]:=
ResourceFunction["EnsureJSON"][{1 -> 1, "one" -> 1}]
Out[15]=

Define data containing many values that do not usually convert to JSON:

In[16]:=
data = <|"assoc" -> <|
    "missing" -> Missing["Not Found"],
    "true" -> True,
    "false" -> False,
    "all" -> All,
    "none" -> None,
    "location" -> GeoPosition[{40.11`, -88.24`}],
    "entity" -> Entity["City", {"SaintLouis", "Missouri", "UnitedStates"}],
    "dates" -> {DateObject[{2021, 1, 5}, "Day", "Gregorian", -6.`], DateObject[{2021, 1, 5, 9, 7, 47.208725`8.426597247626681}, "Instant", "Gregorian", -6.`], DateObject[{2000}, "Year", "Gregorian", -6.`]},
    "colors" -> {RGBColor[1, 0, 0], RGBColor[0, 0, 1], RGBColor[
      0, 1, 0]},
    "cloudobject" -> CloudObject["Testing"],
    "link" -> Hyperlink["wiki", "https://www.wikipedia.org"],
    "url" -> URL["https://www.wolfram.com"],
    "quantity" -> Quantity[500, "Miles"]|>|>
Out[16]=

Exporting fails:

In[17]:=
ExportString[data, "JSON"]
Out[17]=

EnsureJSON works:

In[18]:=
ResourceFunction["EnsureJSON"][data, "JSON"]
Out[18]=

Possible Issues (2) 

The data should have a structure compatible with JSON:

In[19]:=
ResourceFunction["EnsureJSON"]["date" -> Yesterday, "JSON"]
Out[19]=

Use lists of rules instead of unwrapped expressions:

In[20]:=
ResourceFunction[
 "EnsureJSON"][{"data" -> {"date" -> Yesterday}}, "JSON"]
Out[20]=

Version History

  • 1.0.0 – 21 January 2021

Related Resources

Author Notes

The list of conversion rules should grow over time through occasional updates. Support for a default handler for non-JSON-supported values will also be added.

License Information