30
votes

Is there a standard way of referencing objects by identity in JSON? For example, so that graphs and other data structures with lots of (possibly circular) references can be sanely serialized/loaded?

Edit: I know that it's easy to do one-off solutions (“make a list of all the nodes in the graph, then …”). I'm wondering if there is a standard, generic, solution to this problem.

4

4 Answers

11
votes

I was searching on this same feature recently. There does not seem to be a standard or ubiquitous implementation for referencing in JSON. I found a couple of resources that I can share:

  • The Future for JSON Referencing

http://groups.google.com/group/json-schema/browse_thread/thread/95fb4006f1f92a40 - This is just a discussion on id-based referencing.

  • JSON Referencing in Dojo

http://www.sitepen.com/blog/2008/06/17/json-referencing-in-dojo/ - An implementation in Dojox (extensions for the Dojo framework) - discusses id-based and path based referencing.

  • JSONPath - XPath for JSON

http://goessner.net/articles/JsonPath/ - This seems to be an attempt at establishing a standard for path based JSON referencing - maybe a small subset of XPath (?). There seems to be an implementation here but I kept getting errors on the download section - you might have better luck. But again this is no where close to a standard yet.

10
votes

There is the "JSON Reference" specification, but it seems it didn't got over the state of an expired Internet draft.

Still, it seems to be used in JSON Schema and Swagger (now OpenAPI) (for reusing parts of an API description in other places of the same or another API description).

A reference to an object in the same file looks like this: { "$ref": "#/definitions/Problem" }.

4
votes

Douglas Crockford has a solution that uses JSONPath (an Xpath-like syntax for describing json paths). It seems fairly sane:

https://github.com/douglascrockford/JSON-js/blob/master/cycle.js

1
votes

There is no canonical way to achieve that. JSON does not have a native support for references, so you have to invent your own scheme for unique identifiers which will act as pointers. If you really want to make it generic you could use the object identifiers provided by your programming language (eg. object_id in Ruby or id(obj) in Python).