修改了一下

This commit is contained in:
xiemengjun
2012-10-13 10:19:56 +08:00
parent 4c03af08f1
commit c68c1646ad
3 changed files with 41 additions and 25 deletions

44
8.3.md
View File

@@ -1,11 +1,35 @@
#8.3 REST #8.3 REST
RESTful架构,就是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。接下来让我们来了解这种架构到底是怎么样的?Go里面如何来实现RESTful RESTful是目前最流行的一种互联网软件架构。因为它结构清晰、符合标准、易于理解、扩展方便,所以正得到越来越多网站的采用。本小节我们将来学习它到底是一种什么样的架构?以及在Go里面如何来实现
##什么是REST ##什么是REST
REST(REpresentational State Transfer)描述了一个架构样式的网络系统比如Web应用程序。它首次出现在 2000年Roy Thomas Fielding的博士论文中,他是HTTP规范的主要编写者之一。REST指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful。 REST(REpresentational State Transfer)这个概念,首次出现在 2000年Roy Thomas Fielding他是HTTP规范的主要编写者之一)的博士论文中,它指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是RESTful
Web应用程序最重要的REST原则是客户端和服务器之间的交互在请求之间是无状态的。从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启客户端不会得到通知。此外无状态请求可以由任何可用服务器回答这十分适合云计算之类的环境。客户端可以缓存数据以改进性能。 要理解什么是REST我们需要理解下面几个概念:
在服务器端应用程序状态和功能可以分为各种资源。资源是一个有趣的概念实体它向客户端公开。资源的例子有应用程序对象、数据库记录、算法等等。每个资源都使用URI(Universal Resource Identifier)得到一个惟一的地址。所有资源都共享统一的界面以便在客户端和服务器之间传输状态。使用的是标准的HTTP方法比如 GET、PUT、POST 和 DELETE。 - 资源Resources
REST是"表现层状态转化",其实它省略了主语。"表现层"其实指的是"资源"的"表现层"。
那么什么是资源呢就是我们平常上网访问的一张图片、一个文档、一个视频等。这些资源我们通过URI来定位也就是一个URI表示一个资源。
- 表现层Representation
资源是做一个具体的实体信息他可以有多种的展现方式。而把实体展现出来就是表现层例如一个txt文本信息他可以输出成html、json、xml等格式一个图片他可以jpg、png等方式展现这个就是表现层的意思。
URI确定一个资源但是如何确定它的具体表现形式呢应该在HTTP请求的头信息中用Accept和Content-Type字段指定这两个字段才是对"表现层"的描述。
- 状态转化State Transfer
访问一个网站就代表了客户端和服务器的一个互动过程。在这个过程中肯定涉及到数据和状态的变化。而HTTP协议是无状态的那么这些状态肯定保存在服务器端所以如果客户端想要通知服务器端改变数据和状态的变化肯定要通过某种方式来通知它。
客户端能通知服务器端的手段只能是HTTP协议。具体来说就是HTTP协议里面四个表示操作方式的动词GET、POST、PUT、DELETE。它们分别对应四种基本操作GET用来获取资源POST用来新建资源也可以用于更新资源PUT用来更新资源DELETE用来删除资源。
综合上面的解释我们总结一下什么是RESTful架构
- 1每一个URI代表一种资源
- 2客户端和服务器之间传递这种资源的某种表现层
- 3客户端通过四个HTTP动词对服务器端资源进行操作实现"表现层状态转化"。
Web应用要满足REST最重要的原则是:客户端和服务器之间的交互在请求之间是无状态的,即从客户端到服务器的每个请求都必须包含理解请求所必需的信息。如果服务器在请求之间的任何时间点重启,客户端不会得到通知。此外此请求可以由任何可用服务器回答,这十分适合云计算之类的环境。因为是无状态的,所以客户端可以缓存数据以改进性能。
另一个重要的REST原则是分层系统这表示组件无法了解它与之交互的中间层以外的组件。通过将系统知识限制在单个层可以限制整个系统的复杂性促进了底层的独立性。 另一个重要的REST原则是分层系统这表示组件无法了解它与之交互的中间层以外的组件。通过将系统知识限制在单个层可以限制整个系统的复杂性促进了底层的独立性。
@@ -13,7 +37,7 @@ Web应用程序最重要的REST原则是客户端和服务器之间的交互
![](images/8.3.rest2.png?raw=true) ![](images/8.3.rest2.png?raw=true)
当REST架构的约束条件作为一个整体应用时将生成一个可以扩展到大量客户端的应用程序。它还降低了客户端和服务器之间的交互延迟。统一界面简化了整个系统架构改进了子系统之间交互的可见性。REST简化了客户端和服务器的实现而且对于使用REST开发的应用程序更加容易扩展。 当REST架构的约束条件作为一个整体应用时将生成一个可以扩展到大量客户端的应用程序。它还降低了客户端和服务器之间的交互延迟。统一界面简化了整个系统架构改进了子系统之间交互的可见性。REST简化了客户端和服务器的实现而且对于使用REST开发的应用程序更加容易扩展。
下图展示了REST的扩展新性 下图展示了REST的扩展新性
@@ -74,15 +98,7 @@ Go语言对于REST没有标准包直接支持但是因为RESTful是基于HTTP
上面的代码我们演示如何编写一个REST的应用我们访问的资源是用户然后我们通过不同的method来访问不同的函数这里我们使用了一个第三方库`github.com/drone/routes`这个库实现了方便的路由规则映射我们在上面章节也介绍过可以实现自定义的路由器这个库就实现了自定义的路由我们可以很方便的实现REST的架构。通过上面的代码我们知道REST就是根据不同的method访问同一个资源的时候实现不同的逻辑处理。一般这些method的定义如下 上面的代码我们演示如何编写一个REST的应用我们访问的资源是用户然后我们通过不同的method来访问不同的函数这里我们使用了一个第三方库`github.com/drone/routes`这个库实现了方便的路由规则映射我们在上面章节也介绍过可以实现自定义的路由器这个库就实现了自定义的路由我们可以很方便的实现REST的架构。通过上面的代码我们知道REST就是根据不同的method访问同一个资源的时候实现不同的逻辑处理。
- Get表示获取请求的资源信息
- Post表示修改相应的资源信息
- Put表示添加一个新的资源
- Delete表示删除请求的资源信息
- Patch表示对资源进行部分更新的一个特殊方法
通过上面的代码演示我们知道资源是通过URI来确定的然后通过不同的方式执行不同的操作方式这就是RESTful的实现。
##总结 ##总结
REST是一种架构风格汲取了WWW的成功经验无状态以资源为中心充分利用HTTP协议和URI协议提供统一的接口定义使得它作为一种设计Web服务的方法而变得流行。在某种意义上通过强调URI和HTTP等早期Internet标准REST是对大型应用程序服务器时代之前的Web方式的回归。目前Go对于REST的支持还是很简单的通过实现自定义的路由规则我们就可以实现不同的method实现不同的handle这样就实现了REST的架构。 REST是一种架构风格汲取了WWW的成功经验无状态以资源为中心充分利用HTTP协议和URI协议提供统一的接口定义使得它作为一种设计Web服务的方法而变得流行。在某种意义上通过强调URI和HTTP等早期Internet标准REST是对大型应用程序服务器时代之前的Web方式的回归。目前Go对于REST的支持还是很简单的通过实现自定义的路由规则我们就可以实现不同的method实现不同的handle这样就实现了REST的架构。

20
8.4.md
View File

@@ -1,9 +1,9 @@
#8.4 RPC #8.4 RPC
前面几个小节我们介绍了基于Socket和HTTP来编写应用通过介绍我们了解了Socket和HTTP使用类似消息传递的模式,客户端发送一个消息到服务端,然后一般服务器端都会一定的返回信息。客户端和服务端都需要约定交互的消息格式,双方都需要对这种消息能够解析。但是很多独立的应用不会使用这种消息传递的模式,而是采用类似函数调用的方式,这种方式应用通过调用带有一串参数的函数,然后返回一组值 前面几个小节我们介绍了如何基于Socket和HTTP来编写网络应用,通过学习我们了解了Socket和HTTP采用的是类似"信息交换"模式,客户端发送一条信息到服务端,然后(一般来说)服务器端都会返回一定的信息以表示响应。客户端和服务端之间约定交互信息的格式,以便双方都能够解析交互所产生的信息。但是很多独立的应用并没有采用这种模式,而是采用类似常规的函数调用的方式来完成想要的功能
RPC就是想实现函数调用模式的网络化。客户端就像调用本地函数一样然后客户端把这些参数打包之后通过网络传递到服务端服务端解包到处理过程中执行然后执行的结果反馈给客户端。 RPC就是想实现函数调用模式的网络化。客户端就像调用本地函数一样然后客户端把这些参数打包之后通过网络传递到服务端服务端解包到处理过程中执行然后执行的结果反馈给客户端。
RPCRemote Procedure Call Protocol——远程过程调用协议是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在如TCP或UDP为通信程序之间携带信息数据。在OSI网络通信模型中RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。 RPCRemote Procedure Call Protocol——远程过程调用协议是一种通过网络从远程计算机程序上请求服务而不需要了解底层网络技术的协议。假定某些传输协议的存在如TCP或UDP以便为通信程序之间携带信息数据。通过它可以使函数调用模式网络化。在OSI网络通信模型中RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。
##RPC工作原理 ##RPC工作原理
@@ -23,7 +23,7 @@ RPCRemote Procedure Call Protocol——远程过程调用协议它是
- 10.客户接收句柄返回的数据 - 10.客户接收句柄返回的数据
##Go RPC ##Go RPC
Go标准包里面已经支持了RPC而且支持三个级别的RPCTCP、HTTP、JSONRPC。但Go的RPC包是独一无二的RPC和传统的RPC系统不一样Go的客户端只能和Go的服务端交互因为他们的交互采用了Go的Gob编码。 Go标准包中已经提供了对RPC的支持而且支持三个级别的RPCTCP、HTTP、JSONRPC。但Go的RPC包是独一无二的RPC和传统的RPC系统不它只支持Go开发的服务器与客户端之间的交互因为在内部它们采用了Gob编码。
Go RPC的函数只有符合下面的条件才能被远程访问不然会被忽略详细的要求如下 Go RPC的函数只有符合下面的条件才能被远程访问不然会被忽略详细的要求如下
@@ -88,7 +88,7 @@ http的服务端代码实现如下
} }
} }
通过上面的例子我们看到我们注册了一个Arith的RPC服务然后通过`rpc.HandleHTTP`函数把该服务注册到了HTTP协议上然后我们就可以利用http的方式来传递数据了。 通过上面的例子可以看到我们注册了一个Arith的RPC服务然后通过`rpc.HandleHTTP`函数把该服务注册到了HTTP协议上然后我们就可以利用http的方式来传递数据了。
请看下面的客户端代码: 请看下面的客户端代码:
@@ -144,7 +144,7 @@ http的服务端代码实现如下
Arith: 17*8=136 Arith: 17*8=136
Arith: 17/8=2 remainder 1 Arith: 17/8=2 remainder 1
通过上面的调用我们看到参数和返回值是我们定义的结构体,在服务端我们把们当做调用函数的参数类型,在客户端作为`client.Call`参数。客户端最重要的就是这个`Call`函数,他三个参数,第一个参数是调用对象的函数,第二个参数是传递的参数,第三个参数是返回的参数(注意是指针类型),通过上面服务端和客户端的代码例子我们发现,Go的RPC相当的简单调用也很方便。 通过上面的调用可以看到参数和返回值是我们定义的struct类型,在服务端我们把们当做调用函数的参数类型,在客户端作为`client.Call`第23两个参数的类型。客户端最重要的就是这个Call函数它有3个参数,第1个要调用的函数的名字第2个是要传递的参数,第3个要返回的参数(注意是指针类型),通过上面的代码例子我们可以发现,使用Go的RPC实现相当的简单,方便。
###TCP RPC ###TCP RPC
上面我们实现了基于HTTP协议的RPC接下来我们要实现基于TCP协议的RPC服务端的实现代码如下所示 上面我们实现了基于HTTP协议的RPC接下来我们要实现基于TCP协议的RPC服务端的实现代码如下所示
@@ -210,9 +210,9 @@ http的服务端代码实现如下
} }
} }
上面这个代码和http的服务器比,唯一不同的就是这边是采用了TCP然后需要自己控制连接这个连接通知给rpc来处理。 上面这个代码和http的服务器比,不同在于:在此处我们采用了TCP协议,然后需要自己控制连接,当有客户端连接上来后,我们需要把这个连接给rpc来处理。
而且我们可以发现这是一个阻塞型的单用户的程序如果想要实现多并发那么可以使用goroutine来实现我们前面在socket小节的时候已经介绍过如何处理goroutine。 如果你留心了,你会发现这是一个阻塞型的单用户的程序如果想要实现多并发那么可以使用goroutine来实现我们前面在socket小节的时候已经介绍过如何处理goroutine。
下面展现了TCP实现的RPC客户端 下面展现了TCP实现的RPC客户端
package main package main
@@ -264,7 +264,7 @@ http的服务端代码实现如下
这个客户端代码和http的客户端代码对比唯一的区别一个是DialHTTP一个是Dial(tcp),其他处理一模一样。 这个客户端代码和http的客户端代码对比唯一的区别一个是DialHTTP一个是Dial(tcp),其他处理一模一样。
###JSON RPC ###JSON RPC
JSON RPC是数据编码采用了JSON而不是gob编码其他和上面介绍的RPC概念一模一样下面我们来看Go标准包里面如何实现JSON RPC,请看服务端代码的实现: JSON RPC是数据编码采用了JSON而不是gob编码其他和上面介绍的RPC概念一模一样下面我们来演示一下如何使用Go提供的json-rpc标准包,请看服务端代码的实现:
package main package main
@@ -329,7 +329,7 @@ JSON RPC是数据编码采用了JSON而不是gob编码其他和上面介
} }
} }
我们可以发现上面的代码是基于TCP协议的目前只支持基于TCP协议的方式不支持HTTP方式。 通过示例我们可以看出 json-rpc是基于TCP协议实现的,目前它还不支持HTTP方式。
请看客户端的实现代码: 请看客户端的实现代码:
@@ -380,7 +380,7 @@ JSON RPC是数据编码采用了JSON而不是gob编码其他和上面介
} }
##总结 ##总结
Go的标准包已经对RPC支持的非常好这样就可以开发很多分布式的Web应用通过上面HTTP、TCP、JSON RPC的实现我们可以领会到这一点。但唯一遗憾的是目前Go标准包里面不支持SOAP RPC协议当然第三方开源包有在实现类似的东西,我们也可以找到相应的开源代码 Go已经提供了对RPC的良好支持通过上面HTTP、TCP、JSON RPC的实现,我们可以很方便的开发很多分布式的Web应用我想作为读者的你已经领会到这一点。但遗憾的是目前Go尚未提供对SOAP RPC的支持欣慰的是现在已经有第三方开源实现了

2
8.5.md
View File

@@ -1,5 +1,5 @@
#8.5 小结 #8.5 小结
这一章我们介绍了目前流行的集中Web开发方式,第一小节介绍了网络编程中非常重要的Socket编程因为现在云计算时代网络通信是唯一的也是必要的一种方式那么通过网络来进行数据的交流是多么的重要Socket就是交流的公路你只有了解了这条路的方向才能开快车。第二小节介绍了目前流行的HTML5中一个重要的特性WebSocket通过这个可以实现服务器的主动推,可以简化以前ajax轮询的模式。第三小节介绍了REST编写模式也是目前很多大公司开发API的实现方式种模式特别适合来开发API结合目前移动的快速发展,我觉得将来会是一个潮流。第四小节介绍了RPC的编程模式可以实现分布式的应用过程实现。Go对于上面四种模式都很好的支持了Go的`net`包下面基本实现了所有网络编程的函数。如果你想更加深入的了解里面是怎么实现的,可以尝试阅读这个包下面的源码。 这一章我们介绍了目前流行的几种主要的网络应用开发方式,第一小节介绍了网络编程中的基础:Socket编程因为现在网络正在朝云的方向快速进化作为这一技术演进的基石的的socket知识作为开发者的你是必须要掌握的。第二小节介绍了正愈发流行的HTML5中一个重要的特性WebSocket通过它,服务器可以实现主动的push消息以简化以前ajax轮询的模式。第三小节介绍了REST编写模式这种模式特别适合来开发网络应用API目前移动应用的快速发展,我觉得将来会是一个潮流。第四小节介绍了Go实现的RPC相关知识对于上面四种开发方式Go都已经提供了良好的支持net包及其子包,是所有涉及到网络编程的工具的所在地。如果你想更加深入的了解相关实现细节,可以尝试阅读这个包下面的源码。
## links ## links
* [目录](<preface.md>) * [目录](<preface.md>)
* 上一节: [RPC](<8.4.md>) * 上一节: [RPC](<8.4.md>)