设计并实现超媒体API2013-11-30 infoq 译:孙镜涛本文(这一系列的第二篇文章)的主题是超媒体服务器的实现。本文用到的消息设计和问题领域描述已经 在之前的文章中介绍过。在本文中,我们首先会简要介绍超媒体服务器的角色(路由、评估和执行),然后会 讨论它的基础实现,包括组件层、展现层和连接层。最后,我们将简要介绍一个超媒体API的客户端浏览器; 特别是常见的Web浏览器和命令行工具的限制以及“媒体类型浏览器”的优点。本文详细介绍了使用 Node.js构建一个完整功能的服务器所需的高层细节信息。为了让事情相对简单一些,本文中的示例实现并没 有使用其他自定义Node模块或者框架,甚至连简单的磁盘文件的存储处理都没有使用。因为本文的实现只有骨 架和基础实现,所以它并不具有真实的产品级服务器所具有的所有特性和安全,但是你依然能够从中了解实现 的主要技术点。同时,虽然这个服务器是使用Node.js构建的,但是将本文所介绍的思想转换成你喜欢的其他 编程语言、框架和/或者平台也没有问题。注意:可以从GitHub上获取这个服务器实现的所有 源代码。超媒体API服务器超媒体API服务器在基本Web服务器的基础上添加了很多功能。和常 见的Web服务器一样,超媒体API服务器会接收请求、处理请求并返回响应。但是,超媒体API服务器还会执行 一些其他的工作。它们就像翻译家,按照预定义的消息格式发送每一个请求,将其翻译成服务器组件(存储、 数据库和业务逻辑)能够理解的内容进行处理,然后重新翻译回预定义的格式,翻译后的格式中可能包含发送 请求的客户端做下一步操作所需的信息。典型的RPC类型的API服务器并不会包含这些信息。这些额外 的信息可能会包含这个客户端是否能够看到相关的资源,是否能够执行一个搜索操作,是否能够修改存储在服 务器上的数据等内容。所有这一切都是基于发送请求的客户端所能理解的媒体类型设计,通过增加超媒体控制 (链接和表单)通信的。客户端请求可能会和用户身份绑定到一起;该身份可能会(也可能不会)包含一些额 外的特权,同时也会影响下一个请求进行时哪些内容是有效的。对响应做出的修正是上下文驱动的,这也是对 超媒体类型的实现所添加的关键价值增值元素之一。路由在Web环境中,一个API服务器的首要 任务是接收、解析并路由传入的请求。在设计Web API服务器时,通常会将URI作为首选方式路由到达服务器的 请求。这个过程是这样的,首先将URI解析成路径片段和查询字符串等内容,然后使用这些信息将请求的详细 内容(包括可能的请求体数据)发送到正确的内部组件进行处理。例如下面的HTTP请求:
GET/users/?search=pendingHost: http://www.example.orgAccept: application/vnd.collection+jsonAuthorization: q1w2e3r4t5=
这个请求的第一部分告诉服务器一个客户端想要执行一个“读”操作 ,它要搜索www.example.org服务器上被挂起的用户。客户端请求的第二部分表明响应的数据应该是 collection+json格式的(一种已注册的超媒体类型)。请求的最后一部分表示该请求是由一个经过授权的用 户发出的,可以通过授权头中的加密值鉴别该用户。服务器通常会将URI分解为不同的部分:userssearch=pending然后会生成一个有效的请求发送给对应的内部组件处理:
results = Users.Search("pending");
处理结果会被转换成被请求的格式并发送回客户端:
http.Response = Representation(results, "collection+json");
上面的例子使用的是伪代码,但是你能从中体会到 基础思路。API服务器接收、路由并处理请求,然后创建符合格式的结果返回给客户端。