ServiceStack Serializer recursion issue

Hi there,

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.

Performance result is here:

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 :smile:

Many thanks

ServiceStack.Text does not support cyclical dependencies which are poor candidates for use in Serializable DTO’s

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.

Thanks

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.

Hi. Unfortunately, I cant clearly understand your point. If you have a moment to spell it out for me I would appreciate it. many thanks

class Parent
{
    Child[] Children
}
class Child
{
    Parent Parent; //<- Don't serialize models with cyclical dependencies
}

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));
2 Likes