Serializtion Cycle
Each Tastypie resource has a Serializer instance which it uses internally to convert data between well formatted string and javascript objects. This behavior is defined in the serialize and deserialize methods. A serializer class defines how
data is converted to and from a string. This is done via the to_<FORMAT>
and from_<FORMAT>
methods for each of the formats. For example, the default serializer defines the following methods:
- to_json - Converts an object to a JSON string
- from_json - Converts a JSON string to a javascript object
- to_xml - Converts a javascript object to an XML string
- from_xml - Converts an XML String to a javascript object
Serialization
Serialization is the act of converting a javascript object into a standard format string - JSON string, XML String, YAML String, etc. In the simplest case this is as simple as calling JSON.stringify
. To add support for serialization of a new format, you must define the to_
method on a serializer class.
var tastypie = require('tastypie')
, Class = tastypie.Class
, Serializer = tastypie.Serializer
, JSONSerializer
;
JSONSerializer = new Class({
inherits: Serializer
,options:{
content_types :{
'application/json':'json'
}
}
,to_json: function( data, options, callback ){
callback( null, JSON.stringify( data ) );
}
});
Deserialization
Deserialization is the act of converting a standard format string ( usually from user input ) into a javascript object. To add support for deserialization of a new format, you must define the from_
method on a serializer class.
var tastypie = require('tastypie')
, Class = tastypie.Class
, Serializer = tastypie.Serializer
, JSONSerializer
;
JSONSerializer = new Class({
inherits: Serializer
,options:{
content_types :{
'application/json':'json'
}
}
,from_json: function( data, callback ){
callback( null, JSON.parse( data ) );
}
});
XML Handling
Tastypie 5.0 introduced the strict
xml option for the default serializer which changes the way array elements are handled during serialization. When strict mode
is set to false, Arrays are treated as an object of type array with repeating elements
var Serializer = require('./lib/serializer')
var s = new Serializer({xml:{strict: false}})
var data = {
a:{
b:[1,2,3]
,c:[{
foo:'bar'
},{
bar:'baz'
}]
}
}
s.serialize(data ,'text/xml',function( err, result ){
console.log( result )
});
<?xml version="1.0" encoding="UTF-8"?>
<response>
<a type="object">
<b type="array">
<value type="number">1</value>
<value type="number">2</value>
<value type="number">3</value>
</b>
<c type="array">
<object type="object">
<foo type="string">bar</foo>
</object>
<object type="object">
<bar type="string">baz</bar>
</object>
</c>
</a>
</response>
This has been the default behavior of the serializer since 1.0 of tastypie and was done in an effort to be in line with the behaviors of the python libraries. However, there are two problems that arise with this implementation.
- It is non standard XML format and may break existing XML parsing libaries in the wild
- XML data sent to be deserialized by tastypie would be parsed incorrectly. ( see point #1 )
For this reason, when strict mode is enabled arrays will be serialized as repeating elements. When in strict mode, XML responses sent from tastypie can be sent back in the same format as they were received
var Serializer = require('./lib/serializer')
var s = new Serializer()
var data = {
a:{
b:[1,2,3]
,c:[{
foo:'bar'
},{
bar:'baz'
}]
}
}
s.serialize(data ,'text/xml',function( err, result ){
console.log( result )
});
<?xml version="1.0" encoding="UTF-8"?>
<response>
<a type="object">
<b type="number">1</b>
<b type="number">2</b>
<b type="number">3</b>
<c type="object">
<foo type="string">bar</foo>
</c>
<c type="object">
<bar type="string">baz</bar>
</c>
</a>
</response>