2
votes

I've seen quite some examples of ServiceStack services and I don't seem to understand when to use a DTO and when to use a Model. As I understand it the DTO is to keep everything as seperate as possible as it's the contract of your service. That would allow you to change a lot in your code but keep the DTO's unchanged. But if you have a Model as one of the properties or it's return value (in a lot of examples that's what I see), the dependency on the model is there any way, so why not simply wrap the Model in the DTO for the request as well?

[Route("/events", "POST")]
public class CreateEvent : IReturn<Event>
{
   public string Name { get; set; }
   public DateTime StartDate { get; set; }
}

From: Recommended ServiceStack API Structure

/// <summary>
///     Define your ServiceStack web service response (i.e. Response DTO).
/// </summary>
public class MovieResponse
{
    /// <summary>
    ///     Gets or sets the movie.
    /// </summary>
    public Movie Movie { get; set; }
}

From: https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.MovieRest/Web/MovieService.cs

1

1 Answers

1
votes

You would use distinct DTO's for Data Models that make poor substitutes for serializable DTO's, e.g:

Have cyclical dependencies or overuse of Inheritance and interfaces

This is less of an issue when using code-first ORM's like OrmLite which as they encourage use of clean POCO's already make good candidates to be re-used as DTO's.

Ideally DTO's should be self-describing and non-hierarchical (i.e. flat) and not rely on serializer-specific features, inhibiting re-usability and reducing interoperability with different formats and serializers.

Doesn't match the shape of the Contract that you want to expose

Your data models might make use of internal codes (e.g. int values) which doesn't make sense to external users outside your database, in which case you may want to project them into self-describing DTO's which exposes more user-friendly labels.

You can use Auto Mapping to reduce the effort whenever you need to re-project between models.