Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Understanding JSON

Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

JSON (JavaScript Object Notation, which I pronounce "Jason" and you can pronounce however you like) is a text-based data format that's designed to be human-readable, lightweight, and easy to transmit between a server and a web client. Its syntax is derived from JavaScript -- hence the name -- but it can be used in most languages, including AS3 and C#.


Arrays

If you've done much programming, you'll have come across arrays before: collections of items, each assigned to a specific integer.

In JSON, an array of the first six letters of the alphabet would be represented like this:

["a", "b", "c", "d", "e", "f"]

AS3 and JavaScript coders will find the above listing very familiar. It's similar to the C# way of defining an array, too.

As you can probably guess, the square brackets say "this is an array", and commas are used to separate different elements (note that there's no comma after the final element). Assuming the language in which you parse the JSON uses zero-based arrays (and how many languages don't, these days?), element 0 will be "a", 1 will be "b", 2 will be "c", and so on.

To make arrays easier to read, we'll often write them with extra newlines and indentation:

[
	"a", 
	"b", 
	"c", 
	"d", 
	"e", 
	"f"
]

Note that there's still no comma after the final element, so it now looks a bit odd.

We don't have to use strings as the elements of a JSON array; we can also use numbers, true, false, and null. There's no strict typing, which means you can mix the types of values you use in any given array. For instance, this is perfectly valid:

[
	"apple", 
	3, 
	912, 
	null,
	-7.2222202, 
	"#", 
	true,
	false
]

Note that you must use double quotes (") to surround all your strings; single quotes (') are not allowed. Yes, this is the case, even though JavaScript allows you to enclose strings in either type of quote. If you want to use double quotes inside JSON strings, use \" instead.


Objects

An array is a collection of items where each is assigned to a specific integer. An object is a collection of items where each is assigned to a specific string. The items are called values, and the strings used to identify them are called keys. Some programming languages call this kind of data structure a hash table or hash map.

We could represent people's ages in an object like so:

{ "Alan": 44, "John": 58, "Brian": 19, "Eliza": 4, "Jessie": 58 }

Curly braces say "this is an object", and -- as with arrays -- commas separate different elements. However, the elements are given in pairs, this time. It's easier to see if we add some newlines and indentation:

{ 
	"Alan": 44, 
	"John": 58, 
	"Brian": 19, 
	"Eliza": 4, 
	"Jessie": 58 
}

In each pair, a colon separates the key (which is a string) from the value (which, in this case, is a number). When we were making an array, we didn't need to specify which integer each element was assigned to (i.e. we only needed to specify the values and not the keys), because they were assigned based on the order in which they were written in the array.

Rather than request the second or fifth element, as you would when accessing an array, with an object you'll request the "Alan"th or "Eliza"th element.

To make things more confusing, objects also allow you to use strings as the values -- not just the keys. So you could have an object like this:

{ 
	"Activetuts+": "http://active.tutsplus.com/", 
	"Psdtuts+": "http://psd.tutsplus.com/", 
	"Nettuts+": "http://net.tutsplus.com/", 
	"Aetuts+": "http://ae.tutsplus.com/", 
	"Vectortuts+": "http://vector.tutsplus.com/", 
	"Audiotuts+": "http://audio.tutsplus.com/", 
	"Cgtuts+": "http://cg.tutsplus.com/", 
	"Phototuts+": "http://photo.tutsplus.com/", 
	"Webdesigntuts+": "http://webdesign.tutsplus.com/", 
	"Mobiletuts+": "http://mobile.tutsplus.com/"
}

This way, to retrieve the URL for a given Tuts+ site, you can request it using the name of the site as a key. However, the reverse isn't true -- you can't use "http://cg.tutsplus.com/" to retrieve "Cgtuts+".

The same rules about different types of quotes apply to objects as to arrays. Objects can also use strings, numbers, true, false, and null as values (but only strings as keys).


Nesting

Objects and arrays can also store other objects and arrays. This lets us create nested data structures; for example:

{ 
	"Activetuts+": { "url": "http://active.tutsplus.com/", "hasPremium": true },
	"Psdtuts+": { "url": "http://psd.tutsplus.com/", "hasPremium": true },
	"Nettuts+": { "url": "http://net.tutsplus.com/", "hasPremium": true },
	"Aetuts+": { "url": "http://ae.tutsplus.com/", "hasPremium": true },
	"Vectortuts+": { "url": "http://vector.tutsplus.com/", "hasPremium": true },
	"Audiotuts+": { "url": "http://audio.tutsplus.com/", "hasPremium": true },
	"Cgtuts+": { "url": "http://cg.tutsplus.com/", "hasPremium": true },
	"Phototuts+": { "url": "http://photo.tutsplus.com/", "hasPremium": true },
	"Webdesigntuts+": { "url": "http://webdesign.tutsplus.com/", "hasPremium": false },
	"Mobiletuts+": { "url": "http://mobile.tutsplus.com/", "hasPremium": false }
}

Let's see that with a little more whitespace:

{ 
	"Activetuts+": 
	{ 
		"url": "http://active.tutsplus.com/", 
		"hasPremium": true 
	},
	"Psdtuts+": 
	{ 
		"url": "http://psd.tutsplus.com/", 
		"hasPremium": true 
	},
	"Nettuts+": 
	{ 
		"url": "http://net.tutsplus.com/", 
		"hasPremium": true 
	},
	"Aetuts+": 
	{ 
		"url": "http://ae.tutsplus.com/", 
		"hasPremium": true 
	},
	"Vectortuts+": 
	{ 
		"url": "http://vector.tutsplus.com/", 
		"hasPremium": true 
	},
	"Audiotuts+": 
	{ 
		"url": "http://audio.tutsplus.com/", 
		"hasPremium": true 
	},
	"Cgtuts+": 
	{ 
		"url": "http://cg.tutsplus.com/", 
		"hasPremium": true 
	},
	"Phototuts+": 
	{ 
		"url": "http://photo.tutsplus.com/", 
		"hasPremium": true 
	},
	"Webdesigntuts+": 
	{ 
		"url": "http://webdesign.tutsplus.com/", 
		"hasPremium": false 
	},
	"Mobiletuts+": 
	{ 
		"url": "http://mobile.tutsplus.com/", 
		"hasPremium": false
	}
}

Each object contains two fields: one with the key "url" whose value is a string containing the URL of the site, and one with the key hasPremium whose value is a Boolean that's true if the site has a Premium section.

We're not restricted to having the exact same structure for each object in the JSON, though. For example, we could add an extra URL that points to the Premium program URL, but only for those sites who have one:

{ 
	"Activetuts+": 
	{ 
		"url": "http://active.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/active-Premium/"
	},
	"Psdtuts+": 
	{ 
		"url": "http://psd.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/psd-Premium/"
	},
	"Nettuts+": 
	{ 
		"url": "http://net.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/net-Premium/"
	},
	"Aetuts+": 
	{ 
		"url": "http://ae.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/ae-Premium/"
	},
	"Vectortuts+": 
	{ 
		"url": "http://vector.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/vector-Premium/"
	},
	"Audiotuts+": 
	{ 
		"url": "http://audio.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/audio-Premium/"
	},
	"Cgtuts+": 
	{ 
		"url": "http://cg.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/cg-Premium/"
	},
	"Phototuts+": 
	{ 
		"url": "http://photo.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/photo-Premium/"
	},
	"Webdesigntuts+": 
	{ 
		"url": "http://webdesign.tutsplus.com/", 
		"hasPremium": false 
	},
	"Mobiletuts+": 
	{ 
		"url": "http://mobile.tutsplus.com/", 
		"hasPremium": false
	}
}

We could even include an array of all the latest Premium tutorials for a given site (I'll just show Activetuts+ here, and limit it to a few Premiums, to save space):

{ 
	"Activetuts+": 
	{ 
		"url": "http://active.tutsplus.com/", 
		"hasPremium": true,
		"premiumUrl": "http://tutsplus.com/Premium-program/active-Premium/"
		"previousPremiums":
		[
			"http://tutsplus.com/join/",
			"http://active.tutsplus.com/tutorials/games/create-a-space-shooter-game-in-flash-using-as3http://tutsplus.com/join/",
			"http://active.tutsplus.com/tutorials/games/obscuring-and-revealing-scenes-with-as3http://tutsplus.com/join/",
			"http://active.tutsplus.com/tutorials/games/building-a-dynamic-shadow-casting-engine-in-as3http://tutsplus.com/join/",
			"http://tutsplus.com/join/"
		]
	},
	
	/** SNIP! **/
	
	"Mobiletuts+": 
	{ 
		"url": "http://mobile.tutsplus.com/", 
		"hasPremium": false
	}
}

An array makes sense for listing the Premiums, because I'm working under the assumption that any app which actually reads this data is just going to display a list of Premium tutorials, rather than needing to access them according to their name -- so we don't need to assign them each a string key.

We could take this even further:

{ 
	"Activetuts+": 
	{ 
		"url": "http://active.tutsplus.com/", 
		"premium":
		{
			"hasPremium": true,
			"premiumUrl": "http://tutsplus.com/Premium-program/active-Premium/",
			"previousPremiums":
			[
				{
					"title": "Create a Customizable Flash Quiz Application",
					"url": "http://tutsplus.com/join/",
				},
				{
					"title": "Create a Space Shooter Game in Flash Using AS3",
					"url": "http://active.tutsplus.com/tutorials/games/create-a-space-shooter-game-in-flash-using-as3http://tutsplus.com/join/",
				},
				{
					"title": "Obscuring and Revealing Scenes with AS3",
					"url": "http://active.tutsplus.com/tutorials/games/obscuring-and-revealing-scenes-with-as3http://tutsplus.com/join/",
				},
				{
					"title": "Building a Dynamic Shadow Casting Engine in AS3",
					"url": "http://active.tutsplus.com/tutorials/games/building-a-dynamic-shadow-casting-engine-in-as3http://tutsplus.com/join/",
				},
				{
					"title": "Animating the Envato Community Podcast",
					"url": "http://tutsplus.com/join/"
				}
			]
	},
	
	/** SNIP! **/
	
	"Mobiletuts+": 
	{ 
		"url": "http://mobile.tutsplus.com/", 
		"premium":
		{
			"hasPremium": false
		}
	}
}

Phew! If we wanted we could create objects that contain the names and profile URLs of each author of each Premium tutorial -- can you figure out the best way to do that?

Keeping arrays within arrays can be useful, too; particularly for gaming. This could be the current layout of a Tic-Tac-Toe board:

[
	[
		1,
		2,
		0
	],
	[
		0, 
		1,
		0
	]
	[
		0,
		2,
		1
	]
]

Not seeing it? Try removing some whitespace:

[
	[1,2,0],
	[0,1,0],
	[0,2,1]
]

1 is a nought, 2 is a cross and 0 is an empty space. Noughts win! And I'm sure you can see how something similar could be used for Battleships or Connect 4 or Minesweeper. For more info on nested arrays, check out my previous tutorial.


Using JSON with Different Platforms

Since JSON is so popular, there are parsers (tools and libraries that decode one programming language so that another can understand it) and generators (tools and libraries that do the opposite; encode one programming language into another) available for most programming languages. Just search [JSON parser (name of your language}]. I'll highlight a few that are relevant to Activetuts+ readers.


For Flash and AS3

The standard library for encoding and decoding JSON data in AS3 is the as3corelib; see my guide to using external libraries if you're not sure how to install it.

You can decode a JSON-formatted String to AS3 objects and arrays by passing it to com.adobe.serialization.json.JSON.decode(); the return value will be either an array or an object, depending on the JSON. If you pass false as a second argument, the decoder won't follow the JSON standard so strictly, so you can get away with sloppier formatting.

You can encode an AS3 object or array (which can contain nested objects and arrays) to a JSON string by passing it to com.adobe.serialization.json.JSON.encode(); the return value will be a String.

It's been announced that future versions of Flash will include native JSON parsing, so there'll soon be no need to use the as3corelib for that purpose.


For .NET (Including Silverlight)

To parse JSON, just add a reference to System.Json. Then:

#using System.Json;

decoded = JsonValue.Parse(jsonString);	//may be a JsonPrimitive, JsonArray, or JsonObject, depending on the JSON passed

To encode an object to a JSON string is a little more complicated. You must first create a data contract for the type of object you wish to encode; let's call ours Thing, and the actual object myThing. Then:

#using System.Runtime.Serialization.Json;

MemoryStream myStream = new MemoryStream();
DataContractJsonSerializer jsonEncoder = new DataContractJsonSerializer(typeof(Thing));
jsonEncoder.WriteObject(myStream, myThing);

myStream.Position = 0;
StreamReader sr = new StreamReader(myStream);

encoded = sr.ReadToEnd();

You can also use this method to decode a JSON string to a specific class of object:

#using System.Runtime.Serialization.Json;

myStream.Position = 0;
myOtherThing = ser.ReadObject(myStream);	//you should cast this as Thing

For more information, see the MSDN pages Working with JSON Data and How to: Serialize and Deserialize JSON Data.


For JavaScript (and thus HTML 5 apps)

You could just pass the JSON string to eval() in JavaScript, but this is a terrible security risk. Most modern browsers support a function JSON.parse(), which will parse a JSON string into JavaScript objects, and JSON.stringify(), which will turn a JavaScript object or array into a JSON string.

Douglas Crockford created a library for doing this in older browsers; it's available on github.


For Unity

There's a C# assembly called LitJSON which you can use in your Unity projects to parse and generate JSON. You can use this even if your project is written in JavaScript or Boo rather than C#.

To decode a Unity object to a JSON string:

#using LitJson;

string jsonString = JsonMapper.ToJson (myObject);

To encode a JSON string to a Unity object of type Thing:

#using LitJson;

Thing myThing = JsonMapper.ToObject<Thing> (jsonString);

The LitJSON Manual is great; I recommend reading that for more guidance.


For Other Languages

JSON.org has a long list of libraries for various different platforms and languages -- plus, you can search Google, as mentioned above ;)

That site also has some great visualizations of how JSON can be constructed, and plenty of detail going beyond what I've explained in this quick introduction. Check it out if you want to know more!

Advertisement