I am in the process of rewriting MMO-Champion Tables and I want a generic way to manage the hash part of the URL (#table__search_results_item=4%3A-slot). I no longer want to write a new parser every time I want to add a new widget.
Why JSON is not suited for URLs
JSON uses characters that are not widely known in the URL. For example, having the double quote character in the URL sucks for HTML embedding. As well, Many of the automated URL insertion will fail at highlighting the whole URL.
MSN Messenger trying to automatically URLify: See the missing last three
}
.http://website.com/#{"table":{"achievement":{"column":"instance","ascending":true}}}
As a user, I am also really disturbed when I see this URL. This does not feel like a normal URL. I am a bit suspicious.
A strong requirement for an URL is its small size. JSON representation can be further compressed by removing extra quotes and ending characters such as "
and }
.
URLON
This is why I made URLON, a new Object Notation intended to be used in URLs. It makes use of URL friendly characters such as = : @ _ &
. It is shorter than JSON and should no longer scare your users ๐
Put some random JSON / URLON / Rison in one of the boxes to see the other notations update.
JSON:
URLON:
Rison:
A reference implementation is available:
It is also available on NPM:
npm install URLON |
var URLON = require('URLON'); console.log(URLON.stringify({URLON: 'works'})); // _URLON=works |
JSON / URLON Comparison
Object
An object starts with an underscore _
. All the fields are separated by ampersand &
and terminated by a semicolon ;
. It makes it feel really url'ish. Note that trailing semicolons can safely be removed.
- JSON:
{"first": "value", "second": "value"}
- URLON:
_first=value&second=value
String
A string just starts with an equal sign =
. A string stop as soon as it reaches a reserved keyword (= : @ _ &
). You can escape a character a slash before /
.
- JSON:
"string"
- URLON:
=string
Number, Boolean and null
Sadly, we have to distinguish between Strings and Numbers/Booleans/null. Therefore I chose to use a colon :
for those instead.
|
|
|
Array
An array starts with a arobas @
and elements are separated by comma @
. The prefix typing does not really fit well with the Array syntax. If you can find something better, I'm open to your suggestions ๐
- JSON:
[1, "vjeux", 3]
- URLON:
@:1@=vjeux@:3
URLON / Query String
Query String is a standard for encoding structured data in a URL context. It is implemented natively in PHP and Ruby. However, I strongly believe that URLON is better for several reasons:
- Query String are not typed: Every atomic value is a string. This makes it less expressive than JSON and less easy to work with as numbers and booleans are common in urls.
- Query Strings are big. For every leaf node, the whole identifier is being written, this is a waste of space.
The following example from the PHP Documentation compares JSON, Query String and URLON.
JSON
{ "user": { "name": "Bob Smith", "age": 47, "sex": "M", "dob": "5-12-1956" }, "pastimes": ["golf", "opera", "poker", "rap"], "children": { "bobby": { "age": 12, "sex": "M" }, "sally": { "age": 8, "sex": "F" } } } |
Minified JSON
{"user":{"name":"Bob Smith","age":47,"sex":"M","dob":"5-12-1956"},"pastimes": ["golf","opera","poker","rap"],"children":{"bobby":{"age":12,"sex":"M"}, "sally":{"age":8,"sex":"F"}}} |
Query String
user[name]=Bob+Smith&user[age]=47&user[sex]=M&user[dob]=5-12-1956&pastimes[0]=golf &pastimes[1]=opera&pastimes[2]=poker&pastimes[3]=rap&children[bobby][age]=12 &children[bobby][sex]=M&children[sally][age]=8&children[sally][sex]=F |
URLON
_user_name=Bob%20Smith&age:47&sex=M&dob=5-12-1956;&pastimes@=golf@=opera @=poker@=rap;&children_bobby_age:12&sex=M;&sally_age:8&sex=F |
Rison
(user:(name:'Bob Smith',age:47,sex:M,dob:'5-12-1956'),pastimes:!(golf,opera ,poker,rap),children:(bobby:(age:12,sex:M),sally:(age:8,sex:F))) |
Rison is a tiny-bit longer than URLON but is easier to read. However it does not feel like it's part of an URL to me. It is also common for automatic linking to break on parenthesis (
or )
, meaning that we are back with the same issues as JSON.
Please, feel free to give your ideas in the comments ๐