将DTO重用于各种请求/响应类型与显示所需内容/应返回的内容

时间:2017-06-03 22:47:31

标签: rest asp.net-web-api architecture dto

我开始怀疑自己是不是会陷入反模式,所以请告知最佳做法。

我正在设计一个带有一组各种端点的REST API,我想要包装请求&响应参数到漂亮的DTO。

例如,一些端点:

public async Task<JobStateResponse> GetJobState(JobStateRequest request);
public async Task<JobDownloadRespose> DownloadJob(JobDownloadRequest request);
public async Task<CreateJobResponse> CreateJob(CreateJobRequest request);

问题是这些请求和响应是相对类似的DTO,例如:

public class JobStateResponse{
    public int TaskId {get;set;}
    public string ExternalId {get;set;}
    public State State {get;set;}
}
public class JobDownloadResponse {
    public int TaskId {get;set;}
    public string ExternalId {get;set;}
    public string JobContent {get;set;}
}

我考虑过为这些和继承创建基类,但在某些情况下,某些属性可能是多余的...... 这意味着这些方法没有明确指出它们工作所需的参数。

我的意思是,使用DTO参数公开API端点,该参数具有7个属性但只需要2个声音非常糟糕 ......

另一方面,为大多数端点维护单独的DTO似乎也是一种过度杀伤,也是维护地狱。

而且我想要的最后一件事是请求的几个基类的复杂关系,因为这可能是一个更糟糕的主要问题。

那么,请求&lt;&gt;响应处理的正确方法是什么?

编辑: 关于基于意见的&#39;标志 - 我正在寻找处理此问题的最佳做法。我知道它可以通过多种方式完成,但我想避免使用地雷/反模式。此外,我得说我到目前为止对答案非常满意。

3 个答案:

答案 0 :(得分:18)

独立,简单的DTO将让您的生活更加轻松。它将需要更多的代码,但它将是无聊的,简单的代码,易于测试,并允许您的界面独立地改变和发展。

为每个请求端点创建一个DTO,为每个响应创建一个单独的DTO。否则,你最终会感到难过。

如果找到多个端点共有的元素,请将它们提取到自己的对象中,并将它们包含在两者中。

是的,在这里使用继承是错误的。坚持构图模式,你会没事的。

答案 1 :(得分:3)

使用单独的DTO可以通过数据访问调用的行为优化数据传输,还允许您限制对可能不希望公开的属性的访问。虽然代码更多,但您正在准确定义所暴露的内容并完全控制它。

答案 2 :(得分:2)

您肯定希望将每个端点的DTO分成2个gruop:请求和响应。

现在,谈到继承,您可以拥有基本请求和基本响应类,其中包括一些常规的,非特定的内容(例如,您插入数据的请求和响应包装器消息)但您不想要混合请求和响应方之间的继承。

正如其他人已经指出的那样,它在开始时会有更多的代码,但这样你就永远不会碰壁了。相反,混合它们很快就会让你有巨大的重构,你会失去更多的时间和神经,而不是以明确,分开的方式开始。