设计 SOA WCF Web 服务时的最佳实践是啥?
Posted
技术标签:
【中文标题】设计 SOA WCF Web 服务时的最佳实践是啥?【英文标题】:What is best-practice when designing SOA WCF web-services?设计 SOA WCF Web 服务时的最佳实践是什么? 【发布时间】:2010-10-03 08:34:09 【问题描述】:给定一个操作合同,例如:
[OperationContract]
void Operation(string param1, string param2, int param3);
这可以重新设计为:
[MessageContract]
public class OperationRequest
[MessageBodyMember]
public string Param1 get; set;
[MessageBodyMember]
public string Param2 get; set;
[MessageBodyMember]
public int Param3 get; set;
[MessageContract]
public class OperationResponse
[OperationContract]
OperationResponse Operation(OperationRequest request);
我喜欢 MessageContract 的一点是,我可以更明确地控制 SOAP 消息的格式。
同样,我可以编写几乎相同的代码,但使用 DataContract:
[DataContract]
public class OperationRequest
[DataMember]
public string Param1 get; set;
[DataMember]
public string Param2 get; set;
[DataMember]
public int Param3 get; set;
[DataContract]
public class OperationResponse
[OperationContract]
OperationResponse Operation(OperationRequest request);
我喜欢 DataContract 的一点是我可以定义 IsRequired、Order 和 Name。
今天我预计唯一的消费者将是 WCF 客户端。但是,我想先设计契约,并尽可能地坚持 SOA 实践。我不想让 WCF 规定我的 SOAP、WSDL 和 XSD,而是希望 XML 定义 WCF 层,但使用 WCF 生成它,以免向 WCF 添加任何自定义消息处理。我想遵循最常见的 SOA XML 约定,我认为这些约定可能所有标签都以小写开头——对吗?而且我希望尽可能地容忍版本。
总是这样创建请求和响应消息是否明智?三种格式中的哪一种促进了最佳 SOA 实践?我应该更进一步并定义一个 DataContract 和一个 MessageContract ,而 MessageContract 只包含 DataContract 吗?还是应该只在我真正公开一种新类型(即不将消息类型创建为容器)时才使用 DataContracts?
我知道一组加载的问题,但我正试图深入其中,我不确定将问题分开是否能提供足够的上下文来获得我正在寻找的答案。
【问题讨论】:
【参考方案1】:在操作合约中不要有多个参数总是一个最佳实践,总是有一个包装所有必需参数的类型,这从长远来看会有所帮助。当您添加新的可选参数时,您现有的客户端不会中断。
我在一个业务集成团队工作,我们定期与其他公司(AT&T、Cox、Exxon ...)进行集成,并且从未见过使用多个参数的 Web 服务调用。
【讨论】:
与我们相同的做法。我们将所有内容包装到单个请求和响应对象中。【参考方案2】:XML
通常倾向于驼峰式。 WSDL
和 XML
Schema 对元素和属性都使用驼峰式,例如查看 syntax 和 schema。
为什么SOAP
的定义不同,我不知道,但它对元素使用 PascalCasing,对属性使用 camelCasing,检查 here。
类似地,大多数WS*
规范(可能全部)使用 PascalCasing 表示元素和属性,请参阅here。 XML Schema 不知道它为 XML 定义的类型的约定。
Thomas Erl 写了很多关于SOA
的重要书籍,包括《面向服务的架构》。在第 13 章和 15 章中,他提供了一些典型交易各个部分的 XML 示例。它使用 PascalCasing 在 XML Schema 中定义类型和对象成员,这很好地匹配了 C# 用于类和属性命名的正常模式。因此WCF
默认值已经非常符合标准。
关于实际的消息命名,一些约定使用 camelCasing 而其他约定使用 PascalCasing,所以我的偏好是匹配主要语言需求,在 WCF
的情况下是 PascalCasing。 WCF
默认匹配一些请求和响应消息应该如何编写的示例,some examples here。
因此,现在唯一悬而未决的问题是关于使用OperationContract
、DataContract
和/或MessageContract
的标准化程度。
只有当你有一个复杂类型(XSD
用语)时才定义 DataContract 是有意义的,我倾向于认为 Terry 指出的 YAGNI(你不需要它)是正确的选择,但是 Erl 似乎建议使用更多流程密集型版本,所以我仍然不确定用作默认选择的最佳方法(问题的主要部分)。
【讨论】:
为什么是这个答案社区维基?这是一个很好的答案,vjrobinson 应该得到他/她应得的声誉。【参考方案3】:老实说,我认为这取决于场景。如果您只是交换简单类型 [即string],OperationContract 肯定是可以接受的。
当您想要修改消息格式时应该使用 MessageContract,而当您想要表达复杂类型(例如地址)时应该利用 DataContract。
【讨论】:
【参考方案4】:YAGNI 出现在这里。
我说不要过于幻想未来。 WCF 已经很好地支持 SOA。我说,一般来说,坚持默认值并小心耦合,直到你有特殊需要做一些复杂的事情。
【讨论】:
以上是关于设计 SOA WCF Web 服务时的最佳实践是啥?的主要内容,如果未能解决你的问题,请参考以下文章