全胖还是瘦 DTO objects?
Full fat or skinny DTO objects?
我要return Full-Fat Dtos;即使用基本的 parent 实体信息,它的 ID 和名称,以及 child 实体的集合转换为 child dto 的集合;或去掉所有东西,只有 parent 个实体的 return 个 ID?
瘦的选择会导致大量调用 web-api 来填充缺失的细节,但是 full-fat dto 将是一个相当重的 object 如果一个实体有许多 child、grand-child 等关系。
是否有 semi-skimmed 选项可以在特定级别停止 dto 序列化?
要添加一些额外的上下文:我们正在包装第 3 方 api 供内部使用。第 3 方正在使用 "skinny" 方法处理 return ~18,000 个实体,大约 18mb。
要使其不仅仅是一个 ID 集合,我们至少需要添加一些上下文。 Id 和 Name 实体很简单,可以包含但是相关字段可能具有 child 关系,由于底层数据库设计导致有趣的循环关系,事情变得有趣...
我一直倾向于 "full-fat" DTO 方法,正如您所说的那样。性能是一项功能,没有比增加一堆不必要的网络延迟更好的降低性能的方法了。
我会说,除非你正在处理一个资源严重紧张的机器,否则不要全力以赴,以减少往返服务器的往返次数。
您没有提供太多信息,但我想您在这里得到了数据库表的支持?如果是这样,我更愿意将 "entities" 公开为单个数据库记录的纯粹表示(显然省略了敏感字段)。并创建一个 RESTful API 来公开和导航它。
EDIT: To elaborate with some code on what I mean by "full-fat" (note:
certain superfluous details are omitted to reduce the verbosity).
示例 SQL 设置:
create table dbo.User (
Id int identity primary key,
Name nvarchar(50)
);
create table dbo.Post (
Id int identity primary key,
UserId int not null foreign key references dbo.User(Id),
Title nvarchar(50),
Body nvarchar(max)
);
示例 CLR 对象:
public sealed class User
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<Post> Posts { get; set; }
}
public sealed class Post
{
public int Id { get; set; }
public int UserId { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public User User { get; set; }
}
鉴于上述设置,有关如何以 REST 方式公开对象的示例如下:
/api/users /*users collection*/
/api/users/1 /*user resource*/
/api/users/1/posts /*user resource with posts sub-collection*/
/api/posts /*posts collection*/
/api/posts/1?user=1|0 /*post resource with/without User*/
选择完全取决于您应用解决方案的环境。
我通常把两者混在一起。如果我有 'master-detail' 类型的视图,例如网上商店,并且我必须在用户只能看到产品名称和价格的列表中显示产品,那么我选择 'skinny' 版本.然后,用户点击商品可以看到详情页,我发的是'full-fat'版本。
但是如果每个产品都有一个类别,我可能只会在 'detail' 产品 dto 中发送类别 ID 和类别名称。然后,当用户单击某个类别以查看类别详细信息和其他产品时,我会发送其余部分。
答案是 "Do you need "Full-Fat" Dto?"
Return 只提供您需要的数据。
例如 Customer-Orders 结构
- 对于仅使用
customer.Id
和 customer.Name
的方法,您只能 return { Id: 1, Name: "One" }
- 对于需要更多客户信息的方法,您将return更多信息
{ Id: 1, Name: "One", Street: "Street 12", City: "City" }
- 对于需要更复杂数据的方法,您将创建 api
return 更复杂的数据
不要尝试从一开始就通用,开发应用程序所需的具体 API 方法,然后您可以看到全局并重构方法以使其更通用,并进行不同的权衡
我要return Full-Fat Dtos;即使用基本的 parent 实体信息,它的 ID 和名称,以及 child 实体的集合转换为 child dto 的集合;或去掉所有东西,只有 parent 个实体的 return 个 ID?
瘦的选择会导致大量调用 web-api 来填充缺失的细节,但是 full-fat dto 将是一个相当重的 object 如果一个实体有许多 child、grand-child 等关系。
是否有 semi-skimmed 选项可以在特定级别停止 dto 序列化?
要添加一些额外的上下文:我们正在包装第 3 方 api 供内部使用。第 3 方正在使用 "skinny" 方法处理 return ~18,000 个实体,大约 18mb。
要使其不仅仅是一个 ID 集合,我们至少需要添加一些上下文。 Id 和 Name 实体很简单,可以包含但是相关字段可能具有 child 关系,由于底层数据库设计导致有趣的循环关系,事情变得有趣...
我一直倾向于 "full-fat" DTO 方法,正如您所说的那样。性能是一项功能,没有比增加一堆不必要的网络延迟更好的降低性能的方法了。
我会说,除非你正在处理一个资源严重紧张的机器,否则不要全力以赴,以减少往返服务器的往返次数。
您没有提供太多信息,但我想您在这里得到了数据库表的支持?如果是这样,我更愿意将 "entities" 公开为单个数据库记录的纯粹表示(显然省略了敏感字段)。并创建一个 RESTful API 来公开和导航它。
EDIT: To elaborate with some code on what I mean by "full-fat" (note: certain superfluous details are omitted to reduce the verbosity).
示例 SQL 设置:
create table dbo.User (
Id int identity primary key,
Name nvarchar(50)
);
create table dbo.Post (
Id int identity primary key,
UserId int not null foreign key references dbo.User(Id),
Title nvarchar(50),
Body nvarchar(max)
);
示例 CLR 对象:
public sealed class User
{
public int Id { get; set; }
public string Name { get; set; }
public IEnumerable<Post> Posts { get; set; }
}
public sealed class Post
{
public int Id { get; set; }
public int UserId { get; set; }
public string Title { get; set; }
public string Body { get; set; }
public User User { get; set; }
}
鉴于上述设置,有关如何以 REST 方式公开对象的示例如下:
/api/users /*users collection*/
/api/users/1 /*user resource*/
/api/users/1/posts /*user resource with posts sub-collection*/
/api/posts /*posts collection*/
/api/posts/1?user=1|0 /*post resource with/without User*/
选择完全取决于您应用解决方案的环境。
我通常把两者混在一起。如果我有 'master-detail' 类型的视图,例如网上商店,并且我必须在用户只能看到产品名称和价格的列表中显示产品,那么我选择 'skinny' 版本.然后,用户点击商品可以看到详情页,我发的是'full-fat'版本。
但是如果每个产品都有一个类别,我可能只会在 'detail' 产品 dto 中发送类别 ID 和类别名称。然后,当用户单击某个类别以查看类别详细信息和其他产品时,我会发送其余部分。
答案是 "Do you need "Full-Fat" Dto?"
Return 只提供您需要的数据。 例如 Customer-Orders 结构
- 对于仅使用
customer.Id
和customer.Name
的方法,您只能 return{ Id: 1, Name: "One" }
- 对于需要更多客户信息的方法,您将return更多信息
{ Id: 1, Name: "One", Street: "Street 12", City: "City" }
- 对于需要更复杂数据的方法,您将创建 api return 更复杂的数据
不要尝试从一开始就通用,开发应用程序所需的具体 API 方法,然后您可以看到全局并重构方法以使其更通用,并进行不同的权衡