4

I have a customer that uses JSON to represent objects. For example:

var person = {
  fname: "John",
  lname: "Doe",
  nicknames: ["jake", "kevin"]
}

For the purposes of editing these entries, we would like to include GUIDS for each object. A method of embedding the GUIDs has not yet been established. I am currently thinking of doing something like this:

var person = {
  _guids: {
    fname: "XXX",
    lname: "XXX",
    _nicknames: "XXX", /* This GUID corresponds to the nickname container */
    nicknames: ["jake-guid", "kevin-guid"],
  }
  fname: "John",
  lname: "Doe",
  nicknames: ["jake", "kevin"]
}

If each item were to be its own object, it would become exceedingly messy, and would prohibit a clean exchange in cases where the GUIDs are not necessary. However, this approach also leads to the question of how to deal with something like this:

var person = {
  _guids: {
    fname: "XXX",
    lname: "XXX",
    sacks_of_marbles: ["container-guid",
                       "first-sacks-guid", ["XXX", "XXX"],
                       "second-sacks-guid", ["XXX", "XXX"]]
  }
  fname: "John",
  lname: "Doe",
  sacks_of_marbles: [["red", "blue-with-swirls"], ["green", "pink"]]
}

Any recommendations for how to maintain cleanliness, lack of verbosity, as well as the ability to include GUIDs?

  • As far as generating and including guids go, you may find [this](http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript#answer-2117523) article of some use. – War10ck May 20 '13 at 18:40
  • Appreciated. The GUIDs are generated elsewhere, and are merely being embedded within the JSON. – hypersphere May 20 '13 at 18:52

3 Answers3

2

In my opinion, the cleanest "identification strategy" is, firstly to include only relevant identifiers, and secondly to include those identifiers within the scope of the object.

In your case, I'd be genuinely shocked to learn that fname and lname require identifiers of their own. They're properties or attributes of an single person object or record. The person will likely have an ID, and the relevant fname and lname values should be easily identified by the person context:

var person = {
  id: <guid>,
  fname: "Robert",
  lname: "Marley",
  nicknames: ["Bob Marley"]
};

Or, if the nicknames attribute is actually a list of references, maybe this:

var person = {
  id: <guid>,
  fname: "Robert",
  lname: "Marley",
  nicknames: [{id:<guid>,nickname:"Bob Marley"}]
};

If, for some peculiar reason, each name is its own semi-independent record with attributes and identifiers, treat it as a fully qualified object:

var person = {
  id: <guid>,
  fname: {id:<guid>, name:"Robert"},
  lname: {id:<guid>, name:"Marley"},
  nicknames: [ {id:<guid>,nickname:"Bob Marley"} ]
};

And while the 3rd example here isn't terribly confusing, it's probably far more verbose than is necessary. I'd highly recommend shooting for the first example and letting context do it's job.

svidgen
  • 13,744
  • 4
  • 33
  • 58
1

You're not going to get cleanliness or lack of verbosity if you're including GUIDs for everything! That said, one approach would be to turn your property values into hashes like

var person = {
    fname: {
        value: "John",
        guid: "..."
    },
    lname: {
        value: "Doe",
        guid: "..."
    }
}

This has the advantage that you can nest the GUIDs next to the corresponding values, arbitrarily deeply. However, this will also add some overhead to each access to the object's values (since person.fname will have to become person.fname.value, and so on).

bdesham
  • 15,430
  • 13
  • 79
  • 123
  • As simple as that would make the algorithm, that approach is exactly the kind of verbosity that I would like to avoid. If the GUIDs are not included, then the JSON is quite clean and concise. – hypersphere May 20 '13 at 18:51
  • 1
    Who's going to be looking at this JSON: humans or computers? You have a trade-off here between a clean data structure (which leads to more-complex lookups, as in your idea) or a simple way to access data (which leads to a more cluttered-looking structure, as in my idea). You'll have to decide which of those is more important in this case. – bdesham May 20 '13 at 19:03
0

After reviewing the proposals here as well as the use-case, the following solution was adopted, and seems to be working reasonably well.

var person_with_guids = {
  obj:{
    type: "person",
    fname: "fname=guid",
    lname: "lname=guid",
    nicknames: ["larry-guid", "curly=guid", "moe-guid"],
    father: "nick-nolte-guid",
  },
  refs:{
    fname-guid:{
      display: "Johnny",
      edit: "johnny"
    },
    lname-guid:{
      display: "Walker",
      edit: "walker"
    },
    larry-guid:{
      type: "person",
      ...
    }
  }
}

var person_without_guids = {
  fname: "Johnny",
  lname: "Walker",
  nicknames: ["Larry", "Curly", "Moe"],
  father: {fname: "Nick", lname: "Nolte"}
}

Without getting too far into the specifics of the choice, the listed scheme has the advantage of permitting the guid version to be translated by machine into the sans-guid version. There will be times when a human-readable lightweight JSON will be required, and other times when even the subtle difference between the display-text and the edit-text is required.

This same sort of thing could be accomplished by using schemes proposed above making everything into an object and embedding the guid within it. Doing so, however, causes the guids to be included in an already nested system making it even more difficult to interpret visually. To maintain a more flattened representation, a lookup table methodology was selected.

My thanks to all who responded.