I feel like I've gone and over-complicated my design by using DTOs, but I'm looking for a second opinion.
My structure is:
As such, a PlaylistItem domain object looks like:
public class PlaylistItem
{
public virtual Guid Id { get; set; }
public virtual Playlist Playlist { get; set; }
public virtual int Sequence { get; set; }
public virtual string Title { get; set; }
public virtual Video Video { get; set; }
// Not written to the database. Used for client to tell who is who after a save.
public virtual string Cid { get; set; }
}
and a PlaylistItem DTO looks like:
[DataContract]
public class PlaylistItemDto
{
[DataMember(Name = "playlistId")]
public Guid PlaylistId { get; set; }
[DataMember(Name = "id")]
public Guid Id { get; set; }
[DataMember(Name = "sequence")]
public int Sequence { get; set; }
[DataMember(Name = "title")]
public string Title { get; set; }
[DataMember(Name = "video")]
public VideoDto Video { get; set; }
[DataMember(Name = "cid")]
public string Cid { get; set; }
}
The only change is that I have broken the circular-referential structure by replacing the Playlist reference with a PlaylistId.
The default JSON serializer in C# .NET MVC was unable to handle circular structures. I've since updated to using the JSON.NET serializer which is capable of handling circular structures. I'm now re-evaluating why I even need my DTO.
Are there any benefits of a DTO that I should be aware of / considering here? Is it bad practice to JSONize a circular reference and send it across the wire?
JSON, being a hierarchical format, is going to work best when representing data in a hierarchical fashion. JSON isn't a node graph, so trying to serialize graph-like data is going to prove difficult, I think. I think your solution of converting an object (Playlist
) to a form of "reference" (PlaylistId
) is the correct one. The code receiving and processing this JSON can reconstruct the circular reference, if necessary, since you have your "foreign key" (PlaylistId
) in place.
Most of the time I would rather have an extra DTO than none at all. DTOs insulate you from change--in this case, insulate your API from change. PlaylistId
is unlikely to change its schema in the future, but the actual Playlist
might.