为什么 ServiceStack 会给 DTO 增加路由问题的负担?
Why does ServiceStack burden the DTOs with routing concerns?
我正在学习 ServiceStack,通过阅读 this page,有几件事我不太清楚。
所以,考虑这个 DTO 对:
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
而这项服务:
public class MyService : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
为什么 Hello
有责任使用标记界面 IReturn<HelloResponse>
指定 return 类型?
这似乎可以从 MyService
的 return 类型推断出来——除了通常使用 object
的 return 类型,这还需要在测试和客户端代码中进行类型转换。为什么?
为什么 Route
属性应用于模型 Hello
,而不是实际处理请求的服务 MyService
?
似乎这两个事实与服务的相关性比与模型的相关性更高。
一方面,阅读服务声明的人会更容易找到与服务相关的信息,而不必在模型中找到它。
另一方面,接受的 HTTP 方法是由服务通过方法命名约定隐式声明的 - 因此关于服务 routing/dispatch 的事实似乎分散在两层之间。
从这个角度来看,我可能期待更多类似的东西:
// NON-VALID EXAMPLE
public class Hello
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
public class MyService : Service
{
[Route("/hello")]
[Route("/hello/{Name}")]
public HelloResponse Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
约定背后的原因或设计思想是什么?
(请不要把这仅仅看作是一种批评尝试 - 这个框架有很多我喜欢的地方,我真的在试图理解这些约定背后的想法。)
Why does ServiceStack burden the DTOs with routing concerns?
请注意,在 ServiceStack 中根本不需要路由问题负担,所有用户定义的路由都是可选的,所有客户端都可以使用其自动 pre-defined routes.
调用服务
Why is it the responsibility of Hello to specify the return-type using the marker interface IReturn?
它为像 generic C#/.NET Service Clients 这样的客户端库提供了更好的类型化访问,它们能够重新使用现有的 SericeModel DTO 以启用其最佳类型化 API,而无需任何代码生成,例如:
var client = new JsonServiceClient(baseUrl);
var response = client.Get(new Hello { Name = "World" });
或者,如果您不共享 DTO,它对 Add ServiceStack Reference 生成的客户端也很有用。
服务实现上的 return 类型在 ServiceStack 中没有意义,即没有行为差异,并且会阻止相同的服务实现 returning 相同的响应 DTO,或用自定义 HTTP 响应,例如:
public object Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
//...
return new HttpResult(new HelloResponse { Result = $"Hello, {request.Name}!" }) {
//... custom
};
}
both return types adhere to the API's IReturn<HelloResponse>
contract
它只对调用 inter-process Services using the older ResolveService method, but for inter-prcess requests it's recommended to use the Service Gateway 有用,它也使用类型 IReturn<T>
接口标记作为其类型 APIs.
路由不是实现细节,它们是您的 public 服务合同的一部分,应该在用于定义服务合同的 DTO 上进行注释。
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
.NET ServiceStack 客户端使用它们发送服务客户端请求的位置。
var response = client.Get(new Hello { Name = "World" });
For another, accepted HTTP methods are implicitly declared by the service via method-naming conventions - so it seems like the facts about service routing/dispatch are sort of scattered between two layers.
请参阅 Routing 上的文档,路由定义定义了特定路由在哪些方法上处于活动状态,同时根据请求调用最合适的服务实现,例如:
public object GetJson(Customers request) => ... // ONLY GET JSON Requests
public object Get(Customers request) => ... // All other GET Requests
public object Post(Customers request) => ... // ONLY POST Requests
public object Any(Customers request) => ... // ALL other Requests
What is the reason or the design thinking behind the conventions?
很多这些问题试图模糊你的 API 的显式类型服务契约及其具体实现,在 ServiceStack 中,这些是不同的显式概念,其中关于你的 public 的所有信息服务合同应在您的 implementation-free ServiceModel project.
中维护
请阅读 Background Concepts docs 以熟悉 ServiceStack 的目的和目标。
我正在学习 ServiceStack,通过阅读 this page,有几件事我不太清楚。
所以,考虑这个 DTO 对:
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
而这项服务:
public class MyService : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
为什么 Hello
有责任使用标记界面 IReturn<HelloResponse>
指定 return 类型?
这似乎可以从 MyService
的 return 类型推断出来——除了通常使用 object
的 return 类型,这还需要在测试和客户端代码中进行类型转换。为什么?
为什么 Route
属性应用于模型 Hello
,而不是实际处理请求的服务 MyService
?
似乎这两个事实与服务的相关性比与模型的相关性更高。
一方面,阅读服务声明的人会更容易找到与服务相关的信息,而不必在模型中找到它。
另一方面,接受的 HTTP 方法是由服务通过方法命名约定隐式声明的 - 因此关于服务 routing/dispatch 的事实似乎分散在两层之间。
从这个角度来看,我可能期待更多类似的东西:
// NON-VALID EXAMPLE
public class Hello
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
public class MyService : Service
{
[Route("/hello")]
[Route("/hello/{Name}")]
public HelloResponse Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
}
}
约定背后的原因或设计思想是什么?
(请不要把这仅仅看作是一种批评尝试 - 这个框架有很多我喜欢的地方,我真的在试图理解这些约定背后的想法。)
Why does ServiceStack burden the DTOs with routing concerns?
请注意,在 ServiceStack 中根本不需要路由问题负担,所有用户定义的路由都是可选的,所有客户端都可以使用其自动 pre-defined routes.
调用服务Why is it the responsibility of Hello to specify the return-type using the marker interface IReturn?
它为像 generic C#/.NET Service Clients 这样的客户端库提供了更好的类型化访问,它们能够重新使用现有的 SericeModel DTO 以启用其最佳类型化 API,而无需任何代码生成,例如:
var client = new JsonServiceClient(baseUrl);
var response = client.Get(new Hello { Name = "World" });
或者,如果您不共享 DTO,它对 Add ServiceStack Reference 生成的客户端也很有用。
服务实现上的 return 类型在 ServiceStack 中没有意义,即没有行为差异,并且会阻止相同的服务实现 returning 相同的响应 DTO,或用自定义 HTTP 响应,例如:
public object Any(Hello request)
{
return new HelloResponse { Result = $"Hello, {request.Name}!" };
//...
return new HttpResult(new HelloResponse { Result = $"Hello, {request.Name}!" }) {
//... custom
};
}
both return types adhere to the API's
IReturn<HelloResponse>
contract
它只对调用 inter-process Services using the older ResolveService method, but for inter-prcess requests it's recommended to use the Service Gateway 有用,它也使用类型 IReturn<T>
接口标记作为其类型 APIs.
路由不是实现细节,它们是您的 public 服务合同的一部分,应该在用于定义服务合同的 DTO 上进行注释。
[Route("/hello")]
[Route("/hello/{Name}")]
public class Hello : IReturn<HelloResponse>
{
public string Name { get; set; }
}
public class HelloResponse
{
public string Result { get; set; }
}
.NET ServiceStack 客户端使用它们发送服务客户端请求的位置。
var response = client.Get(new Hello { Name = "World" });
For another, accepted HTTP methods are implicitly declared by the service via method-naming conventions - so it seems like the facts about service routing/dispatch are sort of scattered between two layers.
请参阅 Routing 上的文档,路由定义定义了特定路由在哪些方法上处于活动状态,同时根据请求调用最合适的服务实现,例如:
public object GetJson(Customers request) => ... // ONLY GET JSON Requests
public object Get(Customers request) => ... // All other GET Requests
public object Post(Customers request) => ... // ONLY POST Requests
public object Any(Customers request) => ... // ALL other Requests
What is the reason or the design thinking behind the conventions?
很多这些问题试图模糊你的 API 的显式类型服务契约及其具体实现,在 ServiceStack 中,这些是不同的显式概念,其中关于你的 public 的所有信息服务合同应在您的 implementation-free ServiceModel project.
中维护请阅读 Background Concepts docs 以熟悉 ServiceStack 的目的和目标。