Rest 对各种请求/响应类型重用DTO与明确要求/应返回的内容

Rest 对各种请求/响应类型重用DTO与明确要求/应返回的内容,rest,asp.net-web-api,architecture,dto,Rest,Asp.net Web Api,Architecture,Dto,我开始怀疑我是否在这里陷入了反模式,所以请就最佳实践提供建议 我正在设计一个带有一组不同端点的restapi,我想将请求和响应参数包装到nicedto中 例如,一些端点: public async Task<JobStateResponse> GetJobState(JobStateRequest request); public async Task<JobDownloadRespose> DownloadJob(JobDownloadRequest request);

我开始怀疑我是否在这里陷入了反模式,所以请就最佳实践提供建议

我正在设计一个带有一组不同端点的restapi,我想将请求和响应参数包装到nicedto中

例如,一些端点:

public async Task<JobStateResponse> GetJobState(JobStateRequest request);
public async Task<JobDownloadRespose> DownloadJob(JobDownloadRequest request);
public async Task<CreateJobResponse> CreateJob(CreateJobRequest request);
我曾考虑过为这些属性创建一个基类并进行继承,但在某些情况下,某些属性可能是多余的。。。 这意味着这些方法没有明确指出它们正常工作所需的参数

我的意思是,用一个DTO参数公开一个API端点,该参数有7个属性,但实际上只需要2个属性,这听起来很糟糕

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

另外,我最不想要的是请求的几个基类的复杂关系,因为这可能是一个更糟糕的维护问题

那么,处理requestresponse的正确方法是什么

编辑:
关于“基于意见”的标志-我正在寻找处理这一问题的最佳实践。我知道这可以通过多种方式实现,但我希望避免地雷/反模式。另外,我必须说,我对目前为止的答案非常满意。

单独的、简单的DTO将使您的生活更加轻松。它将需要更多的代码,但它将是枯燥、简单的代码,易于测试,并允许您的接口独立地更改和发展

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

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


是的,在这里使用继承是错误的。坚持组合模式,您会很好。

您肯定希望将每个端点的DTO分为两个GROUP:请求和响应

现在,说到继承,您可以拥有基本请求和基本响应类,其中包括一些通用的、非特定的内容(例如,您将数据插入其中的请求和响应包装消息),但您不希望在请求端和响应端之间混合继承


正如其他人已经指出的那样,它一开始的代码要多一些,但这样你就永远不会碰到墙。相反,混合使用它们将很快使您面临巨大的重构,与以清晰、独立的方式开始相比,您将损失更多的时间和精力。

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

嘿。。。我开始怀疑——如果我倾向于组合,那么我的DTO将具有嵌套的复杂类型。如果我有一个复杂的DTO,它总共有几个属性,并且我将它作为HTTP POST发送,那么它可以序列化到请求体中。如果我需要使用HTTP GET怎么办?对象到请求URI的一般转换似乎相当复杂。不要在GET上发送实体。GET模式几乎总是基于标识或查询进行检索。从REST的角度考虑GET是什么,它是对对象的请求,而不是发送对象本身。如果您的URL上有五到六个以上的内容,则可能有另一个您正在引用的对象,您应该使用该对象的标识。我有一个get端点,它需要2个ID值和一个枚举值来设置选项。。。所以,有三件事,包含在“ProjectStateRequest”DTO中,与我返回的ProjectStateResponse DTO保持一致。。。你将如何设计它?作为一篇帖子,你没有得到什么,你正在更新ProjectState…端点是GetProjectState,响应返回一个项目状态…感谢你发布这个问题-这是许多开发人员每天都要面对的问题,是从SO社区获得答案的一个很好的候选人。
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;}
}