-
Notifications
You must be signed in to change notification settings - Fork 16
2. Basic usage
JSON rule is a wild attribute which defines a record name (as atom) and then a list of field rules. Field rules belong to record files one-by-one respectively. In normal cases there are equal number of field rules in the json rule and fields in record definition.
-json(record_name1, {type1, name1}, ...).
-json(record_name2, {type2, name2, [Options]}, ...).The field rules are type-name pairs or type-name-optionlist triplets. Types can be
| Erlang type | JSON type |
|---|---|
| true/false | boolean |
| number | int/double |
| atom | string |
| list of chars | string |
| record | object |
| list of records | array |
| binary | string |
| pid | - |
| ref | - |
Since there are generic rules one can implement conversion for pid, ref, dict, set, etc.
Names with atom type will be camel-cased and converted to string. String names are left as it is. Let us see some examples
| json rule name | json field |
|---|---|
| apple | "apple" |
| person_list | "personList" |
| "birthYear" | "birthYear" |
| "a_string" | "a_string" |
In this example we handle windows on the UI. A window has title and uuid and also upper left and bottom right corner coordinates.
-module(window).
-record(point, {x, y}).
-record(window, {title, uuid, upper_left, bottom_right}).
-json(point, {number, x}, {number, y}).
-json(window, {string, title},
{binary, uuid},
{record, upperLeft},
{record, bottomRight}).
...
Window = #window{title = "MainWindow",
uuid = <<"34fea1-23012">>,
upper_left = #point{x = 200, y = 150},
bottom_right = #point{x = 400, y = 280}},
to_json(Window)JSON can have boolean, number, string and JSON object values. The previous code result in a JSON like this
{
"title": "MainWindow",
"uuid": "34fea1-23012",
"upperLeft": {
"__rec": "point",
"x": 200,
"y": 150
},
"bottomRight": {
"__rec": "point",
"x": 400,
"y": 280
}
}As you can see this generates __rec meta-fields in the embedded object in order to describe the meta-type of the record from which the objects are created. We will discuss this meta-type field later, for now it is enough to know that it is useful for ejson to parse incoming JSONs back according to the rules we specified.
In JSON the most frequent data type is probably the string. In Erlang we have three data types which needs to be converted to strings. List of chars, binaries and atom will be converted to JSON strings. However - from decoding perspective - we need to know if we have a string, what Erlang type we need to create from that. That is why in the rule spec we need to specify the types.
-json({http_request, {atom, method}, {string, url},
{binary, body}, {binary, session_id, [base64]}}).
to_json({http_request, 'GET', "/index.html", <<>>, <<"x#123$‹›&">>}).The result will be a JSON like this
{
"method": "GET",
"url": "/index.html",
"body": "",
"sessionId": "eCMxMjMkOTom"
}If we pass number like 13 in the body, ejson will result in an {error, {binary_value_expected, "body", 13}}. So for the extra work that we specify sometimes the obvious, it gives us better error messages in case of wrong record values. Also, we can tell ejson to base64 encode the binary before put it into the JSON (in case of decoding at first it will base64 decode the string).