I have an issue with the ServiceStack serializer, which adversely effects performance. It may be that I should be handling it in the certain way but I was not able to find a solution.
If I query10000 orders that happen to have the same buyer, 10000 instances of that same buyer is also returned in json, which makes the response very large. Gzip has support for this recursion so it will compress very well, but I want to avoid this overhead.
JSON.NET seems to handle this issue and only return once instance of the Buyer.
To demonstrate this properly, I have created a tiny demo with test output as I thought this may be more effective than pasting code: github example project
I am still very new to ServiceStack, so please go easy on me
I am sorry but please could you be more specific about what the best practice or intended way to work with this issue is? Are you saying that I project to a flatter DTO using automapping? if so, I dont see how that solves the recusion issue unless the automapper has some specific support for this but still i dont see that anywhere.
Serializable DTO’s should not have cyclical dependencies, when you have a Company > Order the parent child relationship is already defined, just don’t serialize DTO’s that have a cyclical reference back to its parent.
I can’t stress enough how bad Cyclical Dependencies are for Serialization and Data Transfer (i.e. DTO’s). There’s no concept of cyclical dependencies in wire formats, it requires coupling to specific Serializer implementations of specific wire formats, reducing the interoperability and reusability of your services. You’ll also forever be running into endless issues trying to pass POCO’s with cyclical deps into libraries that work with POCO’s.
With that said, I’ve created an example of how you can achieve this with ServiceStack Text Serializers in this commit:
class Node
{
public string Name { get; set; }
[IgnoreDataMember]
public Node Parent { get; set; }
public List<Node> Children { get; set; }
}
JsConfig<Node>.OnDeserializedFn = (node) =>
{
node.Children.Each(child => child.Parent = node);
return node;
};
var parent = new Node
{
Name = "Parent",
};
parent.Children = new List<Node>
{
new Node { Name = "Child", Parent = parent },
};
You can ignore the cyclical Parent' dependency during serialization and restore it with a Deserializing callback which will restore the cyclical relationship:
var json = parent.ToJson();
Assert.That(json,
Is.EqualTo("{\"Name\":\"Parent\",\"Children\":[{\"Name\":\"Child\"}]}"));
var node = json.FromJson<Node>();
Assert.That(node.Children[0].Parent, Is.EqualTo(node));