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

REST 技术术语

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.64/5 (8投票s)

2010 年 9 月 7 日

BSD

7分钟阅读

viewsIcon

67544

REST Web 服务和模板,具有关注点分离

跳转到与 Visual Studio 的集成

引言

对于大多数开发者来说,Visual Studio 是最好的工具。由于各种因素,它也常常是唯一的工具。它提供了大量的项目模板,可以帮助开发者入门或帮助经验丰富的专业人士。遗憾的是,这些模板常常是过于简化的示例,最终出现在实际产品中仅仅是因为它们是默认的,而不是因为它们适合手头的问题。

本文详细介绍了如何实现 Web 服务,但采用了更好的项目结构,减少了组件之间的耦合,并分离了接口定义和它们的实现。最后但同样重要的是,提供了一个新模板来固化这些新发现的原则。

背景

为方便说明,本文围绕一个基于 WCF 构建的虚构 Web 服务展开。该服务通过 REST 公开资源集合,这些资源可以托管在 IIS 中或独立运行。此外,还包括一个示例 Web 客户端应用程序以及核心逻辑的单元测试。

将软件项目分层在业界已存在一段时间,但术语和技术仍然存在很多混淆。特别是,此类讨论常常将层分离和软件层混淆,因此推荐阅读入门文章 Ted Neward 的“实用架构:分层”

Web 服务——“REST 技术行话”

软件开发充斥着新技术和新术语,通常是针对相同甚至更旧的技术,但无论如何,其中涉及大量技术行话。在本文中,Web 服务实际上管理着一系列 REST 技术行话短语。此 Web 服务的客户端可以请求 [最新] 技术行话短语列表、添加新的、修改现有的等等(即 CRUD 支持)。

项目

Projects

首先,让我们回顾一下所涉及的项目以及它们在 Visual Studio 解决方案中的组织方式。本段旁边是解决方案资源管理器的快照,它显示了几个解决方案文件夹和相应的项目。解决方案文件夹对应于稍后描述的层。

解决方案文件夹和项目的关键点是:

  • 解决方案文件夹以两位数字(例如 10、20)作为前缀,用于排序。
  • 项目编译(仍然)由项目依赖项设置控制。
  • 项目/层依赖项以可视方式传达给开发人员。
  • 顶层项目依赖于较低层项目。

图层

Layers

本段旁边的图表显示了 Web 服务、其契约、宿主和客户端被分配到不同的层。图表上的箭头显示了不同层之间的编译时依赖关系。

层描述

  • 数据层——持久存储的抽象*
  • 核心——实现的业务逻辑
  • Web 服务——核心的包装
  • 宿主——Web 服务的宿主(即 IIS 宿主或独立宿主)
  • 客户端——客户端应用程序

*:为了限制此 Web 服务项目的范围,信息存储在内存中,并且相应的逻辑未被分解到单独的数据层中。

关于层及其依赖关系的图表的关键点

  • 编译时依赖项以箭头表示。
  • 上层依赖于下层(反之则不然)。
  • 客户端层仅依赖于契约,而不依赖于实现层。

Assemblies

Assemblies

下图显示了上述项目生成的程序集的依赖关系。该图由 Visual Studio 生成,并提供了另一个确认,即已遵守层依赖关系。一个有趣的特性是 Visual Studio 还可以将这些依赖关系与层图(上方)中指定的依赖关系进行检查,并在添加了不正确的依赖关系时进行通知。

此图的关键点是:

  • 客户端程序集仅依赖于契约的定义
  • 部署到客户端的程序集数量较少(因此部署大小更小)
  • 可以在不重新部署客户端程序集的情况下实现服务实现中的更正
  • 多个客户端(即 WebApp 和 WebMVC3)仅基于契约定义构建

运行示例

现在您已经阅读了上一节中的许多技术行话,看看正在运行的 Web 服务是什么样子可能会很有趣。

为了演示目的,我将 Web 服务的客户端实现为(另一个)Web 应用程序,该应用程序使用并允许操作技术行话短语(毕竟,技术行话总是在不断演变)。

所有项目都已设置相应的依赖项,因此Client.WebApp项目的构建和运行就足够了。否则,您可以先构建和运行Host.WebApp项目,然后构建和运行Client.WebApp项目。

REST Technobabble web client snapshot

REST api snapshot

优点

与 Visual Studio 默认的 WCF/REST 模板和此处显示的模板相比,最明显的区别在于所涉及的项目数量。但这真的更好吗?

嗯,答案是那句古老的:“视情况而定”,但以下是这种方法的一些优点:

  • 关注点分离——每个项目都专注于更小、更具体的任务。
  • 客户端程序集仅依赖于契约的定义,因此无需将实现程序集部署到客户端。
  • 部署到客户端的程序集数量减少(因此部署大小更小)。
  • 可以在不重新部署客户端程序集的情况下实现服务实现中的更正。
  • 核心层功能的单元测试实现起来容易得多。
  • 更容易处理不同的 API 语义(例如:REST 的无状态方面与核心层公开的内部 API 的有状态用法)。
  • Web 和 Host 项目可以专注于它们的目标,这些目标是技术特定的,并且会随着时间快速变化。

上述所有优点都足以证明拥有更细粒度的项目是值得的。

单元测试

如上所述,核心层可以遵循更简单的开发实践。由于它对部署基础设施的依赖有限,因此其单元测试可以更容易地实现。特别是与涉及客户端和 Web 服务时所需的系统/集成级别测试相比。

Unit test results

此外,Web 和 Host 项目可以专注于它们的目标,这些目标是技术特定的,并且会随着时间快速变化。今天,服务通过 WCF 实现,并通过 ASP.NET 项目或独立可执行文件托管在 IIS 中;明天它可能是 Windows(R) 服务或其他东西。

关注点

即使在这个简单的例子中,这种分离也能更容易地解决语义差异。例如,服务通过 REST 公开,并通过 .NET 的 `WebGet` 属性实现。这增加了限制,即只有 `string` 参数会从 URI 中解析(`WebGet` 实现的行为),并且连续相同的删除资源调用不是错误条件(这在一般过程编程中是错误的)。

与 Visual Studio 集成

最后,最棒的部分是:上述所有内容都可以通过一个新的 Visual Studio 模板合理地重用。要安装模板,您可以导航到 Visual Studio Gallery,或者更简单地,使用 Visual Studio 进行安装

  1. 在 Visual Studio 中打开新项目对话框。
  2. 输入搜索词:“structured”。
  3. 选择“结构化 WCF REST 服务”项目,然后继续向导。

如果一切正常,您应该会看到如下所示的对话框:

Visual studio install

源代码

源代码现在可以在 GitHub 上获取

参考文献

关于应用程序/表示层分离以及相应的表示层/业务逻辑/数据访问层的大量信息可供参考——事实上,多到无法在此列出。尽管如此,实用的建议却很少见。本文使用了以下参考资料:

历史

  • 版本 1.2:新增 ASP.NET MVC3 客户端项目
  • 文章更新:发布了模板源
  • 版本 1.1:控制台托管应用程序更新
  • 版本 1.0:初始发布
© . All rights reserved.