65.9K
CodeProject 正在变化。 阅读更多。
Home

WCF 还是 ASP.NET Web API?我的几点看法

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.92/5 (99投票s)

2012年3月6日

CPOL

9分钟阅读

viewsIcon

341293

WCF vs. ASP.NET Web API

几周前(大约在 2 月 16 日),WCF Web API——一个用于构建 RESTful/超媒体/HTTP 服务的框架,在过去一年半的时间里作为 CodePlex 上的一个副项目进行开发——已正式并入 ASP.NET,并更名为 ASP.NET Web API。

在过去的两周里,WCF 开发者们提出了很多问题:Web API 不再是 WCF 的一部分意味着什么?WCF 是不是要消亡了?SOAP 是不是已经破产了?HTTP 是实现互操作性的新方式吗?

为了更好地理解发生了什么以及未来的发展方向,我们需要回答几个问题:

  1. Web API 的目的是什么?
  2. 我们为什么需要RESTHTTP 服务?SOAP-over-HTTP 有什么问题?
  3. 为什么 Web API 从 WCF 移到了 ASP.NET MVC?
  4. WCF 还有用武之地吗?我应该在什么时候选择 Web API 而不是 WCF?

Web API 的目的是什么?

当 WCF 在其 Indigo 和 .NET 3 时代被构思出来时,其主要目标是在多种传输协议上支持 SOAP + WS-*。然而,随着时间的推移,人们逐渐清楚地认识到,尽管 SOAP 应用广泛并受许多平台支持,但它并非创建服务的唯一途径。同时,也需要支持非 SOAP 服务,尤其是在 HTTP 上,可以利用 HTTP 协议的强大功能来创建 HTTP 服务:通过简单的 GET 请求激活,或通过 POST 传递纯 XML,并以非 SOAP 内容(如纯 XML、JSON 字符串或任何消费者可以使用的其他内容)进行响应的服务。当时 WCF 非常需要对非 SOAP 服务的支持,主要是因为一些客户端,例如 Web 浏览器,不太适合处理 SOAP 消息(涉及大量的 XML 解析和 DOM 操作)。

因此,在 WCF 3.5 中,我们得到了 WebHttpBinding——一种新的绑定,它帮助我们创建了这种基于 HTTP 的非 SOAP 服务,也就是我们熟知的 RESTful 服务。

WebHttpBinding 还不够,于是在 WCF 3.5 发布后,一套新工具被创造出来——WCF REST Starter Kit。REST Starter Kit 旨在丰富 WCF 3.5 对 HTTP 服务的支持——为 .NET 应用添加更好的客户端支持,扩展服务器端对其他内容类型的支持,实现响应和请求缓存,消息检查等等。不幸的是,这个优秀的工具包从未正式发布,其产品周期止于“Preview 2”,尽管至今仍在一些使用 .NET 3.5 构建的微软产品中使用。

虽然没有正式发布,但 REST Starter Kit 的一些服务端功能被集成到了 WCF 4 中——我们没有得到任何客户端库,但确实获得了大部分服务端功能(不包括新的检查器)。有些功能很好地集成到了 WCF 中,而另一些则需要使用 ASP.NET(通过开启 ASP.NET 兼容模式)。

因此,在 WCF 4 中,我们对“Web” HTTP 服务有了一定的支持,但这并不完美——要获得某些功能,你需要 IIS 托管和 ASP.NET,不是所有类型的请求都能轻松支持(你试过向 WCF HTTP 服务 POST HTML 表单数据吗?),过度使用 CLR 特性来定义 POST/GET/PUT/DELETE 很繁琐,更不用说创建这类服务并配置所有终结点行为所需的配置了。即使做了所有这些,我们实际上也无法完全控制 HTTP 消息。

这就是 Web API(当时称为 WCF Web API)的主要目标:不再从 WCF 的视角看待 HTTP——仅仅把它当作一个传递请求的传输协议。相反,它让我们能够将其视为它真正的应用层协议——一个功能丰富、可互操作、面向资源的协议。Web API 的目的就是正确地使用 URI、HTTP 头和主体来为 Web 创建 HTTP 服务,并为所有希望将 HTTP 作为其协议和终身伴侣的人提供服务。

我们为什么需要RESTHTTP 服务?SOAP-over-HTTP 有什么问题?

SOAP 的世界和 HTTP 服务的世界非常不同。SOAP 允许我们将服务所需的所有信息都放在消息本身中,而忽略其传输协议,无论是 TCP、HTTP、UDP、PGM 还是命名管道……但与 TCP、UDP 和其他第 4-5 层协议不同,HTTP 是一个应用层协议,因此,它提供了多种多样的功能:

  • 它支持定义操作的动词——使用 GET 查询信息,使用 POSTPUT 放置新信息和更新现有信息,使用 DELETE 删除信息等。
  • 它包含非常有意义和描述性的消息头——例如暗示消息正文内容类型的头,解释如何缓存信息、如何保护信息等的头。
  • 它的正文可以用于任何类型的内容,而不仅仅是 SOAP 强制的 XML 内容(如果你想要其他内容——需要将其编码为 base64 字符串并放入 SOAP 的 XML 内容中)。HTTP 消息的正文可以是任何你想要的东西——HTML、纯 XML、JSON、二进制文件(图像、视频、文档……)……
  • 它使用 URI 来标识信息路径(资源)和操作——URI 模板倡议正在流行,并迅速成为表示资源请求和超媒体 URI 的标准方式。

HTTP 的使用多年来不断演进。像REST 超媒体 API 这样的应用层协议架构风格已经在 HTTP 之上出现。这些风格反过来利用 HTTP 的强大功能来创建面向资源的服务,并更好地定义客户端与服务之间的无状态交互。

因此,Web API 旨在支持所有这些方法——你可以用它来创建只使用标准 HTTP 概念(URI 和动词)的 HTTP 服务,也可以用它来创建使用更高级 HTTP 功能的服务——请求/响应头、超媒体概念等。

所以,HTTP 远不止是一个传输协议。它是一个应用层协议,事实是,尽管许多平台知道如何使用 SOAP,但有更多的平台知道如何使用 HTTP!在那些不太支持 SOAP 但支持 HTTP 的平台中,浏览器是其中之一——这可能是 Web 开发者(和用户)最重要的平台。如果你不相信 REST 和超媒体很有用,或许 Martin Fowler 能比我更好地说服你

当然,这并不意味着 SOAP 是多余的——当你没有可用的替代应用层协议时,或者当你希望全面使用 SOAP,并将 HTTP 仅仅视为另一种传递消息的方式时(例如,使用 HTTP 是因为它比 TCP 更容易穿过防火墙),SOAP 仍然很有用。

为什么 Web API 从 WCF 移到了 ASP.NET MVC?

回到 WCF 和 WCF Web API 的故事(我们还在合并之前)。WCF Web API 的另一个目标是引入一些已知的概念,以帮助开发者克服他们在 WCF 中遇到的缺点,例如庞大的配置、过度使用特性,以及 WCF 基础设施对测试不友好等。因此,Web API 使用了 IoC(控制反转),实现了约定优于配置,并试图提供一个更简单的配置环境。

问题在于,当时构建 HTTP 服务有几种不同的方法:

  1. 使用 WebHttp 绑定和 REST 支持的 WCF。
  2. 新的 WCF Web API,即后来的 ASP.NET Web API。
  3. 一个不算新的框架,ASP.NET MVC,它从以 HTML 为中心(从 HTML 页面获取请求并返回 HTML/JSON)转向了以资源为中心——人们开始意识到他们可以将控制器视为服务,并使用 MVC 基础设施来定义控制请求、响应,并更好地控制 HTTP 消息。
  4. 开源框架,如 OpenRastaServiceStack

除此之外,随着时间的推移,WCF Web API 在将 WCF 适配到“原生”HTTP 世界方面遇到了很多麻烦。由于 WCF 主要为基于 SOAP 的 XML 消息设计,为了让 Web API 作为 WCF 的一部分工作所需的“开膛破肚”式的手术有点过头了(至少我从参与创建 Web API 的人那里是这么理解的)。另一方面,ASP.NET MVC 基础设施凭借其对 HTTP 请求和响应的优雅处理,以及对易于创建的控制器的支持,似乎是创建这种新型服务的正确途径。

所以事实是我们有太多的选择,因此也造成了太多的困惑。我们该怎么办?合并团队!(这有点让我们想起 LINQ-to-SQL 和 Entity Framework,WCF 和 ADO.NET Data Services 以及其他类似例子)。于是,WCF 团队和 ASP.NET 团队联手打造了一个专注于 REST/超媒体/HTTP 服务的新框架,服务于 Web 世界,ASP.NET Web API 就此诞生。

对于这个名字的选择,我仍然不太确定,因为新的 Web API 也可以在 ASP.NET 之外与 WCF 一起工作,但我猜“WCF ASP.NET Web API”这个名字有点太长了。或许叫“WASP Web API”?“WAWAPI”(Wcf Aspnet Web API)?或者干脆叫“Hypermedia Web API”?

所以这次合并旨在减少困惑,而不是制造困惑。我想如果当时解释清楚了,也许随着时间的推移会减少很多困惑(参考 PDC 2010 上关于 Silverlight 已死的口误)。微软是不是需要一个新的开发者部门公关团队?

WCF 还有用武之地吗?我应该在什么时候选择 Web API 而不是 WCF?

回想我之前的观点——HTTP 远不止是一个传输协议;全面使用 SOAP,并将 HTTP 仅仅视为另一种传递消息的方式。

  • 如果你的目标是创建支持特殊场景的服务——例如单向消息、消息队列、双工通信等,那么你最好选择 WCF。
  • 如果你想创建的服务在可用时可以使用快速的传输通道,例如 TCP、命名管道,甚至 UDP(在 WCF 4.5 中),并且当所有其他传输方式都不可用时,还希望支持 HTTP,那么你最好选择 WCF,并同时使用基于 SOAP 的绑定和 WebHttp 绑定。
  • 如果你想通过 HTTP 创建面向资源的服务,并且可以利用 HTTP 的全部功能——为浏览器定义缓存控制、使用 ETag 进行版本控制和并发处理、传递各种内容类型(如图片、文档、HTML 页面等)、在响应中使用 URI 模板来包含任务 URI,那么新的 Web API 是你的最佳选择。
  • 如果你想创建一个多目标服务,既可以作为通过 HTTP 的面向资源的服务,又可以作为通过 TCP 的 RPC 风格的 SOAP 服务——先跟我谈谈,我会给你一些指点。

我希望这篇文章能帮助你消除一些关于这个话题的困惑。

© . All rights reserved.