JSON Message
From Ajax Patterns
There's an archived version of this pattern available, taken from the Ajax Pattern book draft, showing roughly how it appeared before the page became publicly editable.
Evidence: 2/3
Tags: JSON Marshall Serialize
Contents |
|
In A Blink
Diagam Server talks (balloon).
- Browser: "Tell me about the account balance."
- Server: "accountBalance: { ... }"
Technical Story
Devi is creating an Ajaxian calendar. The browser periodically polls for new appointments, which the server is sending as JSON messages. Since JSON messages are just Javascript code for object creation, Devi's browser script only needs to run eval against each message in order to reconstruct the appointment.
Problem
How can you transfer data between server and browser?
Forces
- Many Ajaxian applications use semantic messages.
- Both browser and the server must be able to access the message. That usually means the format must be easily accessed in Javascript as well as whichever server-side language is used.
Solution
Pass messages between server and browser in JavaScript Object Notation (JSON) format. JSON is a standard serialization format, created in 2002 as a cleaner and lighter alternative to XML. As with XML, the object can range in complexity from a simple string to a deep hierarchical structure. Also like XML, JSON is language-neutral, meaning that you could marshall a C++ object into JSON notation, and unmarshall it to form an object in Perl. But in practice, JSON is particularly suited to browser-server communication because it's a format based on JavaScript.
In fact, a JSON Message is JavaScript. This is a valid JSON Message:
"Homer J."
You can test browser-based JSON conversion on the Basic JSON Demo. As you'll see there, the JSON message "Homer J." maps to the JavaScript string, Homer J..
Here's a more complex example (as on the demo, reformatted):
{"houseNumber":"742",
"street":"Evergreen Terrace",
"city":"Springfield",
"postcode":"49007",
"country":"USA",
"comments": ["Deliveries accepted.","Familiar address, huh?",""]
}
As you can see, this JSON message is just a literal JavaScript object. You convert it like this:
var name = eval("(" + nameJSON + ")");
Or like this:
var name = null;
eval("name = " + nameJSON);
Or like this if it takes your fancy:
var name=new Function("return " + nameJSON)();
Note that you don't even need a JSON library in the browser. The browser can pick up a JSON string using an XMLHttpRequest Call, and simply run the standard eval function.
However, there is actually a JavaScript JSON library which adds two important capabilities: (a) a safer string-to-object conversion, and (b) an object-to-string conversion.
The safe string-to-object conversion is important if you don't trust the message. It's dangerous to run eval on an arbitrary message, since you might end up running malicious JavaScript code. Instead, there's an explicit method which will only parse the string and not actually run it:
var name = text.parseJSON();
If you need to upload something to the server, you'll need to convert a JavaScript object to JSON. The Basic JSON Demo shows this conversion process too. The call looks like this:
var nameJSON = object.toJSONString();
So far, the examples have considered only JavaScript conversion. But JSON wouldn't be very useful if you could only convert to and from JavaScript objects - you need to convert at the other end too, and your server is probably not running on JavaScript. That's why there are JSON processors for many languages. Using these processors, you can easily share an object between JavaScript and your favourite server-side language.
A remoting modification of the Basic JSON Demo sends JSON to the server, using XMLHttpRequest Calls. There, it's converted to standard PHP objects using Michael Migurski's JSON-PHP library. The library works similarly to JSON libraries for Java, .Net, and other languages. The following code converts JSON to a standard object:
$json = new JSON(); $newObject = $json->decode($jsonString);
while the following code performs the reverse operation:
$json = new JSON(); $json = $json->encode($object);
Real-World Examples
Many websites have a session timeout feature, though it's not implemented in the browser-side manner described here.
Kiko
Kiko is an online calendar application with a slew of Ajax features. As you'd expect, the server holds a model of the calendar and the browser keeps uploading changes using XMLHttpRequest Calls. JSON is the message format used for server responses - each response is a list of objects.
Authenteo
Authenteo uses JSON in the form of JSPON, an extension to JSON to provide client access to persisted objects on the server. By passing the persisted object graph through JSPON, all aspects of a web application including HTML, CSS, and JavaScript are transferred through JSON/JSPON.
Del.icio.us JSON Feed
Del.icio.us, a social bookmarking tool, provides a Web Service that exposes a user's recent bookmarks in the form of a JSON Message. For reasons discussed in On-Demand Javascript, this means a browser script can conveniently grab the data without the need for a Cross-Domain Proxy.
coComment JSON
coComment, a social commenting tool, provides web service that help bloggers to keep tracking on the comment they post all over the time. A sample page that uses JSON exploreBlog
Route Planning
Jim Ley's Route Planning application shows you all the routes for a given airport, and, as his long-running XMLHttpRequest Tutorial explains, it uses JSON. For example, a JSON Message for the LAX airport is available at http://jibbering.com/routeplanner/route.1?LAX. What the browser receives from an XMLHttpRequest Call is a JSON Message as follows
{from:'LAX',airports:[{id:"AMS",country:"NL",lat:"52.316666666667",lon:"4.7833333333333",tz:"Europe/Amsterdam",name:"Amsterdam",shortname:"Schiphol"},...,{id:"IAD",country:"US",lat:"38.95",lon:"-77.45",tz:"America/New_York",name:"Washington, DC",shortname:"Washington Dulles International"}],routes:[{carrier:"star",toAirport:"AMS",miles:5570},...,{carrier:"oneworld",toAirport:"DCA",miles:2304}]}
[Note: I've substituted "..." in place of several dozen airports and carriers.]
Ajax.Net Framework
Ajax.Net is one of several Ajax Stub frameworks that uses JSON Messages to transfer data, which can easily be converted to and from native objects at either end. For more details, see "JSON" in the Related Patterns of Ajax Stub.
Code Examples
Kiko
Kiko responds to XMLHttpRequest Calls with JSON Messages. When you log in, it downloads a list of appointments like this (reformatted below):
[
{"title":"text", "isevent":"bool", "picture":"text", "starttime":"timestamp",
"endtime":"timestamp", "recurs":"int2", "recurend":"timestamp", "insystem":"timestamp",
"recurstart":"timestamp", "recurweek":"int2", "description":"text", "defaultfree":"bool",
"location":"text", "apptid":"int8"},
{"title":"Roundup meeting", "isevent":"t", "picture":"", "starttime":"2005-09-16 19:00:00",
"endtime":"2005-09-16 19:30:00", "recurs":"1", "recurend":"", "insystem":"2005-09-12
14:52:10.965713", "recurstart":"2005-09-16 04:00:00", "recurweek":"16",
"description":"Hopefully just a quick roundup"," defaultfree":"f",
"location":"Cyberspace", "apptid":"9222"},
{"title":"Go Home!", "isevent":"t", "picture":"", "starttime":"2005-09-15 21:00:00",
"endtime":"2005-09-15 21:30:00", "recurs":"0", "recurend":"", "insystem":"2005-09-12
15:00:33.659793", "recurstart":"", "recurweek":"", "description":"", "defaultfree":"f",
"location":"Office, Bar, Home", "apptid":"9288"}
]
Note that the message format here is a little unusual: everything is Strings, whereas JSON can store booleans and numbers directly. Consequently, the first element of the array includes some metadata to facilitate conversion, and the Javascript includes a generic function to create native Javascript objects from JSON messages like this.
Kiko's browser script also includes some conversion to JSON, as shown below, though I was unable to exercise this code. Typically, requests in Kiko are made as POSTs with CGI-style parameters and only the responses are JSON.
var obj=json.stringify({'type':'newuser','email':email})
Alternatives
XML Message
JSON explicitly defines itself as a "fat-free alternative to XML". JSON and XML share the following properties:
- Both are formats that depict an object as a plain-text string.
- Being plain-text string formats, both are suitable for transfer across HTTP. This means that both are suitable as inputs and outputs for a web service.
- Each format is supported by libraries in numerous languages, including Javascript. There are libraries to convert from native objects to either format and back again to native objects.
JSON has several advantages over XML:
- JSON is more compact and the lack of tags can make it easier for humans to comprehend the underlying data.
- It's often claimed that JSON is faster for browsers to parse, though a recent investigation suggests XML parsing actually scales better. See also this follow up on this topic.
- JSON is a concrete data format inherently capable of describing data structures. XML, in contrast, is really a meta-format, designed for giving semantic meaning to parts of a document, and a developer has many choices to make about the precise XML dialect to use it to describe a data structure. Each mapping strategy has its own conventions - for example, developers need to decide on tag names and decide between tag attributes or nested tags. Consequently, a server-side XML-object mapping framework may not be message-compatible with a Javascript counterpart, and never underestimate the amount of meetings and emails that will be necessary to resolve a seemingly trivial argument over data formats. In that sense, JSON is comparable to a well-defined XML dialect rather than XML itself.
- Within browsers, JSON has wider support and more consistent handling, because it's based on standard Javascript.
- JSON happens to be quite compatible with YAML, another XML alternative that's gaining traction in the dynamic scripting community.
XML has several advantages over JSON:
- XML is vastly more familiar to the IT community than JSON.
- XML is more self-documenting. The header identifies which XML format is being used, and there's often a schema or DTD which defines the format precisely.
- XML is inherently designed for giving semantic meaning to documents. XML is usually a better choice for describing documents where order, text/element intermixing, and semantic structural meaning are desired.
- XML has much more support in terms of libraries and tool support. JSON libraries tend to be simply about conversion, which its advocates would probably argue is all that's required. XML, on the other hand, has support in terms of DTD and Schema validators, XPath tools to interrogate the data, XSLT processors to perform translations, and so on. Furthermore, many IDEs, editors, and debugging environments make XML easy to work with.
- For any given task, developers usually have the luxury of choosing between several competing implementations.
- XML has good browser support, too. DOM interrogation, XPath and XSLT, are all possible in modern browsers.
Related Patterns
JSPON
JSON has several shortcomings in describing persisted object graphs.JavaScript Persistent Object Notation (JSPON) is a convention for JSON with the goal of empowering JSON to facilitate JavaScript objects that are intended to persist by defining a scheme to provide the necessary semantics needed for efficient and meaningful persistent objects. JSPON is pure JSON and establishes a format for serializing and referring to objects to enable the persistence of JavaScript objects and object graphs by defining a set of fields with specific meaning for persistence and higher level object description.
- Identification - Persisted objects must be identifiable. Identification also enables JSON to include references to an object referenced in another JSON block, or make multiple references to a single object from multiple referring objects/fields. For example:
{"obj1":
{"field1":
{"id":"1",name:"target"}
},
"obj2":
{"field2":
{"id":"1"}
}
}
In this case it is possible to reconstruct this object such that the resulting object, jsponObject meets the following condition:
jsponObject.obj1.field1 == jsponObject.obj2.field2
- Lazy loading - When large scale object graphs are accessed, it is essential to be able to only transfer partial object graphs. JSPON provides a fields to define objects that have been fully loaded, so that partial object graphs can be loaded.
- Decentralized object creation - When persisted object are created on a client, a negotiation for temporary client side ids to server side ids is needed.
- Array properties- JavaScript supports setting (string keyed)fields on arrays as well as first class primitives. JSPON provides a convention for serializing these objects.
Ajax Stub
As portable object representations, JSON Messages are a useful way to facilitate calls from browser to server.
On-Demand Javascript
Since a JSON Message is an ordinary Javascript script, On-Demand Javascript lets you pull down a Javascript object dynamically. Given that Javascript can be directly loaded from external domains, JSON Message are a neat way to transfer semantic content without the need for a Cross-Domain Proxy. See On-Demand Javascript for more details.
Want to Know More?
JSON by itself doesn't support cyclic objects--It means object hierarchies with cross-refrences -- however there is project called flatTree that leverage JSON to produce JSON message for objects with cyclic references. you can find this program at flatTree
Time your website with
WebWait - from the creator of AjaxPatterns.org
